在尚未存在的元素上绑定jQuery插件

时间:2016-08-17 04:44:16

标签: javascript jquery dom

我可以将事件绑定到初始页面加载时不存在的元素,如下所示:

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

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

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

为什么我这样做....我有一些元素,如<p data-handlebar="one">one</p><p data-handlebar="two">two</p>等,点击后,会显示一个对话框,其中包含模板指定的某些内容。在每个模板中,我有几个我想要应用的相同元素。

1 个答案:

答案 0 :(得分:1)

只要将匹配特定选择器的元素添加到DOM,JavaScript或jQuery就没有简单的方法来运行某些代码。 (从技术上讲,你可以使用MutationObservers执行此操作,但这既不是特别简单也不是特别有效。)

相反,您有两种选择:

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

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

  3. 如果你自己插入元素(例如在你自己的代码中调用$(element).html()),那么第一个选项很简单:只需添加代码即可在插入代码后修改元素。但是,如果插入是通过某些框架异步发生的,而这些框架的代码无法轻易修改,那么您需要找到一些方法将代码挂钩到该框架中。

    如果框架本身没有提供任何方便的机制,那么一个稍微讨厌的解决方案可能是找出框架在内部使用什么方法来插入元素,并将其挂钩。例如,可以通过jQuery.fn原型对象修改所有jQuery对象方法,因此,例如,知道框架正在使用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 Unofficial Patch用户脚本中使用了上述两种技术的几种变体(作为用户脚本,必须将自己挂钩到第三方代码中并不总是被设计为被挂钩):

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