繁体   English   中英

jQuery插件对象:通过.on()附加了一个事件处理程序,现在有一个范围问题。 (主插件对象)

[英]jQuery plugin object: attached an event handler via .on() and now have a scope issue of this. (the main plugin object)

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

我通过使用此处找到的基本样板模板来执行此操作: https : //github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.basic.plugin-boilerplate.js

我还发现ToDo MVC普通jQuery代码是灵感的源泉,因为它没有链接许多功能并且保持了很好的分离(由于我的身份不被允许发布两个以上的链接,因此您将不得不到Google那你自己)。

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

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

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

谢谢,
亨德里克

编辑:请参阅下面我的代码

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

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

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

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

jQuery的proxy功能在较旧的浏览器中有效:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM