点击"添加"事件到jQuery插件中的单个(动态)元素

时间:2014-11-13 13:04:14

标签: jquery events dynamic jquery-plugins

我遇到了在jQuery插件中添加on click事件的问题。

以下是对所有元素进行触发(仅应触发单个元素),事件不应用于动态元素(应该) - DEMO

$.fn.myPlugin = function () {
    var element = $(this);
    var settings = { ... }
    var methods = {
        init : function() {
            $(document).on('click', element, function () {
                element.css('background', 'red');
            });
        }
    };
    return methods.init();
};

我需要插件settings.eventhoverclick,...)中的onclick事件。

如何在jquery插件中绑定动态点击事件,而不是在每个元素上触发?

2 个答案:

答案 0 :(得分:1)

你应该更接近公共jQuery plugin pattern

// method is an (optional) string to call a special method on each element
// options is an (optional) object to add or overwrite properties of the defaults
$.fn.myPlugin = function(method, options) {
    if (typeof method == 'object') options = method, method = null;
    var settings,
        defaults = {
            events: {click: function() {$(this).css({backgroundColor: settings.backgroundColor});}},
            backgroundColor: 'red',
            border: '2px solid black',
            /* all your defaults here */
        },
        methods: {
            giveBorder: function() {$(this).css({border: settings.border});}
            /* all your named methods here, you can use values from settings inside*/
        }
    settings = $.extend(true, {}, defaults, options); // merge defaults and options together
    // now apply a function to each element and return the whole collection
    // if there's a valid method do this
    if (method && methods[method]) return this.each(methods[method]);
    // otherwise do the initializing function
    else return this.each(function(i, elem) { // this 'is' the initializing function
        // put in here all you want to do with each element on init
        $.each(settings.events, function(evt, func) { // apply the event handler to each element
            if (typeof func == 'function')elem.on(evt, func);
        })
    })
};

当你现在对li-elements $('li').myPlugin()进行操作时,所有单个elems都会附加一个click-handler。但是$('li') 不活动,它只调用了DOM中的元素(旧版本的jQuery有一个.live() - 函数但是已被弃用并删除了)

所以当你想用你的插件初始化一个新创建的元素时,这样做:

var alllis = $('li').myPlugin();
var newli = $('<li>Dynamic</li>').myPlugin(); // now it has also a click-handler
$('ul').append(newli); // now it's added to the DOM
alllis.add(newli); // this way you can add it to the jQuery collection of all li

这是一个有效的DEMO,您应该使用以下内容来评估此模式的可能性:

var newli2 = $('<li>DynamicGreen</li>').myPlugin({backgroundColor: 'green'});
var newli3 = $('<li>DynamicMouseover</li>').myPlugin(
    {events: {click: 'none', mouseover: function() {$(this).css({backgroundColor: 'yellow'})} }}
);
newli3.myPlugin('giveBorder');
$('ul').append(newli2, newli3);

答案 1 :(得分:0)

我认为事件在所有静态元素上触发的原因是因为当您调用$('li').myPlugin();时,传递给插件的对象是节点列表,而不是单个节点。 this 之类的内容适用于插件应用的元素。

init : function() {
            element.each(
                function(i, el) { 
                    $(el).on('click', function () {
                        $(el).toggleClass('bg_red');
                    });
                });
        }

另外,请注意,当您在此处传递元素$(document).on('click', element, function (e) {时,它并没有按照我认为您尝试的方式将处理程序限定为此元素。 .on()仅使用选择器(即字符串)。在这种情况下,element将在event.data中传入,并且未使用。

至于为什么它不适用于动态添加的,我不确定,但我怀疑它可能是一个范围问题。