jQuery插件也适用于动态创建的元素

Ste*_*e B 11 jquery jquery-plugins

我正在编写一个jquery插件,它应该处理指定开放行为的链接的额外信息.

例如,我想支持标记,如:

  1. <a href="somewhere" data-openmode="NewWindow" class="openmode" />
  2. <a href="somewhere" data-openmode="Modal" class="openmode" />
  3. <a href="somewhere" class="openmode" /> <!-- Not specified -->

第一个应该在新窗口中打开,第二个应该在模式对话框中打开,第三个应该以本机行为打开(无论在标签上设置了什么目标).

我想为这种行为创建一个尽可能通用的插件.我现在写的:

(function ($) {
    $.fn.myOpenMode = function () {
        return this.mousedown(function () {
            var $this = $(this);

            var mode = $this.data("openmode");
            var href = this.href;
            var handled = true;
            if (mode) {
                switch (mode) {
                    case "NewWindow":
                    case "1":
                        window.open(href, "_blank");
                        break;
                    case "Dialog":
                    case "2":
                        openAsDialog(href);
                        break;

                    // Actually, there are other options, but I removed them for clarity

                    default:
                        handled = false;
                }
            }
            else {
                handled = false;
            }
            return !handled;
        });
    };
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

这段代码允许我从任何页面调用类似于:

$(function(){
    $(".openmode").myOpenMode();
});
Run Code Online (Sandbox Code Playgroud)

这适用于静态生成的标记.但是,我的应用程序可能会动态生成标记(大多数时候使用jsRender,但这并不重要).

但是因为在加载javascript文件时会设置一次此行为,所以它不会采用动态生成的对象.

我该怎么办才能处理我的要求?

  1. 我试图使用该on方法来监控加载事件,但这不起作用:

    $(function(){
        $(document).on("load",".openmode", function() { $(this).myOpenMode(); });
    });
    
    Run Code Online (Sandbox Code Playgroud)

    我明白这不起作用,因为"加载"事件不起泡

  2. 我正在考虑修改我的插件以在插件中放置"on",但我不喜欢这个想法,因为它在插件中引入了一些超出范围的行为

  3. 我也可以在每次创建动态节点时调用插件,但它也会将依赖项引入其他部分.我的插件不会像我想的那样自主.

有没有人有建议来处理我的要求,让我的插件尽可能隔离?

[编辑]这应该适用于IE8及更高版本(理想情况下与其他浏览器一起使用)

[编辑]这里是一个说明问题的jsFiddle(只需点击Add并尝试点击新创建的元素).

Aln*_*tak 8

添加的插件$.fn应仅适用于列出的元素,而不适用于任何将来的元素.

您应该专注于让插件提供机制,例如:

(function($) {

    $.fn.openmode = function(cmd) {
        cmd = cmd || 'on';

        switch (cmd) {

            case 'click':
                // read props, open windows, etc
                break;

            case 'on':
                this.addClass('openmode');
                break;

            case 'off':
                this.removeClass('openmode');
                break;
         }
    });

})(jQuery);
Run Code Online (Sandbox Code Playgroud)

然后允许插件用户注册触发该机制的事件处理程序,必要时使用事件委托:

$(document).on('click', 'a.openmode', function() {
    $(this).openmode('click');
});
Run Code Online (Sandbox Code Playgroud)

后一个代码也可以作为实用函数放入jQuery命名空间:

(function($) {
    $.openmode = function(cmd) {
        cmd = cmd || 'on';

        switch (cmd) {

            case 'on':
                $(document).on('click.openmode', 'a.openmode', function() {
                    $(this).openmode('click');
                });
                break;

            case 'off':
                $(document).off('click.openmode', 'a.openmode');
                break;
        }
     };
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

这样只是打电话:

$.openmode();
Run Code Online (Sandbox Code Playgroud)

将完成为每个当前(和未来).openmode元素启用插件所需的所有工作.