Trouver l'id d'un div parent à l'aide de Jquery

99

J'ai du HTML comme celui-ci:

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

et certains JS comme ceci:

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

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

Ce que j'aimerais vraiment, c'est que je n'ai pas besoin d'avoir la classe = "1" sur le bouton (je sais que les classes numériques ne sont pas valides, mais c'est un WIP!), Afin que je puisse déterminer buttonNo en fonction de la id de la div parent. Dans la vraie vie, plusieurs sections ressemblent à ceci.

  1. Comment puis-je trouver l'identifiant du div parenting le bouton.

  2. Quelle serait une manière plus sémantique de stocker la réponse dans le code du bouton. Je veux rendre cela aussi infaillible que possible pour un non programmeur de copier et coller sans casser les choses!

Rich Bradshaw
la source

Réponses:

212

Vous pouvez utiliser la délégation d'événements sur le div parent. Ou utilisez la méthode la plus proche pour trouver le parent du bouton.

Le plus simple des deux est probablement le plus proche.

var id = $("button").closest("div").prop("id");
marque
la source
6
J'aime vraiment le plus proche car vous pouvez faire quelque chose comme .closest ("div.foo") et le code n'est pas lié à la structure.
Mark le
2
Thx j'étais sur le point de faire une fonction récursive .... alors je savais que jquery avait déjà quelque chose ... dans mon cas, j'ai utilisé $ ("#" + id) .closest ("div.form-group") pour trouver le parent div qui avait la classe de groupe de formulaire.
cabaji99
47

1.

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

2.

Il doit y avoir un grand nombre de façons! L'un pourrait être de cacher un élément qui contient la réponse, par exemple

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

Et puis avoir un code jQuery similaire à celui ci-dessus pour saisir cela:

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

gardez à l'esprit que si vous mettez la réponse dans le code client, ils peuvent la voir :) La meilleure façon de le faire est de la valider côté serveur, mais pour une application avec une portée limitée, cela peut ne pas poser de problème.

Rob Grant
la source
Je n'ai aucune idée de la façon de formater le HTML dans cet éditeur, mais cela semble un moyen plus simple de saisir le parent que le truc de Pim ('div: eq (0)'); sauf si je manque une subtilité ici, les éléments html ont tous un parent direct, que vous obtenez simplement avec parent ().
Rob Grant
parent retournera en effet le parent le plus proche, cependant, que se passe-t-il s'il décide qu'il veut ajouter un fieldset ou quelque chose autour de la question mais à l'intérieur de la Div.
Pim Jager
En fait, dans son propre exemple, cela retournera le <p>
Pim Jager
En effet, si plus de divs ajoutent alors le 'div: eq (0)' pourrait être faux. Changez la structure, changez le code qui l'analyse :) Et oui j'ai simplifié l'exemple au minimum html nécessaire pour l'exemple; il devrait appeler le parent deux fois.
Rob Grant
Pour une raison quelconque, lorsque j'ai utilisé parent (), je ne pouvais pas accéder à attr (id), j'ai dû envelopper le résultat comme ceci $(parent[0]).attr('id')après avoir aimé quelques sélecteurs de parents.
Piotr Kula
11

Essaye ça:

$("button").click(function () {
    $(this).parents("div:first").html(...);
});
Buu Nguyen
la source
9
$(this).parents('div').attr('id');
Ashish Sajwan
la source
7

Pour obtenir l'id du div parent:

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

En outre, vous pouvez refactoriser votre code un peu:

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

Désormais, il n'y a plus besoin d'une classe de boutons

explication
eq (0), signifie que vous sélectionnerez un élément de l'objet jQuery, dans ce cas l'élément 0, donc le premier élément. http://docs.jquery.com/Selectors/eq#index
$ (selector) .siblings (siblingsSelector) sélectionnera tous les frères et sœurs (éléments avec le même parent) qui correspondent au siblingsSelector http://docs.jquery.com/Traversing / siblings # expr
$ (selector) .parents (parentsSelector) sélectionnera tous les parents des éléments mis en correspondance par le sélecteur qui correspondent au sélecteur parent. http://docs.jquery.com/Traversing/parents#expr
Ainsi: $ (selector) .parents ('div: eq (0)'); correspondra au premier div parent des éléments mis en correspondance avec le sélecteur.

Vous devriez jeter un œil à la documentation jQuery, en particulier les sélecteurs et la traversée:

Pim Jager
la source
Simple et facile! Pourquoi le div: eq (0)? Qu'est-ce que ça veut dire?
Rich Bradshaw
Je pense que le 'div: eq (0)' sera faux si tout cela est enveloppé dans au moins un div, car vous effectuez une traversée absolue du DOM plutôt que relative. Ce qui serait bien si le premier élément était le parent "le plus proche", mais cela suggère le contraire: tinyurl.com/bbegow
Rob Grant
1
(d'où mon utilisation de parent () à la place)
Rob Grant
6

http://jsfiddle.net/qVGwh/6/ Vérifiez ceci

   $("#MadonwebTest").click(function () {
    var id = $("#MadonwebTest").closest("div").attr("id");
    alert(id);
    });
Jerin K Alexander
la source
5

Cela peut être facilement fait en faisant:

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

Vous attachez ceci à n'importe quel objet à l'intérieur d'une table et il vous renverra l'id de cette table.

Hamid
la source
3

JQUery a une méthode .parents () pour remonter dans l'arborescence DOM, vous pouvez commencer là.

Si vous êtes intéressé à faire cela d'une manière plus sémantique, je ne pense pas que l'utilisation de l'attribut REL sur un bouton soit la meilleure façon de définir sémantiquement «c'est la réponse» dans votre code. Je recommanderais quelque chose du genre:

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

et

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

Je ne sais pas trop comment votre validation et vos commentaires fonctionnent, mais vous comprenez l'idée.

Perroquets
la source
0

find () et plus proche () semble légèrement plus lent que:

$(this).parent().attr("id");
Cris
la source
$(this).parent().parent().attr("id");?
Alejandro Iván