Encontrar o id de um div pai usando Jquery

99

Eu tenho alguns 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>

e alguns 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);
});

O que eu realmente gostaria é se eu não tivesse que ter a classe = "1" no botão (eu sei que classes numéricas não são válidas, mas este é um WIP!), Então eu poderia determinar o botãoNo com base no id do div pai. Na vida real, existem várias seções com esta aparência.

  1. Como faço para encontrar o id do div pai do botão.

  2. Qual seria uma forma mais semântica de armazenar a resposta no código do botão. Eu quero tornar isso o mais infalível possível para um não programador copiar e colar sem quebrar as coisas!

Rich Bradshaw
fonte

Respostas:

212

Você pode usar a delegação de eventos no div pai. Ou use o método mais próximo para encontrar o pai do botão.

O mais fácil dos dois é provavelmente o mais próximo.

var id = $("button").closest("div").prop("id");
Marca
fonte
6
Eu realmente gosto do mais próximo porque você pode fazer algo como .closest ("div.foo") e o código não está vinculado à estrutura.
Marcos
2
Então, eu estava prestes a fazer uma função recursiva .... então eu sabia que o jquery já tinha algo ... no meu caso, usei $ ("#" + id) .closest ("div.form-group") para encontrar o div pai que tinha a classe do grupo de forma.
cabaji99
47

1

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

2

Deve haver um grande número de maneiras! Uma poderia ser ocultar um elemento que contém a resposta, por exemplo

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

E, em seguida, tenha um código jQuery semelhante ao acima para obter isso:

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

tenha em mente que se você colocar a resposta no código do cliente, eles poderão vê-la :) A melhor maneira de fazer isso é validando-a no lado do servidor, mas para um aplicativo com escopo limitado, isso pode não ser um problema.

Rob Grant
fonte
Não tenho ideia de como formatar HTML neste editor, mas parece uma maneira bem mais simples de pegar o pai do que as coisas de Pim ('div: eq (0)'); a menos que esteja faltando alguma sutileza aqui, todos os elementos html têm um pai direto, que você obtém apenas com parent ().
Rob Grant
o pai realmente retornará o pai mais próximo, no entanto, o que acontece se ele decidir que deseja adicionar um fieldset ou algo em torno da questão, mas dentro do Div.
Pim Jager
Na verdade, em seu próprio exemplo, isso retornará o <p>
Pim Jager
De fato, se mais divs forem adicionados, então 'div: eq (0)' pode estar errado. Altere a estrutura, altere o código que a analisa :) E sim, simplifiquei o exemplo para o html mínimo necessário para o exemplo; deve chamar o pai duas vezes.
Rob Grant
Por algum motivo, quando usei parent (), não consegui acessar attr (id), tive que quebrar o resultado assim $(parent[0]).attr('id')depois de alguns seletores pai.
Piotr Kula
11

Experimente isto:

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

Para obter o id do div pai:

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

Além disso, você pode refatorar seu código um pouco:

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

Agora não há necessidade de uma classe de botão

a explicação
eq (0) significa que você selecionará um elemento do objeto jQuery, neste caso o elemento 0, portanto, o primeiro elemento. http://docs.jquery.com/Selectors/eq#index
$ (seletor) .siblings (siblingsSelector) selecionará todos os irmãos (elementos com o mesmo pai) que correspondem ao siblingsSelector http://docs.jquery.com/Traversing / siblings # expr
$ (seletor) .parents (ParentsSelector) selecionará todos os pais dos elementos correspondidos pelo seletor que correspondem ao seletor pai. http://docs.jquery.com/Traversing/parents#expr
Assim: $ (selector) .parents ('div: eq (0)'); corresponderá ao primeiro div pai dos elementos correspondidos pelo seletor.

Você deve dar uma olhada na documentação do jQuery, particularmente seletores e travessia:

Pim Jager
fonte
Simples e fácil! Por que o div: eq (0)? O que isso significa?
Rich Bradshaw
Acho que 'div: eq (0)' estará errado se tudo estiver contido em pelo menos um div, porque você está fazendo um percurso absoluto do DOM em vez de um relativo. O que seria ótimo se o primeiro elemento fosse o pai "mais próximo", mas isso sugere o contrário: tinyurl.com/bbegow
Rob Grant
1
(daí meu uso de parent () em vez disso)
Rob Grant
6

http://jsfiddle.net/qVGwh/6/ Verifique isto

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

Isso pode ser feito facilmente fazendo:

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

Você anexa isso a qualquer objeto dentro de uma tabela e ele retornará o id dessa tabela.

Hamid
fonte
3

JQUery tem um método .parents () para mover para cima na árvore DOM, você pode começar aí.

Se você estiver interessado em fazer isso de uma forma mais semântica, não acho que usar o atributo REL em um botão seja a melhor maneira de definir semanticamente "esta é a resposta" em seu código. Eu recomendaria algo neste sentido:

<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);
});

Não tenho certeza de como sua validação e feedback estão funcionando, mas você entendeu.

Papagaios
fonte
0

find () e mais próximo () parece um pouco mais lento do que:

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