Пошук ідентифікатора батьківського діла за допомогою Jquery


99

У мене є такий 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>

і деякі 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);
});

Що мені дуже хотілося б, якби мені не довелося мати клас = "1" на кнопці (я знаю, що числові класи не вірні, але це WIP!), Тож я міг би визначити buttonNo на основі ідентифікатор батьківського діла. У реальному житті є кілька таких розділів.

  1. Як знайти ідентифікатор кнопки дітового батьківства.

  2. Який би більш семантичний спосіб зберігати відповідь у коді кнопок. Я хочу зробити це якомога дурнішим, щоб непрограміст копіював і вставляв, не порушуючи речі!

Відповіді:


212

Ви можете використовувати делегування події на батьківському розділі. Або скористайтеся найближчими методом, щоб знайти батьківську кнопку.

Найпростіший з двох, мабуть, найближчий.

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

6
Мені дуже подобається найближче, тому що ти можеш зробити щось на кшталт .closest ("div.foo"), а код не прив'язаний до структури.
Марк

2
Thx я збирався виконати рекурсивну функцію .... тоді я знав, що у jquery вже є щось ... у моєму випадку я використовував $ ("#" + id) .closest ("div.form-group"), щоб знайти батьківський дів, який мав клас групової форми.
cabaji99

47

1.

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

2.

Має бути велика кількість способів! Можна приховати елемент, який містить відповідь, наприклад

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

А потім мати схожий код jQuery з вищезазначеним, щоб схопити це:

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

майте на увазі, що якщо ви введете відповідь у код клієнта, то вони зможуть це побачити :) Найкращий спосіб зробити це - перевірити його на стороні сервера, але для програми з обмеженим обсягом це може не бути проблемою.


Я не маю уявлення, як відформатувати HTML у цьому редакторі, але це здається досить простим способом захопити батьківський, ніж матеріал Pim ('div: eq (0)'); якщо мені тут не вистачає тонкощі, то в HTML-елементах є один прямий батько, який ви просто отримуєте з parent ().
Роб Грант

Батько дійсно поверне найближчого батька, однак, що станеться, якщо він вирішить, що хоче додати набір поля чи щось навколо питання, але всередині Div.
Пім Джагер

Насправді в його власному прикладі це повернеться <p>
Пім Джагер

Дійсно, якщо додати більше дівок, то "div: eq (0)" може бути неправильним. Змініть структуру, змініть код, який її розбирає :) І так, я спростив приклад до мінімального html, необхідного для прикладу; він повинен дзвонити батьків два рази.
Роб Грант

З якоїсь причини, коли я використовував parent (), я не міг отримати доступ до attr (id), мені довелося обгортати такий результат $(parent[0]).attr('id')після того, як мені подобалося кілька батьківських селекторів.
Пьотр Кула



7

Щоб отримати ідентифікатор батьківського div:

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

Крім того, ви можете трохи змінити свій код:

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

Тепер немає необхідності в клавішах класу

Пояснення
eq (0) означає, що ви виберете один елемент з об'єкта jQuery, в даному випадку елемент 0, таким чином, перший елемент. http://docs.jquery.com/Selectors/eq#index
$ (selector) .siblings (siblingsSelector) вибере всіх братів і сестер (елементів з тим самим батьківським), які відповідають сібріSelector http://docs.jquery.com/Traversing / siblings # expr
$ (selector) .parents (батьківSelector) вибере всіх батьків елементів, відповідних селектору, що відповідають батьківському селектору.http://docs.jquery.com/Traversing/parents#expr
Таким чином: $ (селектор) .parents ('div: eq (0)'); буде відповідати першому батьківському поділу елементів, відповідним селектору.

Ви повинні ознайомитись із документами jQuery, зокрема селекторами та переходами:


Просто і легко! Чому div: eq (0)? Що це значить?
Багатий Бредшоу

Я думаю, що "div: eq (0)" буде помилятися, якщо все це загорнене в принаймні один div, тому що ви робите абсолютне обхід DOM, а не відносний. Що було б добре, якби перший елемент був "найближчим" батьком, але це говорить про інше: tinyurl.com/bbegow
Роб Грант

1
(отже, моє використання батьківського () замість цього)
Роб Грант


5

Це легко зробити, зробивши:

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

Ви додаєте це до будь-якого об'єкта всередині таблиці, і він поверне вам ідентифікатор цієї таблиці.


3

JQUery має метод .parents () для переміщення вгору по дереву DOM, який ви можете почати там.

Якщо вам цікаво зробити це більш семантичним способом, я не думаю, що використання атрибута REL на кнопці - це найкращий спосіб семантично визначити "це відповідь" у своєму коді. Я рекомендую щось у цьому напрямку:

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

і

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

Не зовсім впевнений, як працює ваша перевірка та відгуки, але ви зрозуміли,


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.