Trovare l'ID di un div genitore utilizzando Jquery


99

Ho un html come questo:

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

e alcuni JS come questo:

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

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

Quello che mi piacerebbe davvero è se non dovessi avere la classe = "1" sul pulsante (so che le classi numeriche non sono valide, ma questo è un WIP!), In modo da poter determinare buttonNo in base al id del div genitore. Nella vita reale ci sono più sezioni che hanno questo aspetto.

  1. Come faccio a trovare l'id del div genitore del pulsante.

  2. Quale sarebbe un modo più semantico per memorizzare la risposta nel codice del pulsante. Voglio renderlo il più sicuro possibile per un non programmatore per copiare e incollare senza rompere le cose!

Risposte:


212

È possibile utilizzare la delega degli eventi sul div genitore. Oppure utilizza il metodo più vicino per trovare il genitore del pulsante.

Il più semplice dei due è probabilmente il più vicino.

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

6
Mi piace molto il più vicino perché puoi fare qualcosa come .closest ("div.foo") e il codice non è legato alla struttura.
Marco

2
Grazie stavo per eseguire una funzione ricorsiva .... allora sapevo che jquery aveva già qualcosa ... nel mio caso ho usato $ ("#" + id) .closest ("div.form-group") per trovare il div genitore che aveva la classe form-group.
cabaji99

47

1.

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

2.

Ci devono essere molti modi! Uno potrebbe essere nascondere un elemento che contiene la risposta, ad es

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

E poi avere un codice jQuery simile a quello sopra per afferrarlo:

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

tieni presente che se inserisci la risposta nel codice client, possono vederla :) Il modo migliore per farlo è convalidarla lato server, ma per un'app con ambito limitato questo potrebbe non essere un problema.


Non ho idea di come formattare HTML in questo editor, ma questo sembra un modo piuttosto più semplice per afferrare il genitore rispetto alle cose di Pim ('div: eq (0)'); a meno che non mi manchi una sottigliezza qui, gli elementi html hanno tutti un genitore diretto, che ottieni solo con parent ().
Rob Grant,

genitore restituirà effettivamente il genitore più vicino, tuttavia, cosa succede se decide di aggiungere un fieldset o qualcosa attorno alla domanda ma all'interno del Div.
Pim Jager,

In realtà nel suo stesso esempio questo restituirà <p>
Pim Jager

In effetti, se si aggiungono più div, "div: eq (0)" potrebbe essere sbagliato. Cambia la struttura, cambia il codice che lo analizza :) E sì ho semplificato l'esempio al minimo html necessario per l'esempio; dovrebbe chiamare due volte il genitore.
Rob Grant,

Per qualche motivo, quando ho usato parent () non ho potuto accedere ad attr (id), ho dovuto racchiudere il risultato in questo modo $(parent[0]).attr('id')dopo aver apprezzato alcuni selettori genitore.
Piotr Kula

11

Prova questo:

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


7

Per ottenere l'ID del div genitore:

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

Inoltre, puoi rifattorizzare il tuo codice un po ':

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

Ora non c'è bisogno di una classe di pulsanti

spiegazione
eq (0), significa che selezionerai un elemento dall'oggetto jQuery, in questo caso l'elemento 0, quindi il primo elemento. http://docs.jquery.com/Selectors/eq#index
$ (selector) .siblings (siblingsSelector) selezionerà tutti i fratelli (elementi con lo stesso genitore) che corrispondono a siblingsSelector http://docs.jquery.com/Traversing / siblings # expr
$ (selector) .parents (parentSelector) selezionerà tutti i genitori degli elementi corrispondenti al selettore che corrispondono al selettore genitore. http://docs.jquery.com/Traversing/parents#expr
Quindi: $ (selector) .parents ('div: eq (0)'); corrisponderà al primo div genitore degli elementi corrispondenti al selettore.

Dovresti dare un'occhiata alla documentazione di jQuery, in particolare ai selettori e agli attraversamenti:


Semplice e facile! Perché div: eq (0)? Cosa significa?
Rich Bradshaw

Penso che 'div: eq (0)' sarà sbagliato se tutto questo è racchiuso in almeno un div, perché stai facendo un attraversamento assoluto del DOM piuttosto che uno relativo. Il che andrebbe bene se il primo elemento fosse il genitore "più vicino", ma questo suggerisce il contrario: tinyurl.com/bbegow
Rob Grant,

1
(da qui il mio uso di parent () invece)
Rob Grant,


5

Questo può essere fatto facilmente facendo:

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

Lo alleghi a qualsiasi oggetto all'interno di una tabella e ti restituirà l'id di quella tabella.


3

JQUery ha un metodo .parents () per spostarsi verso l'alto nell'albero DOM che puoi iniziare da lì.

Se sei interessato a farlo in un modo più semantico, non penso che l'uso dell'attributo REL su un pulsante sia il modo migliore per definire semanticamente "questa è la risposta" nel tuo codice. Consiglierei qualcosa in questo senso:

<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>

e

$("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);
});

Non sei abbastanza sicuro di come funzionino la convalida e il feedback, ma hai un'idea.


0

find () e più vicino () sembra leggermente più lento di:

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

$(this).parent().parent().attr("id");?
Alejandro Iván
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.