将单击事件附加到尚未添加到 DOM 的 JQuery 对象

IT技术 javascript jquery onclick jquery-events
2021-01-31 20:39:37

在将单击事件添加到 DOM 之前,我在将单击事件附加到 JQuery 对象时遇到了很多麻烦。

基本上我有我的函数返回的这个按钮,然后我将它附加到 DOM。我想要的是返回带有自己的点击处理程序的按钮。我不想从 DOM 中选择它来附加处理程序。

我的代码是这样的:

createMyButton = function(data) {

  var button = $('<div id="my-button"></div>')
    .css({
       'display' : 'inline',
       'padding' : '0px 2px 2px 0px',
       'cursor' : 'pointer'
     }).append($('<a>').attr({
       //'href' : Share.serializeJson(data),
       'target' : '_blank',
       'rel' : 'nofollow'
     }).append($('<image src="css/images/Facebook-icon.png">').css({
       "padding-top" : "0px",
       "margin-top" : "0px",
       "margin-bottom" : "0px"
     })));

     button.click(function () {
        console.log("asdfasdf");
     });

     return button;     
}

返回的按钮无法捕捉点击事件。但是,如果我这样做(在将按钮添加到 DOM 之后):

$('#my-button').click(function () {
    console.log("yeahhhh!!! but this doesn't work for me :(");
});

它有效......但不适合我,不是我想要的。

这似乎与对象还不是 DOM 的一部分这一事实有关。

哦!顺便说一下,我正在使用 OpenLayers,我将按钮附加到的 DOM 对象是一个 OpenLayers.FramedCloud(它还不是 DOM 的一部分,但一旦触发了几个事件就会成为。)

6个回答

用这个。您可以将 body 替换为 dom ready 上存在的任何父元素

$('body').on('click', '#my-button', function () {
     console.log("yeahhhh!!! but this doesn't work for me :(");
});

http://api.jquery.com/on/ 上查看有关如何使用 on() 的更多信息,因为它从 1.7+ 开始替换 live()。

下面列出了您应该使用的版本

$(selector).live(events, data, handler); // jQuery 1.3+

$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+

$(document).on(events, selector, data, handler); // jQuery 1.7+

这是我为测试“点击”而制作的小提琴。 jsfiddle.net/X8KcU/1
2021-03-27 20:39:37
@Ajedi32 不一定-您只需要正确的 css 选择器来定位您的元素。你能详细解释一下你到底想做什么吗?
2021-03-28 20:39:37
好吧,我是这么想的。该复选框在对服务器进行 ajax 调用后动态添加,服务器响应创建它所需的信息。在将输入添加到 DOM 后,我已经完成了您的建议并对其进行了操作。
2021-03-30 20:39:37
“你可以用任何准备好 DOM 的父元素替换 BODY”,这是关键,谢谢!
2021-04-04 20:39:37
不幸的是,这个解决方案并不理想,因为它要求我向正在侦听事件的元素添加一个 ID。我宁愿该createMyButton函数返回一个已经附加了一个事件侦听器的元素。这在 JQuery 中可能吗?
2021-04-09 20:39:37

我真的很惊讶还没有人发布这个

$(document).on('click','#my-butt', function(){
   console.log('document is always there');
}) 

如果您不确定当时该页面上将包含哪些元素,只需将其附加到document.

注意:从性能角度来看,这是次优的 - 为了获得最大速度,应该尝试附加到将要插入的元素的最近父元素。

我只是想知道,如何衡量 javascript 性能……有什么推荐的方法吗?
2021-03-15 20:39:37
@JohnnyBigoode 让它变得更糟的唯一方法是将它附加到窗口 :) ,它必须通过 html (child->parent->...document) 一直冒泡。不过我还是会这么做……还有更糟糕的事情……
2021-03-19 20:39:37
从性能的角度来看,您将如何衡量?
2021-04-02 20:39:37
@JohnnyBigoode 和接受的答案(平均而言)将提高 2 个级别,这几乎可以忽略不计......
2021-04-02 20:39:37
@MatasVaitkevicius 我的屁股?哈哈
2021-04-11 20:39:37

试试这个.... 用父选择器替换正文

$('body').on('click', '#my-button', function () {
    console.log("yeahhhh!!! but this doesn't work for me :(");
});
我看到你首先回答了一个简单的错字,所以我的 +1 是为了你的意图。很好的解决方案。谢谢!
2021-03-17 20:39:37

尝试:

$('body').on({
    hover: function() {
        console.log("yeahhhh!!! but this doesn't work for me :(");
    },
    click: function() {
        console.log("yeahhhh!!! but this doesn't work for me :(");
    }
},'#my-button');

jsfiddle 示例

使用 .on() 并绑定到动态元素时,您需要引用页面上已存在的元素(如示例中的 body)。如果您可以使用更具体的元素来提高性能。

事件处理程序仅绑定到当前选定的元素;当您的代码调用 .on() 时,它们必须存在于页面上。为确保元素存在并且可以被选择,请在文档就绪处理程序中为页面上 HTML 标记中的元素执行事件绑定。如果将新 HTML 注入页面,则在将新 HTML 放入页面后选择元素并附加事件处理程序。或者,使用委托事件附加事件处理程序,如下所述。

源代码:http : //api.jquery.com/on/

我知道......它是如此罕见......当我使用: $('body').on('click hover', '#my-button', function () {console.log('hello');} )它有效,但仅在悬停时,如果我从上方删除“点击”,它将与悬停一起工作,但如果我离开“点击”,它不会做任何事情...... :(
2021-03-15 20:39:37
请参阅我更新的答案和示例。
2021-03-15 20:39:37
我不确定我明白你的意思。.on() 绝对适用于点击事件。
2021-03-21 20:39:37
我不相信你可以用 on() 做到这一点。也许使用 bind 你有那个选项,但是使用 on() 你必须做类似的事情$('body').on({ hover: function() { }, click: function() { } }
2021-03-29 20:39:37
这是正确的,但是它只适用于悬停事件,而不适用于点击事件......
2021-04-03 20:39:37

你必须附加它。使用以下命令创建元素:

var $div = $("<div>my div</div>");
$div.click(function(){alert("clicked")})
return $div;

然后,如果您附加它将起作用。

看看你的例子here和一个简单的版本here

我说它工作正常,所以没问题。这是我的首选解决方案,因为这意味着处理程序与内容一样是动态的。基本上将内容视为带有自己的控制器的部分视图,我非常喜欢。
2021-03-17 20:39:37
我做了这样的事情,它工作得很好。
2021-03-26 20:39:37