jQuery插件也可应用于动态创建的元素 [英] jQuery plugin to apply also on dynamically created elements

查看:68
本文介绍了jQuery插件也可应用于动态创建的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个jquery插件,该插件应处理有关链接的更多信息以指定打开行为.

I'm writing a jquery plugin that should handle extra information on links to specify open behavior.

例如,我想支持像这样的标记:

For example, I want to supports markup like :

  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 -->
  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 -->

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

The first should open in a new window, the second in a modal dialog, the third should open with the native behavior (whatever target has been set on the tag).

我想为此行为创建一个尽可能通用的插件.我已经写过:

I would like to create a plugin for this behavior as generic as possible. I've written by now:

(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);

此代码使我可以从任何页面调用以下内容:

This code allows me to call from any page something like:

$(function(){
    $(".openmode").myOpenMode();
});

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

This is working for statically generated tags. However, my applications may generate markup dynamically (most of time using jsRender, but this does not matters).

但是由于此行为是在加载javascript文件时设置的,因此不会接收动态生成的对象.

But because this behavior is set up once when the javascript file is loaded, it won't take dynamically generated objects.

我应该怎么处理我的要求?

What should I do to handle my requirement?

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

  1. I tried to use the on method to monitor load events, but this does not works :

$(function(){
    $(document).on("load",".openmode", function() { $(this).myOpenMode(); });
});

我知道这是行不通的,因为加载"事件不会冒泡

I understand this does not works because the "load" event does not bubbles

我当时正在考虑修改插件以将"on"置于插件内部,但是我不喜欢这个想法,因为它在插件中引入了一些超出范围的行为

I was thinking about modifying my plugin to put the "on" inside the plugin, but I don't like this idea because it introduces some out of scope behavior in the plugin

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

I can also call the plugin each time a dynamic node is created, but it will also introduce dependencies into other parts. My plugin won't be as autonomous as I would like.

有人建议处理我的要求,让我的插件尽可能孤立吗?

Does anyone has a suggestion to handle my requirement, keeping my plugin as isolated as possible?

[edit] 这应该适用于IE8和更高版本(最好是与其他浏览器一起使用)

[edit] This should works with IE8 and later (and ideally with other browsers)

[edit] 这是一个 jsFiddle ,它说明了这个问题(只需单击Add并尝试单击新创建的元素即可.

[edit] here is a jsFiddle that illustrate the issue (just click on Add and try to click on the newly created element).

推荐答案

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

Plugins added to $.fn should only apply to the listed elements, and not any future elements.

您应该集中精力让插件提供机制,例如:

You should concentrate on having your plugin provide the mechanism, e.g.:

(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);

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

and then allow the plugin user to register the event handler which triggers that mechanism, using event delegation if necessary:

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

后面的代码也可以作为实用程序功能放入jQuery命名空间:

The latter code could be put into the jQuery namespace too, as a utility function:

(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);

只需致电:

$.openmode();

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

will do all the work required to enable the plugin for every current (and future) .openmode element.

这篇关于jQuery插件也可应用于动态创建的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆