jQuery插件对象:通过.on()附加了一个事件处理程序,现在有一个范围问题. (主插件对象) [英] jQuery plugin object: attached an event handler via .on() and now have a scope issue of this. (the main plugin object)

查看:80
本文介绍了jQuery插件对象:通过.on()附加了一个事件处理程序,现在有一个范围问题. (主插件对象)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图摆脱jQuery插件中的意大利面条代码,并以一种更加结构化的方式工作.

I am attempting to move away from spaghetti code in my jQuery plugins and work in a more structured manner.

我是通过使用以下基本模板来做到这一点的:

I am doing so by using the basic boilerplate template found here: https://github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.basic.plugin-boilerplate.js

我还发现ToDo MVC普通jQuery代码是一个灵感来源,因为它没有链接许多功能,并且使各方面保持良好的分离(由于我的身份不足,我不允许发布两个以上的链接,因此您将必须自己向Google进行搜索.)

I also found the ToDo MVC plain jQuery code a source of inspiration because it doesn't chain many functions and keeps things nicely separated (I am not allowed to post more than two links due to my lack of status, so you will have to Google that yourself).

总的来说,我发现上述两种方法很好地结合在一起使用,但是如果没有经常引用this(根插件对象),似乎没有办法像这样工作.这本身不是问题,但是有时this超出范围.我还没有真正找到一种优雅的解决方法,尤其是当通过jQuery on.()绑定事件处理程序时.请查看我的JSFiddle以了解我的意思: http://jsfiddle.net/hendrikdegraaf/wzp3ok4h/18/

All in all I find a combination of the two above quite good to work with, but there seems to be no way to work like this without referencing this (the root plugin object) quite often. This in itself is not an issue, but sometimes this becomes out of scope. I haven't really found an elegant way around it, especially when binding event handlers via jQuery on.(). Please see my JSFiddle for an illustration of what I mean: http://jsfiddle.net/hendrikdegraaf/wzp3ok4h/18/

我发现将插件对象作为event.data.base传递给event.data对象有点尴尬(这很冗长,并且损害了我的代码的可读性).有没有更好的方法来引用主插件对象?

I find that passing the plugin object in the event.data object as event.data.base a bit awkward (it's just very verbose and harms readability of my code). Is there not a better way to reference the main plugin object?

在使用这种结构化插件的方式之前,我曾遇到过可变范围的问题,因此,任何有关如何以合理方式构造插件的一般建议也将不胜感激.

I've had issues with variable scope before when using this way of structuring my plugin, so any general advice on how to structure my plugins in a sensible way would be appreciated as well.

谢谢,
亨德里克

Thanks,
Hendrik

请在下面查看我的代码

;(function ( $, window, document, undefined ) {

    // Create the defaults once
    var pluginName = "myplugin",
        defaults = {
            settingA : 'someValue',
            settingB : 'someValue'
        };

    // The actual plugin constructor
    function Plugin(params) { 
        params.options = $.extend( {}, defaults, params.options);
        this.params = params;
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            var base = this; // cache the context so we can still reference it when entering new context
            this.cacheElements();
            this.bindEvents(base);
        },
        cacheElements : function (base) { //cache elements
            this.$el = $('div.doSomething');
        },
        bindEvents : function (base) { // bind some touch functions to touch events, and modal window hidden event
            this.$el.on('click', {base: base}, this.myFunction);
        },
        myFunction : function () {
            console.log(this); //this now refers to $el

        }
    };
    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function ( params ) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName,
                new Plugin(params));
            }
        });
    };

})( jQuery, window, document );

推荐答案

我最近遇到了这个问题,发现了一些解决方法.

I recently ran into this issue, and I found a few work-arounds.

JavaScript的bind可在现代浏览器中使用:

JavaScript's bind works in modern browsers:

bindEvents : function (base) {
    this.$el.on('click', {base: base}, this.myFunction.bind(this));
},
myFunction : function () {
    console.log(this); // Plugin context
}

jQuery的proxy函数可在较旧的浏览器中使用:

jQuery's proxy function works in older browsers:

bindEvents : function (base) {
    this.$el.on('click', {base: base}, $.proxy(this.myFunction, this));
},
myFunction : function () {
    console.log(this); // Plugin context
}

您还可以在bindEvents函数内部创建事件处理函数,并允许自己访问两个上下文:

You can also create the event handler function inside your bindEvents function, and give yourself access to both contexts:

bindEvents : function (base) {
    var instance = this;
    var myFunction = function() {
        console.log(this); // element context
        console.log(instance); // Plugin context
    };
    this.$el.on('click', {base: base}, myFunction);
}

这篇关于jQuery插件对象:通过.on()附加了一个事件处理程序,现在有一个范围问题. (主插件对象)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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