8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

在动态创建的元素上进行事件绑定?

Can Demir 1月前

44 0

我有一段代码,循环遍历页面上的所有选择框,并将 .hover 事件绑定到它们,以便在鼠标打开/关闭时对它们的宽度进行一些调整。这发生在页面上......

我有一段代码,循环遍历页面上的所有选择框,并将事件绑定 .hover 到它们,以便对它们的宽度进行一些调整 mouse on/off .

这在页面就绪时发生并且运行良好。

我遇到的问题是,初始循环之后通过 Ajax 或 DOM 添加的任何选择框都不会绑定事件。

我已经找到了这个插件( jQuery Live Query 插件 ),但在使用插件向我的页面添加另外 5k 之前,我想看看是否有人知道如何做到这一点,无论是直接使用 jQuery 还是通过其他选项。

帖子版权声明 1、本帖标题:在动态创建的元素上进行事件绑定?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Can Demir在本站《ajax》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 从 jQuery 1.7 开始, 您应该使用 jQuery.fn.on 并填写选择器参数:

    $(staticAncestors).on(eventName, dynamicChild, function() {});
    

    解释:

    这称为事件委托,其工作原理如下。事件附加到 staticAncestors 应处理的元素的静态父元素 ()。每次事件在此元素或其中一个后代元素上触发时,都会触发此 jQuery 处理程序。然后,处理程序检查触发事件的元素是否与您的选择器 ( dynamicChild ) 匹配。如果匹配,则执行您的自定义处理程序函数。


    在此之前 ,推荐的方法是使用 live() :

    $(selector).live( eventName, function(){} );
    

    然而, live() 在 1.7 版中, 被弃用,取而代之的是 on() ,并在 1.9 版中被彻底删除。 live() 签名:

    $(selector).live( eventName, function(){} );
    

    ... 可以用以下 on() 签名替换:

    $(document).on( eventName, selector, function(){} );
    

    例如,如果您的页面正在动态创建具有类名的元素, dosomething 您会将事件绑定到 已经存在的父级 (这是问题的核心,您需要绑定到某个存在的内容,而不是绑定到动态内容),这可以是(也是最简单的选择) document 。但请记住, document may not be the most efficient option .

    $(document).on('mouseover mouseout', '.dosomething', function(){
        // what you want to happen when mouseover and mouseout 
        // occurs on elements that match '.dosomething'
    });
    

    事件绑定时存在的任何父级都可以。例如

    $('.buttons').on('click', 'button', function(){
        // do something here
    });
    

    适用于

    <div class="buttons">
        <!-- <button>s that are generated dynamically and added here -->
    </div>
    
  • 在此了解有关事件委托的更多信息:learn.jquery.com/events/event-delegation。

  • 该解决方案在 jQuery 3 和 Firefox 中仍然会带来错误,因为在清除 html 并重新创建它之后,事件被触发两次,

  • 虽然该解决方案至少十次提到“事件委托”,但它并没有真正向您展示如何将事件委托给动态绑定函数。

  • 的文档中有很好的解释 jQuery.fn.on .

    简而言之:

    事件处理程序仅绑定到当前选定的元素;它们必须在代码调用时存在于页面上 .on() .

    因此在下面的例子中, #dataTable tbody tr 在代码生成之前必须存在。

    $("#dataTable tbody tr").on("click", function(event){
        console.log($(this).text());
    });
    

    如果要将新的 HTML 注入页面,最好使用委托事件来附加事件处理程序,如下所述。

    委托事件 的优点是它们可以处理稍后添加到文档的后代元素的事件。例如,如果表格存在,但行是使用代码动态添加的,则以下方法将处理它:

    $("#dataTable tbody").on("click", "tr", function(event){
        console.log($(this).text());
    });
    

    除了能够处理尚未创建的后代元素上的事件之外,委托事件的另一个优点是,当必须监视许多元素时,它们可以大大降低开销。在包含 1,000 行的数据表中 tbody ,第一个代码示例将处理程序附加到 1,000 个元素。

    委托事件方法(第二个代码示例)仅将事件处理程序附加到只有一个元素,即 tbody ,并且事件仅需向上冒泡一个级别(从点击 tr tbody )。

    注意: 委托事件不适用于 SVG .

  • 这是一个 纯 JavaScript 解决方案,没有任何库或插件:

    document.addEventListener('click', function (e) {
        if (hasClass(e.target, 'bu')) {
            // .bu clicked
            // Do your thing
        } else if (hasClass(e.target, 'test')) {
            // .test clicked
            // Do your other thing
        }
    }, false);
    

    哪里 hasClass

    function hasClass(elem, className) {
        return elem.className.split(' ').indexOf(className) > -1;
    }
    

    现场演示

    感谢 Dave 和 Sime Vidas

    使用更现代的 JS, hasClass 可以实现如下:

    function hasClass(elem, className) {
        return elem.classList.contains(className);
    }
    

    下面嵌入了相同的 jsfiddle Live 演示:

    function hasClass(elem, className) {
      return elem.classList.contains(className);
    }
    
    document.addEventListener('click', function(e) {
      if (hasClass(e.target, 'bu')) {
        alert('bu');
        document.querySelector('.bu').innerHTML = '<div class="bu">Bu<div class="tu">Tu</div></div>';
      } else if (hasClass(e.target, 'test')) {
        alert('test');
      } else if (hasClass(e.target, 'tu')) {
        alert('tu');
      }
    
    }, false);
    .test,
    .bu,
    .tu {
      border: 1px solid gray;
      padding: 10px;
      margin: 10px;
    }
    <div class="test">Test
      <div class="bu">Bu</div>test
    </div>
  • @EugenKonkov Element.classList 在较旧的浏览器上不受支持。例如,IE < 9。

  • 一篇关于如何使用原始脚本而不是 jQuery 来完成工作的好文章 - toddmotto.com/…

  • 您可以在创建对象时向其添加事件。如果您在不同时间向多个对象添加相同的事件,则创建命名函数可能是最佳方法。

    var mouseOverHandler = function() {
        // Do stuff
    };
    var mouseOutHandler = function () {
        // Do stuff
    };
    
    $(function() {
        // On the document load, apply to existing elements
        $('select').hover(mouseOverHandler, mouseOutHandler);
    });
    
    // This next part would be in the callback from your Ajax call
    $("<select></select>")
        .append( /* Your <option>s */ )
        .hover(mouseOverHandler, mouseOutHandler)
        .appendTo( /* Wherever you need the select box */ )
    ;
    
  • 您可以简单地将事件绑定调用包装成一个函数,然后调用两次:一次是在文档就绪时,一次是在添加新 DOM 元素的事件之后。如果这样做,您将希望避免在现有元素上两次绑定相同的事件,因此您需要取消绑定现有事件或(更好的)仅绑定到新创建的 DOM 元素。代码看起来如下所示:

    function addCallbacks(eles){
        eles.hover(function(){alert("gotcha!")});
    }
    
    $(document).ready(function(){
        addCallbacks($(".myEles"))
    });
    
    // ... add elements ...
    addCallbacks($(".myNewElements"))
    
  • 这篇文章确实帮助我解决了我在加载相同表单时遇到的问题,并获得了 1、2、4、8、16... 个提交。我没有使用 .live(),而是在 .load() 回调中使用了 .bind()。问题解决了。谢谢!

  • 引用 13

    这是通过事件委托实现的 。事件将绑定在包装器类元素上,但将被委托给选择器类元素。这就是它的工作原理。

    $('.wrapper-class').on("click", '.selector-class', function() {
        // Your code here
    });
    

    和 HTML

    <div class="wrapper-class">
        <button class="selector-class">
          Click Me!
        </button>
    </div>    
    

    #注意:wrapper-class 元素可以是任何内容,例如 document、body 或您的包装器。 包装器应该已经存在 。但是, selector 不一定需要在页面加载时显示。它可能稍后出现,并且事件将 selector 毫无疑问地 .

  • 如果您在父元素和后代元素上绑定相同的事件,则可以使用 event.stopPropagation() 来停止它

  • 尝试使用 .live() 而不是 .bind() .live() 在 Ajax 请求执行后, .hover 绑定

  • 方法 live() 在版本 1.7 中已被弃用,取而代之的是 on,并在版本 1.9 中被删除。

  • 动态创建元素上的事件绑定

    单个元素:

    $(document.body).on('click','.element', function(e) {  });
    

    子元素:

     $(document.body).on('click','.element *', function(e) {  });
    

    注意添加的 * 。该元素的所有子元素都会触发事件。

    我注意到:

    $(document.body).on('click','.#element_id > element', function(e) {  });
    

    它现在不再起作用了,但以前是可以的。我一直在使用 Google CDN ,但我不知道他们是否对其进行了更改。

  • 我更喜欢使用选择器并将其应用于文档。

    这将自身绑定在文档上并适用于页面加载后呈现的元素。

    例如:

    $(document).on("click", 'selector', function() {
        // Your code here
    });
    
  • 您可以使用 live() 方法将元素(甚至是新创建的元素)绑定到事件和处理程序,例如 onclick 事件。

    下面是我编写的示例代码,您可以看到 live() 方法如何将选定的元素(甚至是新创建的元素)绑定到事件:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Untitled Document</title>
        </head>
    
        <body>
            <script src="http://code.jquery.com/jquery-latest.js"></script>
            <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>
    
            <input type="button" id="theButton" value="Click" />
            <script type="text/javascript">
                $(document).ready(function()
                    {
                        $('.FOO').live("click", function (){alert("It Works!")});
                        var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                             autoOpen: false,
                                                                                                             tite: 'Basic Dialog'
                                                                                                         });
                        $('#theButton').click(function()
                        {
                            $dialog.dialog('open');
                            return('false');
                        });
                        $('#CUSTOM').click(function(){
                            //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                            var button = document.createElement("input");
                            button.setAttribute('class','FOO');
                            button.setAttribute('type','button');
                            button.setAttribute('value','CLICKMEE');
                            $('#container').append(button);
                        });
                        /* $('#FOO').click(function(){
                                                         alert("It Works!");
                                                     }); */
                });
            </script>
        </body>
    </html>
    
  • 引用 20

    另一个解决方案是在创建元素时添加侦听器。不要将侦听器放在主体中,而是在创建元素时将侦听器放在元素中:

    var myElement = $('<button/>', {
        text: 'Go to Google!'
    });
    
    myElement.bind( 'click', goToGoogle);
    myElement.append('body');
    
    
    function goToGoogle(event){
        window.location.replace("http://www.google.com");
    }
    
返回
作者最近主题: