Znajdowanie identyfikatora nadrzędnego div za pomocą Jquery

99

Mam taki html:

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

i trochę takich JS:

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

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

Naprawdę chciałbym, gdybym nie musiał mieć klasy = "1" na przycisku (wiem, że klasy numeryczne są nieprawidłowe, ale to jest WIP!), Więc mógłbym określić buttonNo na podstawie identyfikator nadrzędnego div. W prawdziwym życiu jest wiele sekcji wyglądających w ten sposób.

  1. Jak znaleźć identyfikator elementu div, który jest rodzicem przycisku.

  2. Jaki byłby bardziej semantyczny sposób przechowywania odpowiedzi w kodzie przycisku. Chcę, aby kopiowanie i wklejanie bez zepsucia rzeczy przez osoby, które nie są programistami, były maksymalnie niezawodne!

Rich Bradshaw
źródło

Odpowiedzi:

212

Możesz użyć delegowania zdarzeń w nadrzędnym div. Lub użyj najbliższej metody, aby znaleźć rodzica przycisku.

Najłatwiejszy z nich jest prawdopodobnie najbliższy.

var id = $("button").closest("div").prop("id");
znak
źródło
6
Naprawdę lubię najbliższe, ponieważ możesz zrobić coś takiego jak .closest ("div.foo"), a kod nie jest powiązany ze strukturą.
Mark
2
Thx i miałem zamiar wykonać funkcję rekurencyjną ... wtedy wiedziałem, że jquery ma już coś ... w moim przypadku użyłem $ ("#" + id) .closest ("div.form-group"), aby znaleźć nadrzędny div, który miał klasę form-group.
cabaji99
47

1.

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

2.

Musi być wiele sposobów! Można by ukryć element, który zawiera odpowiedź, np

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

A potem miej podobny kod jQuery do powyższego, aby pobrać to:

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

pamiętaj, że jeśli umieścisz odpowiedź w kodzie klienta, będą mogli ją zobaczyć :) Najlepszym sposobem na to jest sprawdzenie jej po stronie serwera, ale dla aplikacji o ograniczonym zakresie może to nie być problemem.

Rob Grant
źródło
Nie mam pojęcia, jak sformatować HTML w tym edytorze, ale wydaje się, że jest to raczej prostszy sposób na złapanie rodzica niż rzeczy Pima ('div: eq (0)'); chyba że brakuje mi tu subtelności, wtedy wszystkie elementy html mają jednego bezpośredniego rodzica, który dostajesz po prostu za pomocą parent ().
Rob Grant
rodzic rzeczywiście zwróci najbliższego rodzica, ale co się stanie, jeśli zdecyduje, że chce dodać zestaw pól lub coś dookoła pytania, ale wewnątrz Div.
Pim Jager
Właściwie w jego własnym przykładzie zwróci to <p>
Pim Jager
Rzeczywiście, jeśli doda się więcej elementów div, to „div: eq (0)” może być błędne. Zmień strukturę, zmień kod, który go przetwarza :) I tak uprościłem przykład do minimum html niezbędnego dla przykładu; powinien dwukrotnie zadzwonić do rodzica.
Rob Grant
Z jakiegoś powodu, gdy użyłem parent (), nie mogłem uzyskać dostępu do attr (id), musiałem zawinąć wynik w ten sposób $(parent[0]).attr('id')po tym, jak zrobiłem kilka selektorów nadrzędnych.
Piotr Kula
11

Spróbuj tego:

$("button").click(function () {
    $(this).parents("div:first").html(...);
});
Buu Nguyen
źródło
9
$(this).parents('div').attr('id');
Ashish Sajwan
źródło
7

Aby uzyskać identyfikator nadrzędnego div:

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

Możesz też nieco zmienić kod:

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

Teraz nie ma potrzeby stosowania klasy przycisków

wyjaśnienie
eq (0) oznacza, że ​​wybierzesz jeden element z obiektu jQuery, w tym przypadku element 0, a więc pierwszy element. http://docs.jquery.com/Selectors/eq#index
$ (selector) .siblings (siblingsSelector) wybierze całe rodzeństwo (elementy z tym samym rodzicem) pasujące do selektora rodzeństwa http://docs.jquery.com/Traversing / siblings # expr
$ (selector) .parents (parentSelector) wybierze wszystkich rodziców elementów dopasowanych przez selektor, które pasują do selektora nadrzędnego. http://docs.jquery.com/Traversing/parents#expr
Zatem: $ (selector) .parents ('div: eq (0)'); dopasuje pierwszy nadrzędny element div elementów dopasowanych przez selector.

Powinieneś rzucić okiem na dokumenty jQuery, w szczególności selektory i przechodzenie:

Pim Jager
źródło
Proste i łatwe! Dlaczego div: eq (0)? Co to znaczy?
Rich Bradshaw
Myślę, że „div: eq (0)” będzie błędne, jeśli to wszystko jest opakowane w co najmniej jeden element div, ponieważ wykonujesz absolutne przechodzenie przez DOM zamiast względnego. Co byłoby w porządku, gdyby pierwszy element był „najbliższym” rodzicem, ale to sugeruje inaczej: tinyurl.com/bbegow
Rob Grant
1
(stąd zamiast tego używam parent ())
Rob Grant,
6

http://jsfiddle.net/qVGwh/6/ Sprawdź to

   $("#MadonwebTest").click(function () {
    var id = $("#MadonwebTest").closest("div").attr("id");
    alert(id);
    });
Jerin K. Alexander
źródło
5

Można to łatwo zrobić, wykonując:

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

Dołączasz to do dowolnego obiektu wewnątrz tabeli i zwróci ci to identyfikator tej tabeli.

Hamid
źródło
3

JQUery ma metodę .parents () do poruszania się w górę drzewa DOM, od którego możesz zacząć.

Jeśli jesteś zainteresowany zrobieniem tego w bardziej semantyczny sposób, nie sądzę, że użycie atrybutu REL na przycisku jest najlepszym sposobem semantycznego zdefiniowania „to jest odpowiedź” w twoim kodzie. Poleciłbym coś w ten sposób:

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

i

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

Nie do końca jestem pewien, jak działa Twoja weryfikacja i informacja zwrotna, ale masz pomysł.

Papugi
źródło
0

find () i najbliższy () wydaje się nieco wolniejszy niż:

$(this).parent().attr("id");
Kryzys
źródło
$(this).parent().parent().attr("id");?
Alejandro Iván