jQuery插件 - 范围/参考问题

时间:2016-12-08 07:58:11

标签: jquery scope closures

我已经简化了下面的代码来概述问题。当我调用类似$('#element').plugin('hide');的插件方法时,它会起作用,但是当我从内部show()方法调用它时,如this.hide()它不起作用或调用它jQuery hide()方法。

我尝试了var self = this$.proxy()apply()call(),但没有成功。这是jsBin

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

    var defaults = {
        type: 'standard',
    };
    var methods = {
        init: function(options){
            console.log('IN - INIT()');
            if(options){
                $.extend(defaults, options);
            }
        },
        show: function(arg){
            console.log('IN - SHOW()');         
            var $this = this; // Here might be the problem
            this.addClass(arg.type);
            this.find('.close-button').on('click', function(){
                $this.hide(); // Here might be the problem      
            });
        },
        hide: function(){
            console.log('IN - HIDE()');
        }
    };

    $.fn.plugin = function(method){
        var args = arguments;
        var $this = this;
        return this.each(function(){
            if(methods[method]){
                return methods[method].apply($this, Array.prototype.slice.call(args, 1));
            }else if (typeof method === 'object' || ! method){
                return methods.init.apply($this, Array.prototype.slice.call(args, 0));
            }else{
                $.error('Method ' +  method + ' does not exist on jQuery.plugin');
            }
        });
    };

}(jQuery, window, document));

1 个答案:

答案 0 :(得分:1)

当你在show中调用$ this.hide()时,它会尝试在元素上调用jquery的hide方法,当你将方法更改为hide1或者它会抛出错误时,因为它正在寻找对于元素上的方法,因为它不存在它会抛出错误

在插件上定义方法时,需要将hide作为插件调用('隐藏') 这就是$('#box')。插件('隐藏')工作的原因

更改关闭按钮

的onclick的绑定事件



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

  var defaults = {
    type: 'standard',
  };
  var methods = {
    init: function(options) {
      console.log('IN - INIT()');
      if (options) {
        $.extend(defaults, options);
      }
    },
    show: function(arg) {
      console.log('IN - SHOW()');
      var $this = this;
      this.css({
        display: 'block'
      });

      this.find('.close-button').on('click', function() {
        $this.plugin('hide'); // Here might be the problem      
      });
    },
    hide: function() {
      console.log('IN - HIDE()');
      this.css({
        display: 'none'
      });
    }
  };

  $.fn.plugin = function(method) {
    var args = arguments;
    var $this = this;
    return this.each(function() {
      if (methods[method]) {
        return methods[method].apply($this, Array.prototype.slice.call(args, 1));
      } else if (typeof method === 'object' || !method) {
        return methods.init.apply($this, Array.prototype.slice.call(args, 0));
      } else {
        $.error('Method ' + method + ' does not exist on jQuery.plugin');
      }
    });
  };

}(jQuery, window, document));

$('#box').plugin('show', {type: 'normal'});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="box">
  <span class="close-button">HIDE</span>
</div>
&#13;
&#13;
&#13;

而不是将此引用存储到变量

使用此代码更改此范围

this.find('.close-button').click($.proxy(function () {
     this.plugin('hide');
 },$this));

希望这有帮助