首页 文章

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

提问于
浏览
409

这个问题在这里已有答案:

<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 关联的点击事件 . 但事件不起作用 .

有人可以帮忙吗?

20 回答

  • 5

    您正在使用的 click() 绑定称为"direct"绑定,它仅将处理程序附加到已存在的元素 . 它赢得了't get bound to elements created in the future. To do that, you'必须使用on()创建一个"delegated"绑定 .

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

    资源

    这是你要找的东西:

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


    Previous Answer

    尝试使用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 .

  • 3

    使用.on() method with delegated events

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

    .on() 方法允许您将任何所需的事件处理程序委派给:
    current 元素或 future 元素稍后添加到DOM .

    P.S:不要使用.live()!从jQuery 1.7开始,不推荐使用.live()方法 .

  • 2

    Reason:

    在jQuery中,Click() - 仅在html代码中已存在该元素时才附加事件处理程序 .

    它不会考虑页面加载后动态创建的新元素(Future元素) .

    javascript or jquery(not in html) 的帮助下创建动态元素 .

    因此点击事件不会触发 .

    Solution :

    要克服这一点,我们应该使用 on() 函数 .

    delegate(),live()on() 函数具有优于DOM元素的优点 .

    on 可以触发现有元素以及未来元素 .

    on 可以考虑整个页面中存在的元素 .

    不推荐使用delegate(),live()函数(不要使用这些函数) .

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

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

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

    变成:

    $(document).on('click','.test',function(){
    
      alert('Clicked');
    
    });
    
  • 3

    Add this function in your js file. It will work on every browser

    $(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>
    
  • 2

    更改

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

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

    现场演示

    jQuery .live()

  • 16

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

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

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

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

    试试 .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/

  • 11

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

    第一:在Body或Document上使用委托

    例如:

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

    为什么?

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

    第二步:使用"on"将函数放在"$( document )",并将其附加到要触发它的元素 . 第一个参数是"event handler",第二个参数是元素,第三个参数是函数 . 例如:

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

    为什么?

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

  • 3

    使用委派在动态生成的内容上应用事件的最佳方法 .

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

    所以你的代码现在就像这样

    $(document).on("click",".test",function(){
        // code goes here
    });
    
  • 6
    $(.surrounding_div_class).on( 'click', '.test', function () {
    alert( 'WORKS!' );
    });
    

    仅当具有类.surrounding_div_class的DIV是对象的直接父级时才会起作用.test

    如果div中有另一个对象将被填充它将无法正常工作 .

  • 196

    您遇到的问题是,在 DOM 中有"test"类的任何内容之前,您试图将"test"类绑定到该事件 . 虽然看起来这似乎都是动态的,但实际发生的是 JQueryDOM 传递并在 ready() 函数触发时连接click事件,这发生在您在按钮事件中创建"Click Me"之前 .

    通过将"test" Click事件添加到"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 并在其中的元素发生变化时重新布线 .

  • 3

    .live功能很棒 .

    它是为舞台动态添加元素 .

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

    干杯,Ankit .

  • 12

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

    对于其他可能也有问题的人来说,只是fyi . 我通过为动态添加的项重新注册悬停事件来解决我的问题:

    重新注册悬停事件,因为悬停不适用于动态创建的项目 . 所以每次我创建新/动态项目时,我再次添加悬停代码 . 工作得很好

    $('#someID div:last').hover(
        function() {
           //...
        },
        function() {
           //...
        }
    );
    
  • 76

    我无法上传或委托在灯箱(tinybox)中使用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());
        })
    }
    
  • 4

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

  • 3

    如果你有一个dinamically添加链接到一些容器或身体:

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

    所以你会收到一条消息说

    好的

    它具有比其他替代品更好的性能 .

    Extra :你可以获得更好的性能,避免使用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);
        };
      }
    
  • 3

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

    Step 1: 更新动态html以触发onclick事件 . 务必将'event'对象作为参数传递

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

    Step 2: 创建测试功能以响应click事件

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

    Optional Step 3: 鉴于您正在使用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);
    
        });
    
  • 0

    我正在使用表向它们动态添加新元素,当使用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() .

  • 605

    您可以添加单击以动态创建的元素 . 以下示例 . 使用When确保完成它 . 在我的例子中,我正在使用类扩展抓取div,添加“单击以查看更多” Span ,然后使用该 Span 隐藏/显示原始div .

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

    使用'on',因为click会绑定到已存在的元素 .

    例如

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

    这会有所帮助 .

相关问题