$(document).on(“点击” ...不起作用?


82

我在这里会犯一个众所周知的错误吗?

我有一个使用.on()的脚本,因为一个元素是动态生成的,并且无法正常工作。为了进行测试,我将选择器替换为动态元素的包装,它是静态的,但仍然无法正常工作!但是,当我切换到普通的旧.click进行换行时,它起作用了。
(显然,这对动态元素无效,这很重要。)

这有效:

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

这不是:

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

更新:

我右键单击并在Chrome中执行“检查元素”以仅仔细检查某些内容,然后单击事件起作用。我刷新了一下,但它不起作用,检查了元素,然后它起作用了。这是什么意思?


1
您是否要创建多个具有相同ID的元素?
2013年

仅发布没有相关HTML的jQuery很难提供帮助。
jmoerdyk

3
Hiya OP,请检查您正在使用的Jquery的版本,:)或轻弹我可能会帮助您的小提琴,
Tats_innit

您的代码应该可以正常工作。该on函数是在jQuery 1.7中添加的,请确保您具有最新版本。编辑:为您证明它可以在小提琴上工作
Phil-R

您的第二个示例适用于最新的1.x版本的jQuery:jsfiddle.net/AJPdS
Wookai 2013年

Answers:


153

您正在使用正确的语法绑定到文档,以侦听id =“ test-element”元素的click事件。

由于以下原因之一,它可能无法正常工作:

  • 不使用最新版本的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内,并且被单击的事件是文档中的最低级别的元素。这真令人困惑。
Lavalamp先生13年

我会说“不需要将侦听器放在父元素上”是必不可少的,尽管我也建议这样做。起泡是使.on()起作用的原因。如果我们不能依靠冒泡来超越直系父母,那将不是一个很好的解决方案。
iGanja

@iGanja-好点,正如您所建议的那样,“需要”一词不正确,因为还有其他较不理想的方法来完成此操作。我修改了答案。
itsmejodie 2013年

如果我使用“本”,以引用元素对象那我怎么才能将其附加的事件处理文档..
阿希什·乔希

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

就像已经指出的那样,您使用的是ID而不是类。如果页面上有多个具有ID的元素,则jquery将返回具有该ID的第一个元素。不会有任何错误,因为这就是它的工作方式。如果这是问题所在,那么您会注意到click事件适用于第一个事件,test-element但不适用于随后的事件。

如果这不能准确地描述问题的症状,则说明您的选择器是错误的。您的更新使我相信是这种情况,因为先检查了一个元素,然后再次单击页面并触发了单击。可能的原因是,如果您将事件侦听器置于实际位置document而不是位置test-element。如果是这样,当您单击关闭文档并重新打开时(例如从开发人员窗口回到文档),事件将触发。在这种情况下,如果您在两个不同的选项卡之间单击(因为它们是两个不同document的,因此您正在单击文档),也会注意到click事件被触发。

如果以上两个都不是答案,那么发布HTML将大有帮助。


4

一个老帖子,但我喜欢分享,因为我有同样的情况,但我终于知道了问题所在:

问题是:我们使一个函数可以使用指定的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);
    });
});

希望对你有帮助


如果您以$(document).on(“ click” ... $(document).on(“ click”,开头),则可以避免使用$(document).ready等待元素添加到DOM。 “#selected-country”,function(){});
Loren

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

@itsmejodie-同意,但是它动态绑定到事件处理程序。更改ID本质上与添加DOM元素没有什么不同。
iGanja

1

试试这个:

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

这样做的文件方式也很奇怪。如果用于类选择器,那对我来说很有意义,但是在id的情况下,您可能只在其中遍历了无用的DOM。对于id选择器,您可以立即获得该元素。


2
这有什么不同$("#test-element").click(function() {
苏珊思-

2
您必须使用.on()将事件绑定到动态生成的DOM-与.click()绑定的任何对象都将在文档准备就绪时尝试进行绑定,如果dom不存在,则不会发生任何事情。
JTravakh

2
但是使用.on而不使用aselector等同于直接在其上应用click事件
Sushanth-13年

1
这不是问题的正确答案。这将直接绑定到元素,因此不适用于动态生成的元素。
itsmejodie 2013年

1
我实际上已经阅读了文档,但是关于性能的部分与委托事件处理程序并没有任何关系,并且您的代码不是委托事件处理程序。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.