在不存在的元素上绑定jQuery插件

Bind jQuery plugin on element which doesn't yet exist

本文关键字:绑定 jQuery 插件 元素 不存在      更新时间:2023-09-26

可以将事件绑定到初始页面加载时不存在的元素:

$('#myParentElement').on('click','a.myClass',function(){
   alert( 'success' );
});

插件如何被绑定?例如,如果a.myClass存在于handlebars模板中,或者在初始页面加载时不存在的任何DOM中,下面的代码将不起作用。如果这个答案是特定于插件的,请限制为https://vitalets.github.io/x-editable/插件。

$('#myParentElement a.myClass').editable();

为什么我这样做....我有一堆元素,如<p data-handlebar="one">one</p>, <p data-handlebar="two">two</p>等,并被点击后,将显示一个对话框与一些由模板指定的内容。在每个模板中,我有几个相同的元素,我希望应用可编辑的

在JavaScript或jQuery中,当一个匹配特定选择器的元素被添加到DOM中时,没有简单的方法来运行一些代码。(从技术上讲,可以使用mutationobserver 完成此操作,但这既不是特别简单也不是特别有效。)

相反,你有两个选择:

  1. 将代码安排在插入元素的代码之后运行,或者

  2. 等待,直到用户以某种方式与元素交互(例如,通过单击它,聚焦它和/或将鼠标悬停在它上面,所有这些都可以捕获触发事件),并在此时运行代码。

如果您自己插入元素(例如通过在您自己的代码中调用$(element).html()),那么第一个选项很容易:只需添加代码来修改插入它的代码之后的元素。但是,如果插入是通过某个框架异步进行的,而该框架的代码您无法轻易修改,那么您需要找到某种方法将您的代码挂接到该框架中。

如果框架本身没有为此提供任何方便的机制,一个稍微有点粗糙的解决方案可能是找出框架内部使用什么方法来插入元素,并钩入该方法。例如,所有的jQuery对象方法都可以通过jQuery.fn原型对象来修改,所以如果你知道框架正在使用jQuery .html()来插入你想要修改的元素,你可以这样做:

(function  ($) {
    var oldHtml = $.fn.html;
    $.fn.html = function () {
        var rv = oldHtml.apply(this, arguments);
        this.find('a.myClass').editable();
        return rv;
    };
})(jQuery);

作为一个现实世界的例子,我在Stack Overflow非官方补丁用户脚本中使用了上述两种技术的几种变体(作为一个用户脚本,它必然需要将自己钩入可能并不总是被设计为钩入的第三方代码中):

    为了修改通过AJAX加载的元素,我使用jQuery ajaxComplete()钩子,jQuery方便地在每个AJAX请求后运行自定义代码。
  • 对于其他任务,我还像上面所示的那样钩入一堆jQuery方法。(我实际上没有钩到.html(),虽然。)
  • 作为备用方案,特别是修改链接和其他交互元素时,我还设置了单击和鼠标悬停事件处理程序(我真的应该为键盘导航添加焦点事件处理程序),以验证修改是否已经真正应用,并在最后一刻应用它们,如果它们还没有。
  • 最后,对于一些特别棘手的任务,我也诉诸于直接挂钩到JS DOM方法,甚至用我自己的包装器替换整个WebSocket类。这些都是特别丑陋的hack,因为很难使它们在不同的浏览器中健壮。