在动态创建的元素上附加javascript / jquery事件

时间:2014-06-07 07:58:27

标签: jquery dom dynamic traversal mutation-observers

我已经看到很多与此类似的不同问题,但所有这些问题通常都针对特定的选择器。如果某处有重复,请告诉我,我错过了。

采取这种情况:

你想为wordpress,drupal或任何使用第三方功能的网站构建一个jquery插件。由于您事先并不知道每个特定事件和选择器,因此您需要定位如何将jquery / javascript功能添加到动态创建的元素中。另外,你不知道如何创建元素(使用ajax / php /等回调)。

示例:

我最近尝试将select2或selectize添加到我的整个网站。不幸的是,由于我无法提前确定将添加选择元素(来自其他插件/模块),我无法确保选择jquery将适用于新创建的选择。

选择二

这是常规方法,但不适用于动态创建或克隆的选择:

<script type='text/javascript'>
    jQuery(document).ready(function($) {
        $("select").select2();
    });
</script>

如果我知道添加了这些选项的所有事件,我可以简单地执行以下操作:

 $( ".some_button_that_creates_new_selects" ).on( "click", function() {
        jQuery("select").select2(); 
    });
 });

但是,由于我不知道所有动态选择器的选择器(因为许多是由第三方插件添加的),所以select2将不适用于新的选择。因此,上述内容仅适用于每例senerio。

我需要找到一种遍历dom树的方法,并识别何时创建新选择。

我尝试使用.on定位多个事件,但它根本无法正常工作。

我读到javascript document.getElementsByTagName识别dom中的更改并反映在集合中。我也调查了querySelectorAll,但不确定它是如何工作的。

我还尝试弄乱MutationObserver并检查选择标记的.addednodes.length是否发生了变化,但我确实没有找到任何地方。

更新

在做了一些测试后,我意识到问题可能在于select2插件本身。 Select2加载动态选择但没有获得定位。 Chrome最终会抛出typeerros:无法读取null的属性'find',无法读取属性'hasclass'为null。

Example adding the select2 plugin to wordpress. Clicking quick edit adds new fields

New selects don't load properly. and there is no dropdown when clicking on them.

Clicking once on the select and then below it will load the select2 overlay wrong

2 个答案:

答案 0 :(得分:6)

解决方案:

我将回答您的基本问题&#34;在动态创建的元素上附加javscript / jquery事件&#34;。

要在动态创建的元素上添加事件,您必须利用事件委派,当事件触发它传播的元素时。

因此,如果您在根元素上附加事件处理程序(它可以是正文或附加此事件时存在的任何父元素)

$("body").on("click","elementSelector", function(){

});

现在这将从动态创建的元素中捕获事件。

答案 1 :(得分:2)

最简单的解决方案是在javascript中创建一个函数,每次在页面上动态添加任何控件时都会调用该函数,在该函数中,您可以放置​​检查,以便仅在新组件上注册事件。 e.g。

function registerEvents()
{
    //Get all the select events from the page and register events only on those controls which are new ..
    $("select").each(function() {

        if (!$(this).hasClass("registeredEvent")) {

              $(this).addClass("registeredEvent");
              $(this).select2();
        }
    });

}

通过不同的方法可以实现相同的结果。

同时检查jquery中的.live事件..当新元素添加了相同的标记或类时,它会自动注册事件。