$ (document) .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
Hiya OP, пожалуйста, проверьте версию JQuery, которую вы используете, :)или щелкните скрипкой, я могу вам помочь,
Tats_innit
Ваш код должен работать. onФункция была добавлена в JQuery 1.7, убедитесь , что у вас есть последняя версия. Изменить: доказательство для вас, что он работает на скрипке
Phil-R
Ваш второй пример работает с последней версией jQuery 1.x: 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

itsmejodie
источник
К сожалению, я использую последнюю версию JQuery, мой код правильно обернут, он находится внутри $ (document) .ready, а событие, на которое нажимают, является элементом самого низкого уровня в документе. Это сбивает с толку.
Mr. Lavalamp
Я бы сказал, что «нужно поместить слушателя в родительский элемент» не обязательно, хотя я тоже рекомендую это. Пузырьки - это то, что позволяет .on () работать. Если бы мы не могли полагаться на пузыри, чтобы пройти мимо непосредственного родителя, это было бы не лучшим решением.
iGanja
@iGanja - хороший аргумент, и, как вы предполагаете, «потребность» - не подходящее слово, поскольку есть другие, менее идеальные способы для этого. Я пересмотрел свой ответ.
itsmejodie
если я использую "this" для ссылки на объект элемента, то как я могу прикрепить это событие к документу ..
Ашиш Джоши
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 вернет только первый элемент с этим идентификатором . Ошибок не будет, потому что так работает. Если это проблема, то вы заметите, что событие click работает для первого, test-elementно не для всех последующих.

Если это не совсем точно описывает симптомы проблемы, возможно, ваш селектор ошибочен. Ваше обновление наводит меня на мысль, что это так, потому что я проверял элемент, а затем снова щелкал страницу и запускал щелчок. Это может быть вызвано тем, что вы поместите прослушиватель событий на фактическое значение documentвместо test-element. В таком случае, когда вы щелкаете по документу и снова включаете его (например, из окна разработчика обратно в документ), событие запускается. Если это так, вы также заметите, что событие щелчка запускается, если вы щелкаете между двумя разными вкладками (потому что это две разные вкладки, documentи поэтому вы щелкаете документ.

Если ни один из этих ответов не является ответом, публикация 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 как:

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

надеюсь, это поможет

Сулунг Нугрохо
источник
Вы можете избежать использования $ (document) .ready для ожидания добавления элемента в DOM, если вместо этого начнете с $ (document) .on ("click" ... $ (document) .on ("click", "# 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");
});

Вот скрипка

iGanja
источник
1
Это не динамически генерируемый элемент, согласно вопросу.
itsmejodie
@itsmejodie - согласен, но динамически привязан к обработчику события. изменение идентификатора по сути не отличается от добавления элемента DOM.
iGanja
1

Попробуй это:

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

Документальный способ сделать это тоже странно. Для меня это имело бы смысл, если бы он использовался для селектора класса, но в случае идентификатора у вас, вероятно, есть бесполезный обход DOM. В случае селектора id вы получите этот элемент мгновенно.

Эдуард Молдован
источник
2
Чем это отличается от $("#test-element").click(function() {?
Sushanth -
2
Вы должны использовать .on () для привязки событий к динамически сгенерированным DOM - все, что связано с .click (), будет пытаться привязать, когда документ будет готов, и если dom отсутствует, ничего не произойдет.
JTravakh
2
Но использование .onбез использования a selector- это то же самое, что прямое применение к нему события click
Sushanth -
1
Это неправильный ответ на вопрос. Это будет связываться напрямую с элементом и поэтому не подходит, если элемент был создан динамически.
itsmejodie
1
Я действительно прочитал документацию, но раздел о производительности на самом деле не имеет ничего общего с делегированными обработчиками событий, а ваш код не является делегированным обработчиком событий.
adeneo