单击事件对动态生成的元素不起作用

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">


$(document).ready(function() {


$("button").click(function() {
$("h2").html("<p class='test'>click me</p>")
});


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


</script>
</head>
<body>
<h2></h2>
<button>generate new element</button>
</body>
</html>

我试图通过单击按钮在 <h2>中生成一个类名为 test的新标记。我还定义了一个与 test相关联的 click 事件。但是这个活动没有成功。

有人能帮忙吗?

627420 次浏览

您正在使用的click()绑定被称为“直接”绑定,它只会将处理程序附加到已经存在的元素上。它不会与将来创建的元素绑定。要做到这一点,您必须使用<强> # EYZ1 < / >强创建一个“委托”绑定。

委托事件的优点是,它们可以处理来自稍后添加到文档的后代元素的事件。

< a href = " http://api.jquery.com/on/ " > < / >来源

以下是你想要的:

.
var counter = 0;


$("button").click(function() {
$("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});


// With on():


$("h2").on("click", "p.test", function(){
alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<h2></h2>
<button>generate new element</button>

以上内容适用于使用jQuery 1.7+版本的用户。如果你使用的是旧版本,请参考下面之前的答案。


# EYZ0:

尝试使用live():

$("button").click(function(){
$("h2").html("<p class='test'>click me</p>")
});




$(".test").live('click', function(){
alert('you clicked me!');
});

为我工作。试过与jsFiddle。

或者有一种新奇的方式来做delegate():

$("h2").delegate("p", "click", function(){
alert('you clicked me again!');
});

# EYZ0。

你需要使用.live来工作:

$(".test").live("click", function(){
alert();
});

或者如果你使用jquery 1.7+使用内用:

$(".test").on("click", "p", function(){
alert();
});

改变

 $(".test").click(function(){

 $(".test").live('click', function(){

LIVE DEMO

jQuery .live()

试试.live().delegate()

http://api.jquery.com/live/ < a href = " http://api.jquery.com/live/ " > < / >

http://api.jquery.com/delegate/ < a href = " http://api.jquery.com/delegate/ " > < / >

您的.test元素是在.click()方法之后添加的,因此它没有附加事件。Live和Delegate将事件触发器赋予检查子元素的父元素,因此之后添加的任何内容仍然有效。我认为Live将检查整个文档主体,而Delegate可以给一个元素,所以Delegate更有效。

更多信息:

http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/ < a href = " http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/ " > < / >

问题是,您试图在DOM中有任何带有“test”类的东西之前将“test”类绑定到事件。虽然看起来这一切都是动态的,但真正发生的是JQuery传递了DOM,并在ready()函数触发时连接了click事件,该事件发生在您在按钮事件中创建“click Me”之前。

通过将“test”单击事件添加到“button”单击处理程序,它将在DOM中存在正确的元素后将其连接起来。

<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("h2").html("<p class='test'>click me</p>")
$(".test").click(function(){
alert()
});
});
});
</script>

使用live()(正如其他人指出的那样)是另一种方法,但我觉得指出JS代码中的小错误也是一个好主意。你写的没有错,只是需要正确的范围。掌握DOM和JS的工作原理是许多传统开发人员难以理解的问题之一。

live()是一种更简洁的处理方法,在大多数情况下是正确的方法。它本质上是观察DOM,并在其中的元素发生变化时重新布线。

.live函数工作得很好。

它用于向舞台动态添加元素。

$('#selectAllAssetTypes').live('click', function(event){
alert("BUTTON CLICKED");
$('.assetTypeCheckBox').attr('checked', true);
});
< p >欢呼, Ankit . < / p >

使用使用委托事件的.on()方法

$('#staticParent').on('click', '.dynamicElement', function() {
// Do something on an existent or future .dynamicElement
});
# EYZ0 < a href = " http://api.jquery.com/on/ " > < / >方法允许您将任何所需的事件处理程序委托给 current元素或未来元素稍后添加到DOM。

注:不要使用.live()!从jQuery 1.7+开始,.live()方法已弃用。

Jquery .on工作还可以,但我有一些问题的渲染实现上面的一些解决方案。我使用.on的问题是,它在某种程度上呈现的事件与.hover方法不同。

只是供其他可能也有这个问题的人参考。我通过为动态添加的项目重新注册悬浮事件来解决我的问题:

重新注册悬停事件,因为悬停对动态创建的项目不起作用。 所以每次我创建新的/动态项目时,我都会再次添加悬停代码。完美的作品< / p >
$('#someID div:last').hover(
function() {
//...
},
function() {
//...
}
);

我正在使用表动态地添加新元素,当使用on()时,使它为我工作的唯一方法是使用一个非动态的父作为:

<table id="myTable">
<tr>
<td></td> // Dynamically created
<td></td> // Dynamically created
<td></td> // Dynamically created
</tr>
</table>


<input id="myButton" type="button" value="Push me!">


<script>
$('#myButton').click(function() {
$('#myTable tr').append('<td></td>');
});


$('#myTable').on('click', 'td', function() {
// Your amazing code here!
});
</script>

这非常有用,因为要删除与在()绑定的事件,可以使用(),而要使用一次事件,可以使用一()

在js文件中添加这个函数。 它将工作在每个浏览器

$(function() {
$(document).on("click", '#mydiv', function() {
alert("You have just clicked on ");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mydiv'>Div</div>

$(.surrounding_div_class).on( 'click', '.test', function () {
alert( 'WORKS!' );
});

只会工作,如果DIV类.surrounding_div_class是直接的父对象。test

如果在div中有另一个对象将被填充,它将不起作用。

我在jQuery的文档中找到了两个解决方案:

首先:在Body或Document上使用委托

例句:

 $("body").delegate('.test', 'click', function(){
...
alert('test');
});

为什么?

根据特定的根元素集合,为匹配选择器的所有元素附加一个或多个事件处理程序,现在或将来。 链接:# EYZ0 < / p > 第二步:将你的函数放在"$(文件)",使用“上”并将它附加到你想要触发这个的元素上。 第一个参数是“事件处理器”,第二个参数是元素,第三个参数是函数。 如 :
 $( document ).on( 'click', '.test', function () {
...
alert('test');
});

为什么?

答:事件处理程序仅绑定到当前选定的元素;在代码调用内()时,它们必须存在于页面上。要确保元素存在并且可以被选择,请在文档就绪处理程序中对页面上HTML标记中的元素执行事件绑定。如果将新的HTML注入到页面中,请在将新HTML放入页面后选择元素并附加事件处理程序。或者,使用委托事件附加事件处理程序,如下所述… 链接:# EYZ0 < / p >

另一种更简洁的方法(IMHO)是使用一个原始的javascript函数来响应一个on click事件,然后将目标元素传递回jQuery。这种方法的优点是你可以在任何地方动态地添加你的元素,点击处理程序将“正常工作”,你不需要担心把控制委托给父元素,等等。

更新动态html以触发onclick事件。确保将'event'对象作为参数传递



$("button").click(function() {
$("h2").html("<p class='test' onclick='test(event)'> click me </p>")
});


创建测试函数来响应点击事件



function test(e){
alert();
});


考虑到你正在使用jQuery,我假设它将是有用的,以获得一个引用回到源按钮



function test(e){
alert();


// Get a reference to the button
// An explanation of this line is available here
var target = (e.target)? e.target : e.srcElement;


// Pass the button reference to jQuery to do jQuery magic
var $btn = $(target);


});


我不能让live或委托在一个灯箱(小盒子)中的div上工作。

我成功地使用了setTimeout,以以下简单的方式:

$('#displayContact').click(function() {
TINY.box.show({html:'<form><textarea id="contactText"></textarea><div id="contactSubmit">Submit</div></form>', close:true});
setTimeout(setContactClick, 1000);
})


function setContactClick() {
$('#contactSubmit').click(function() {
alert($('#contactText').val());
})
}

使用委托对动态生成的内容应用事件的最佳方法。

$(document).on("eventname","selector",function(){
// code goes here
});

你的代码现在是这样的

$(document).on("click",".test",function(){
// code goes here
});

原因:

在jQuery中,单击()事件直接绑定,只有当特定的元素(Html代码)存在于页面(页面加载后)时,才会将事件处理程序附加到元素上。

动态元素在javascript或jquery(不是Html)的帮助下创建。

它不会考虑页面加载后创建的未来元素(Dynamic)。

因此,正常的单击事件不会在动态元素上触发。

解决方案:

为了克服这个问题,我们应该使用在()函数。在()可以为当前元素和未来元素委托事件。

委托事件的优点是可以将处理程序附加到将来要添加到文档的元素上。

注意:delegate(),live()和在()函数比DOM元素更有优势。从JQuery 1.7开始,delegate()和live()已弃用(不要使用它们)。

可以同时委托当前和未来元素的事件。

你的代码应该是这样的

美元(文档)时:中删除代码

$(".test").click(function(){


alert();


});

改变为:

$(document).on('click','.test',function(){


alert('Clicked');


});

你可以点击添加动态创建的元素。下面的例子。使用“何时”来确保完成。在我的例子中,我用类扩展抓取了一个div,添加了一个“点击查看更多”的跨度,然后使用这个跨度隐藏/显示原始的div。

$.when($(".expand").before("<span class='clickActivate'>Click to see more</span>")).then(function(){
$(".clickActivate").click(function(){
$(this).next().toggle();
})
});

如果你有一个动态添加到某个容器或主体的链接:

var newLink= $("<a></a>", {
"id": "approve-ctrl",
"href": "#approve",
"class": "status-ctrl",
"data-attributes": "DATA"
}).html("Its ok").appendTo(document.body);

你可以使用它的原始javascript元素,并添加一个事件监听器,如点击:

newLink.get(0).addEventListener("click", doActionFunction);

无论你添加多少次这个新链接实例,你都可以像使用jquery click函数一样使用它。

function doActionFunction(e) {
e.preventDefault();
e.stopPropagation();


alert($(this).html());
}

所以你会收到一条信息说

它的好

它比其他替代方案具有更好的性能。

额外的:你可以获得更好的性能避免jquery和使用纯javascript。如果你使用的是IE 8版本,你应该使用这个polyfill来使用addEventListener方法

if (typeof Element.prototype.addEventListener === 'undefined') {
Element.prototype.addEventListener = function (e, callback) {
e = 'on' + e;
return this.attachEvent(e, callback);
};
}

你也可以使用onclick="do_something(this)"inside元素

使用'on'作为点击绑定到已经存在的元素。

对如

$('test').on('click',function(){
alert('Test');
})

这将有所帮助。