Encontrar la identificación de un div padre usando Jquery


99

Tengo un html como este:

<div id="1">
    <p>
        Volume = <input type="text" />
        <button rel="3.93e-6" class="1" type="button">Check answer</button>
    </p>
    <div></div>
</div>

y algunos JS como este:

$("button").click(function () {
    var buttonNo = $(this).attr('class');
    var correct = Number($(this).attr('rel'));

    validate (Number($("#"+buttonNo+" input").val()),correct);
    $("#"+buttonNo+" div").html(feedback);
});

Lo que realmente me gustaría es que no tuviera que tener la clase = "1" en el botón (sé que las clases numéricas no son válidas, ¡pero esto es un WIP!), Para poder determinar buttonNo según el id del div padre. En la vida real, hay varias secciones con este aspecto.

  1. ¿Cómo encuentro la identificación del div que cría el botón?

  2. ¿Cuál sería una forma más semántica de almacenar la respuesta en el código del botón? ¡Quiero que esto sea lo más infalible posible para que un no programador pueda copiar y pegar sin romper cosas!

Respuestas:


212

Puede usar la delegación de eventos en el div principal. O usa el más cercano método para encontrar el padre del botón.

El más fácil de los dos es probablemente el más cercano.

var id = $("button").closest("div").prop("id");

6
Realmente me gusta el más cercano porque puedes hacer algo como .closest ("div.foo") y el código no está vinculado a la estructura.
Mark

2
Thx estaba a punto de hacer una función recursiva .... entonces sabía que jquery ya tenía algo ... en mi caso usé $ ("#" + id) .closest ("div.form-group") para encontrar el padre div que tenía la clase form-group.
cabaji99

47

1.

$(this).parent().attr("id");

2.

¡Debe haber un gran número de formas! Una podría ser ocultar un elemento que contenga la respuesta, p. Ej.

<div>
    Volume = <input type="text" />
    <button type="button">Check answer</button>
    <span style="display: hidden">3.93e-6&lt;/span>
    <div></div>
</div>

Y luego tenga un código jQuery similar al anterior para obtener eso:

$("button").click(function () 
{
    var correct = Number($(this).parent().children("span").text());
    validate ($(this).siblings("input").val(),correct);
    $(this).siblings("div").html(feedback);
});

Tenga en cuenta que si coloca la respuesta en el código del cliente, entonces ellos pueden verla :) La mejor manera de hacerlo es validarla en el lado del servidor, pero para una aplicación con alcance limitado, esto puede no ser un problema.


No tengo idea de cómo formatear HTML en este editor, pero esta parece una forma bastante más simple de tomar el elemento principal que las cosas de Pim ('div: eq (0)'); a menos que me falte una sutileza aquí, todos los elementos html tienen un padre directo, que se obtiene con parent ().
Rob Grant

parent de hecho devolverá el padre más cercano, sin embargo, ¿qué sucede si decide que quiere agregar un fieldset o algo alrededor de la pregunta pero dentro del Div.
Pim Jager

En realidad, en su propio ejemplo, esto devolverá el <p>
Pim Jager

De hecho, si se agregan más divs, entonces el 'div: eq (0)' podría ser incorrecto. Cambie la estructura, cambie el código que lo analiza :) Y sí, simplifiqué el ejemplo al html mínimo necesario para el ejemplo; debería llamar a los padres dos veces.
Rob Grant

Por alguna razón, cuando usé parent () no pude acceder a attr (id), tuve que ajustar el resultado de esta manera $(parent[0]).attr('id')después de que me gustaran algunos selectores de padres.
Piotr Kula

11

Prueba esto:

$("button").click(function () {
    $(this).parents("div:first").html(...);
});


7

Para obtener la identificación del div padre:

$(buttonSelector).parents('div:eq(0)').attr('id');

Además, puede refactorizar un poco su código:

$('button').click( function() {
 var correct = Number($(this).attr('rel'));
 validate(Number($(this).siblings('input').val()), correct);
 $(this).parents('div:eq(0)').html(feedback);
});

Ahora no hay necesidad de una clase de botones

explicación
eq (0), significa que seleccionará un elemento del objeto jQuery, en este caso el elemento 0, por lo tanto, el primer elemento. http://docs.jquery.com/Selectors/eq#index
$ (selector) .siblings (siblingsSelector) seleccionará todos los hermanos (elementos con el mismo padre) que coincidan con el siblingsSelector http://docs.jquery.com/Traversing / siblings # expr
$ (selector) .parents (parentSelector) seleccionará todos los padres de los elementos emparejados por el selector que coincidan con el selector padre. http://docs.jquery.com/Traversing/parents#expr
Así: $ (selector) .parents ('div: eq (0)'); coincidirá con el primer div padre de los elementos emparejados por el selector.

Debería echar un vistazo a los documentos de jQuery, particularmente a los selectores y a los recorridos:


¡Simple y fácil! ¿Por qué div: eq (0)? ¿Lo que significa eso?
Rich Bradshaw

Creo que el 'div: eq (0)' será incorrecto si todo esto está envuelto en al menos un div, porque estás haciendo un recorrido absoluto del DOM en lugar de uno relativo. Lo cual estaría bien si el primer elemento fuera el padre "más cercano", pero esto sugiere lo contrario: tinyurl.com/bbegow
Rob Grant

1
(de ahí mi uso de parent () en su lugar)
Rob Grant


5

Esto se puede hacer fácilmente haciendo:

$(this).closest('table').attr('id');

Adjunta esto a cualquier objeto dentro de una tabla y te devolverá la identificación de esa tabla.


3

JQUery tiene un método .parents () para subir el árbol DOM que puede comenzar allí.

Si está interesado en hacer esto de una manera más semántica, no creo que usar el atributo REL en un botón sea la mejor manera de definir semánticamente "esta es la respuesta" en su código. Recomendaría algo en estas líneas:

<p id="question1">
    <label for="input1">Volume =</label> 
    <input type="text" name="userInput1" id="userInput1" />
    <button type="button">Check answer</button>
    <input type="hidden" id="answer1" name="answer1" value="3.93e-6" />
</p>

y

$("button").click(function () {
    var correctAnswer = $(this).parent().siblings("input[type=hidden]").val();
    var userAnswer = $(this).parent().siblings("input[type=text]").val();
    validate(userAnswer, correctAnswer);
    $("#messages").html(feedback);
});

No estoy muy seguro de cómo están funcionando su validación y comentarios, pero entiende la idea.


0

find () y más cercano () parece un poco más lento que:

$(this).parent().attr("id");

$(this).parent().parent().attr("id");?
Alejandro Iván
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.