5

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

采取这种情况:

您想为 wordpress、drupal 或基本上任何使用第三方功能的网站构建 jquery 插件。由于您不提前知道每个特定事件和选择器,您需要确定如何将 jquery/javascript 功能添加到动态创建的元素。另外,您不知道元素是如何创建的(使用 ajax/php/etc 进行回调)。

例子:

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

选择2

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

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

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

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

但是,由于我不提前知道动态选择的所有选择器(因为许多是由 3rd 方插件添加的),所以 select2 不适用于新选择。因此,上述内容仅适用于每种情况。

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

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

我读到javascriptdocument.getElementsByTagName识别dom中的变化并反映在集合中。我也研究了querySelectorAll,但不确定它是如何工作的。

我还尝试弄乱 theMutationObserver并检查.addednodes.lengthselect 标签是否更改,但我并没有真正得到任何地方。

更新

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

将 select2 插件添加到 wordpress 的示例。 单击快速编辑添加新字段

新选择无法正确加载。 并且单击它们时没有下拉菜单。

在选择上单击一次,然后在其下方单击将错误地加载 select2 覆盖

4

2 回答 2

6

Solution:

I am going to answer your base question "Attach javscript/jquery event on dynamically created elements".

For adding event on dynamically created elements you have to take advantage or Event Delegation, when a event trigger on an element it propagates.

So if you attach event handler on a root element( it can be body or any parent element which is present when you are attaching this event)

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

});

Now this will capture event from dynamically created elements as well.

于 2014-06-07T09:45:10.247 回答
2

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

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 事件。当使用相同的标签或类添加新元素时,它会自动注册事件。

于 2014-06-07T10:22:14.037 回答