$ (документ) .on (“клацніть” ... не працює?


83

Чи є тут добре відома помилка?

У мене є сценарій, який використовує .on (), оскільки елемент динамічно генерується, і він не працює. Тільки для того, щоб перевірити це, я замінив селектор на обгортання динамічного елемента, яке є статичним, і він все одно не працював! Коли я перейшов на звичайний старий .click для обгортки, він все ж працював.
(Це просто не буде працювати для динамічного елемента, того, що має значення.)

Це працює:

$("#test-element").click(function() {
    alert("click");
});

Це не означає:

$(document).on("click","#test-element",function() {
    alert("click");
});

ОНОВЛЕННЯ:

Я клацнув правою кнопкою миші та зробив "Перевірити елемент" у Chrome, щоб просто перевірити щось, а потім після цього подія натискання спрацювала. Я оновився, і це не спрацювало, перевірив елемент, а потім він спрацював. Що це означає?


1
Ви створюєте більше одного елемента з однаковим ідентифікатором?
adeneo

Розміщення лише jQuery без відповідного HTML ускладнює допомогу.
jmoerdyk

3
Привіт, О.П., будь ласка, перевір версію Jquery, яку ти використовуєш, :)або клацни на скрипці, я можу тобі допомогти,
Tats_innit

Ваш код повинен працювати. onФункція була додана в JQuery 1.7, переконайтеся , що у вас є остання версія. Edit: доказ для вас, що це працює на скрипці
Phil-R

Ваш другий приклад працює з останньою версією 1.x jQuery: jsfiddle.net/AJPdS
Wookai

Відповіді:


153

Ви використовуєте правильний синтаксис для прив’язки до документа для прослуховування події клацання для елемента з id = "test-element".

Можливо, це не працює через одне з:

  • Не використовується остання версія jQuery
  • Не загортаючи ваш код всередину DOM
  • або ви робите щось, що призводить до того, що подія не переходить до слухача в документі.

Щоб фіксувати події на елементах, які створюються ПІСЛЯ оголошення вашими слухачами подій - вам слід прив’язати батьківський елемент або елемент вище в ієрархії.

Наприклад:

$(document).ready(function() {
    // This WILL work because we are listening on the 'document', 
    // for a click on an element with an ID of #test-element
    $(document).on("click","#test-element",function() {
        alert("click bound to document listening for #test-element");
    });

    // This will NOT work because there is no '#test-element' ... yet
    $("#test-element").on("click",function() {
        alert("click bound directly to #test-element");
    });

    // Create the dynamic element '#test-element'
    $('body').append('<div id="test-element">Click mee</div>');
});

У цьому прикладі спрацьовуватиме лише попередження "прив’язане до документа".

JSFiddle з jQuery 1.9.1


На жаль, я використовую останню версію Jquery, мій код правильно упакований, він знаходиться всередині $ (document) .ready, і подія, що натискається, є елементом найнижчого рівня в документі. Це бентежить.
Містер Лаваламп,

Я б сказав, що "потрібно поставити слухача на батьківський елемент" не є важливим, хоча я теж рекомендую це. Пузиріння - це те, що дозволяє .on () працювати. Якби ми не могли розраховувати на бурхливе проходження повз безпосереднього батька, це не було б чудовим рішенням.
iGanja

@iGanja - хороший момент, і, як ви пропонуєте, "потреба" - це не те слово, оскільки існують інші менш ідеальні способи досягнення цього. Я переглянув свою відповідь.
itsmejodie

якщо я використовую "це" для посилання на об'єкт елемента, то як я можу прикріпити цю подію до документа ..
Ashish Joshi

1
@JasonGlisson, я припускаю, що, хоча у вас є слухач на документі, існує або проблема з тим, що подія не спливає (натисканням кнопки), або різниця між кодом event.targetі event.currentTargetдесь у вашому коді, але їх багато речі, які це може бути, включаючи вимкнення подій покажчика на кнопці
itsmejodie

12

Ваш код повинен працювати, але я знаю, що відповідь вам не допомагає. Ви можете побачити робочий приклад тут (jsfiddle) .

Jquery:

$(document).on('click','#test-element',function(){
    alert("You clicked the element with and ID of 'test-element'");
});

Як хтось уже зазначав, ви використовуєте ідентифікатор замість класу. Якщо на сторінці у вас більше одного елемента з ідентифікатором, тоді jquery поверне лише перший елемент із цим ідентифікатором . Помилок не буде, бо саме так це працює. Якщо проблема полягає в цьому, то ви помітите, що подія натискання працює для першої, test-elementале не для наступної.

Якщо це не точно описує симптоми проблеми, можливо, ваш селектор помиляється. Ваше оновлення змушує мене вважати, що це саме так, оскільки перевіряючи елемент, натискаючи сторінку ще раз і викликаючи клацання. Що може спричинити це, якщо ви встановите прослуховувач подій на фактичний, documentа не на test-element. Якщо так, коли ви клацаєте документ і знову вмикаєте (наприклад, із вікна розробника назад до документа) подія спрацьовує. У цьому випадку ви також помітите, що подія натискання спрацьовує, якщо клацнути між двома різними вкладками (оскільки це дві різні documents, і тому ви натискаєте документ.

Якщо жоден із цих варіантів не є відповіддю, розміщення HTML значною мірою допоможе зрозуміти це.


5

Стара публікація, але я люблю ділитися, оскільки в мене той самий випадок, але нарешті я знав проблему:

Проблема полягає в тому, що ми створюємо функцію для роботи із зазначеним елементом HTML, але елемент HTML, пов’язаний з цією функцією, ще не створений (оскільки елемент динамічно генерується). Щоб це працювало, нам слід зробити функцію одночасно зі створенням елемента. Елемент спочатку, ніж зробити функцію, пов’язану з ним.

Просто кажучи, функція працюватиме лише з елементом, який створив до неї (його). Будь-які елементи, які створюються динамічно, означають після нього.

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

<div class="btn-list" id="selected-country"></div>

Динамічно додається:

<button class="btn-map" data-country="'+country+'">'+ country+' </button>

Ця функція працює добре, натиснувши кнопку:

$(document).ready(function() {    
        $('#selected-country').on('click','.btn-map', function(){ 
        var datacountry = $(this).data('country'); console.log(datacountry);
    });
})

або ви можете використовувати тіло, як:

$('body').on('click','.btn-map', function(){ 
            var datacountry = $(this).data('country'); console.log(datacountry);
        });

порівняйте з цим, що не працює:

$(document).ready(function() {     
$('.btn-map').on("click", function() { 
        var datacountry = $(this).data('country'); alert(datacountry);
    });
});

сподіваюся, це допоможе


Ви можете уникнути використання $ (документ) .готово чекати, поки елемент буде доданий до DOM, якщо замість цього почнете з $ (документ) .on ("клацніть" ... $ (документ) .on ("клацніть", "# selected-country", function () {});
Лорен,

3

Це працює:

<div id="start-element">Click Me</div>

$(document).on("click","#test-element",function() {
    alert("click");
});

$(document).on("click","#start-element",function() {
    $(this).attr("id", "test-element");
});

Ось Скрипка


1
Відповідно до питання, це не є динамічно генерованим елементом.
itsmejodie

@itsmejodie - погодився, але він динамічно прив'язаний до обробника подій. зміна ідентичного елемента по суті нічим не відрізняється від додавання елемента DOM.
iGanja

1

Спробуйте це:

$("#test-element").on("click" ,function() {
    alert("click");
});

Документальний спосіб робити це теж дивно. Для мене це мало б сенс, якщо б він використовувався для вибору класу, але у випадку з ідентифікатором у вас, мабуть, просто марний DOM, який там проходить. У випадку селектора ідентифікатора ви отримуєте цей елемент миттєво.


2
Чим це відрізняється від $("#test-element").click(function() {?
Сушант -

2
Вам потрібно використовувати .on () для прив’язки подій до динамічно генерованих DOM - все, що пов’язано з .click (), спробує прив’язати, коли документ буде готовий, і якщо dom відсутній, нічого не трапиться.
JTravakh

2
Але використання .onбез використання a selector- це те саме, що безпосереднє застосування події клацання на ньому
Sushanth -

1
Це не правильна відповідь на запитання. Це буде прив'язуватися безпосередньо до елемента і, отже, не підходить, коли елемент генерується динамічно.
їїмеджіді

1
Я насправді прочитав документи, але розділ про продуктивність насправді не має нічого спільного з делегованими обробниками подій, і ваш код не є делегованим обробником подій.
adeneo

0

якщо цей код не працює навіть під готовий документ, швидше за все, ви призначили return false;цій кнопці десь у своєму js-файлі, якщо це кнопка, спробуйте змінити його на a, span, anchor або div і перевірте, чи працює.

$(document).on("click","#test-element",function() {
        alert("click bound to document listening for #test-element");
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.