使用 public 方法的 jquery 插件的 clearInterval

clearInterval for jquery plugin with public method

我在 jquery 插件中的清除间隔有问题。下面是简化的代码。如果我在 Firefox 控制台中尝试 运行

$('.banner').pluginName().stop() 

它将继续记录 console.log(1)。我什至尝试使用 window.interval 而不是 $wrapper.interval 但仍然没有成功。我想问题出在作用域上,但为什么 window.interval 不是全局作用域?使用 public 方法清除间隔的正确方法是什么?

<html lang="en">
    <body>
        <div class="banner"></div>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>                  
      ;(function($, f) {
        $.fn.pluginName= function(o) {
            var $wrapper = this; 
            var init = function(o) {
                $wrapper.start();
                return $wrapper;
            };

            this.start = function() {
                $wrapper.interval = setInterval(function() {
              console.log(1)
                }, 1000);
            };

            //  Stop autoplay
            this.stop = function() {
            console.log(2)
            clearInterval($wrapper.interval);
                return $wrapper;
            };
          return init(o);

        };
      })(window.jQuery, false);
      $('.banner').pluginName();        
        </script>
    </body>
</html>

尝试在 this.start 之外初始化 this.interval 以便 $ wrapper.interval 在整个插件中都可以访问,而不仅仅是在 this.start 中:

$.fn.pluginName= function(o) {
        var $wrapper = this; 
        var init = function(o) {
            $wrapper.start();
            return $wrapper;
        };
        this.interval;
        this.start = function() {
            $wrapper.interval = setInterval(function() {
          console.log(1)
            }, 1000);
        };

        //  Stop autoplay
        this.stop = function() {
        console.log(2)
        clearInterval($wrapper.interval);
            return $wrapper;
        };
      return init(o);

你的代码有几个错误。

  1. 您不能在 $wrapper 上保存数据。因为它们每次都会重新创建。
  2. 您需要在创建新间隔之前停止旧间隔,否则您将丢失停止间隔的 ID。
  3. 不要污染包装纸,它们会引起问题。例如。 如果稍后,一个动画函数想要使用 .stop() 来停止动画,他们会发现他们无法停止那个

    ;(函数($, f) { $.fn.pluginName= 函数(o) { var $wrapper = this;

    /* don't save data on wrapper object directly*/
    function interval (data) {
      if (data) {
        $wrapper.data('interval', data);
      } else {
        return $wrapper.data('interval');
      }
    
    }
    
    var init = function(o) {
      if (!o || o === 'start') {
        start();
      } else {
        stop();
      }
      return $wrapper;
    };
    
    /*don't pollute wrapper, use option to switch instead*/
    
    function start() {
      /* you must stop old interval first*/
      stop();
    
      console.log('started')
      interval(setInterval(function() {
        console.log(1)
      }, 1000));
    };
    
    //  Stop autoplay
    function stop() {
      console.log('stoped')
      clearInterval(interval());
      return $wrapper;
    };
    return init(o);
    

    }; })(window.jQuery, 假); var i = $('.banner').pluginName(); $('.banner').pluginName('stop');