点击事件不适用于动态生成的元素[重复]

Posted

技术标签:

【中文标题】点击事件不适用于动态生成的元素[重复]【英文标题】:Click event doesn't work on dynamically generated elements [duplicate] 【发布时间】:2021-10-19 00:47:40 【问题描述】:
<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>

我试图通过单击按钮在&lt;h2&gt; 中生成一个类名为test 的新标签。我还定义了一个与test 关联的点击事件。但该事件不起作用。

谁能帮忙?

【问题讨论】:

尝试使用 。它将一个新的 id 注册到 DOM 中,jQuery 可以访问,而 注意:您不能将

放入有效 HTML 中的

这里有一篇详细介绍如何为动态元素绑定点击事件goo.gl/zlEbnv 这个视频帮助了youtube.com/watch?v=unk-U_LQWuA 【参考方案1】:

您正在使用的click() 绑定称为“直接”绑定,它只会将处理程序附加到已经存在的元素。它不会绑定到将来创建的元素。为此,您必须使用on() 创建一个“委托”绑定。

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

Source

这就是您要查找的内容:

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+ 版本的用户。如果您使用的是旧版本,请参阅下面的上一个答案。


上一个答案

尝试使用live()

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


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

为我工作。 Tried it 与 jsFiddle。

或者使用delegate() 有一种新颖的方法:

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

An updated jsFiddle.

【讨论】:

从 jQuery 1.7 开始,.live() 方法已被弃用。使用.on() 附加事件处理程序。 它必须是$(document).on('click', '.test', function() 或绑定到其他父级才能等于.live 只是说因为它出现在最近的question @BlakePlumb:我查看了 jQuery 文档;你说的对!我会更新我的答案。感谢您的来信! 确保您选择的可点击父元素是在页面加载时呈现的元素,而不是动态生成的元素 - 是的,这很明显,但如果您没有清楚地考虑它可能会让您犯错就像它对我一样!【参考方案2】:

使用.on() method with delegated events

$('#staticParent').on('click', '.dynamicElement', function() 
    // Do something on an existent or future .dynamicElement
);

.on() 方法允许您将任何所需的事件处理程序委托给:当前元素或未来元素添加到DOM 稍后。

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

【讨论】:

这对我有用。有趣的是,上面的答案都没有指出必须使用非动态父选择器的事实。难怪 '.on' 之前对我不起作用。 这个也对我有用,而上面的那些没有。谢谢! 这是唯一对我有用的,因为我将事件绑定到动态元素而不是静态父元素。完美答案。 $('#parent') 这是我错过的那个,它使 on() 的行为变得清晰,谢谢 :) 这应该是最好的答案。缺少的现有父元素触摸让我有一段时间。【参考方案3】:

原因:

在 jQuery 中,仅当特定元素存在于 Html 代码中时(页面加载后),Click() 事件才会绑定该元素。

它不会考虑动态创建的未来元素(未来元素)。 动态元素是在 javascript 或 jquery(不在 Html 中) 的帮助下创建的。

所以正常的点击事件不会在动态元素上触发。

解决方案:

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

delegate()、live() 和 on() 函数比 DOM 元素具有优势。

delegate() 和 live() 已弃用(不要使用这些)。

on只能同时触发现有元素和未来元素。

on 可以考虑整个页面上存在的所有元素。

您应该使用 on 函数在动态(未来)创建的元素上触发事件。

从 $(document).ready 中删除代码:

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

  alert();

);

改成:

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

  alert('Clicked');

);

【讨论】:

当父级不存在并且也在动态创建时,情况的最佳答案。 以上所有答案怎么可能没有提到最重要的一行$(document).on('click','.test',function()?这应该是检查的答案!谢谢 唯一的答案对我有用。 这是最好的答案 你拯救了我的一天【参考方案4】:

在你的 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>

【讨论】:

【参考方案5】:

改变

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

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

LIVE DEMO

jQuery .live()

【讨论】:

我猜 live() 已被弃用【参考方案6】:

您需要使用.live 才能使用:

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

或者如果您使用的是 jquery 1.7+,请使用 .on:

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

【讨论】:

请阅读有关委派事件的文档。您的事件委托元素在哪里?您展示的另一个示例(使用 .on())无论如何都不是替换 .live() 的确切方法。【参考方案7】:

试试.live().delegate()

http://api.jquery.com/live/

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/

【讨论】:

从 jQuery 1.71 开始,.live() 已弃用,delegate() 已被 .on() 方法取代【参考方案8】:

使用委托将事件应用于动态生成的内容的最佳方式。

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

所以你的代码现在是这样的

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

【讨论】:

【参考方案9】:

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

首先:在正文或文档上使用委托

例如:

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

为什么?

答案:根据一组特定的根元素,为现在或将来匹配选择器的所有元素附加一个或多个事件的处理程序。 链接:http://api.jquery.com/delegate/

第二:把你的函数放在"$(document)",使用"on"并将它附加到你想要触发它的元素上。 第一个参数是“事件处理程序”,第二个:元素,第三个:函数。 例如:

 $( document ).on( 'click', '.test', function () 
 ...
  alert('test');
 );

为什么?

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

【讨论】:

【参考方案10】:
$(.surrounding_div_class).on( 'click', '.test', function () 
alert( 'WORKS!' );
);

仅当具有类 .surrounding_div_class 的 DIV 是对象 .test 的直接父级时才有效

如果 div 中有另一个对象将被填充,它将无法工作。

【讨论】:

【参考方案11】:

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

通过将“测试”单击事件添加到“按钮”单击处理程序,它将在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,并在其中的元素发生变化时重新布线。

【讨论】:

【参考方案12】:

另一种更简洁的替代方法(恕我直言)是使用原始 javascript 函数来响应点击事件,然后如果您愿意,将目标元素传回 jQuery。这种方法的优点是您可以在任何地方动态添加元素,并且单击处理程序将“正常工作”,您无需担心将控制权委派给父元素等等。

第 1 步: 更新动态 html 以触发 onclick 事件。确保将“事件”对象作为参数传递

$("按钮").click(function() $("h2").html("

onclick='test(event)'>点击我

") );

第二步: 创建响应点击事件的测试函数

功能测试(e) 警报(); );

可选步骤 3: 鉴于您使用的是 jQuery,我假设获取对源按钮的引用会很有用

功能测试(e) 警报(); // 获取按钮的引用 // 此行的解释可用here var 目标 = (e.target)? e.target:e.srcElement; // 将按钮引用传递给 jQuery 以执行 jQuery 魔术 var $btn = $(目标); );

【讨论】:

【参考方案13】:

.live 函数效果很好。

用于动态添加元素到舞台。

$('#selectAllAssetTypes').live('click', function(event)
                    alert("BUTTON CLICKED");
                    $('.assetTypeCheckBox').attr('checked', true);
                );

干杯, Ankit。

【讨论】:

Live 在 Jquery 1.7 中被弃用,取而代之的是 .on。从 Jquery 1.9 开始,它甚至已被删除。 api.jquery.com/live【参考方案14】:

Jquery .on 工作正常,但我在渲染实现上述一些解决方案时遇到了一些问题。我使用.on 的问题是它以某种方式呈现事件,而不是.hover 方法。

仅供其他可能有问题的人参考。我通过为动态添加的项目重新注册悬停事件解决了我的问题:

重新注册悬停事件,因为悬停不适用于动态创建的项目。 所以每次我创建新的/动态项目时,我都会再次添加悬停代码。完美运行

$('#someID div:last').hover(
    function() 
       //...
    ,
    function() 
       //...
    
);

【讨论】:

hovermouseentermouseleave 事件 (api.jquery.com/mouseenter) 的包装器,它们又是 .on('mouseenter', handler) 的包装器。 所以这在下面使用 .on!所以我看不出这对使用.on 有什么影响。在我看来,您在这里缺少其他东西。【参考方案15】:

我正在处理向它们动态添加新元素的表格,并且在使用 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>

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

【讨论】:

【参考方案16】:

我无法直播或委托处理灯箱(小盒子)中的 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());
    )

【讨论】:

【参考方案17】:

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

【讨论】:

【参考方案18】:

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

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

您可以获取它的原始 javascript 元素并向其添加事件侦听器,例如 click

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);
    ;
  

【讨论】:

【参考方案19】:

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

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

【讨论】:

【参考方案20】:

当点击绑定到已经存在的元素时,使用“on”。

例如

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

这会有所帮助。

【讨论】:

以上是关于点击事件不适用于动态生成的元素[重复]的主要内容,如果未能解决你的问题,请参考以下文章

点击事件不适用于动态添加的按钮

Twitter BootStrap Confirmation 不适用于动态生成的元素

jquery无法为动态生成的元素添加点击事件的解决方法

Twitter Bootstrap 弹出框不适用于动态生成的内容

Javascript 不适用于 ujs 新生成的 DOM 元素

关于动态生成的行内元素添加事件问题