jQuery插件回调$这不能返回元素

时间:2015-07-10 12:11:28

标签: javascript jquery

我正在学习编写迷你jQuery插件工具。

我的插件正在帮助用户检查用户鼠标滚轮是否向上滚动或向下滚动以触发回调功能。

我有四个div,当我的鼠标指针悬停它并用鼠标滚轮向上滚动时,插件回调将改变这个div的背景颜色。

不幸的是,我的回调'这不是指向这个元素。 我需要一些帮助。

风格

    body {background: #2A2B30;}
    .wrapper {margin-top: 100px;}
    .wrapper div.content {border-radius: 7px; border: 1px solid #000; min-height: 300px; margin-top: 30px; background: #ededed; padding: 30px; font-size: 20px;}

HTML

    <div class="container">
    <div class="wrapper clearfix">
        <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
            <div class="blk content"> </div>
        </div>
        <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
            <div class=" content"> </div>
        </div>
        <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
            <div class="blk content"> </div>
        </div>
        <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
            <div class=" content"> </div>
        </div>
    </div>
</div>

调用插件

$(function() {
    $('.blk').scroll({
        lastAnimation   : 0,
        quietPeriod     : 500,
        animationTime   : 800,
        ScrollUp : function() {
            $(this).css('background', 'red');
        },
        ScrollDown : function() {
            alert('Scroll Down');
        }
    });
});

我的插件

(function($) {
$.fn.scroll = function( options ) {

    var settings = $.extend({
        // selector         : $(this),
        lastAnimation    : null,
        quietPeriod      : null,
        animationTime    : null,
        ScrollUp         : null,
        ScrollDown       : null
    }, options);

    return this.each( function() {
        var lastAnimation = settings.lastAnimation;
        var quietPeriod = settings.quietPeriod;
        var animationTime = settings.animationTime;

        function init(event, delta) {
            deltaOfInterest = delta;
            var timeNow = new Date().getTime();
            if( timeNow - lastAnimation < quietPeriod + animationTime ) {
                event.preventDefault();
                return;
            }

            if ( deltaOfInterest < 0 ) {
                // Call Back
                if ( $.isFunction( settings.ScrollUp ) ) {
                    settings.ScrollUp.call(this);
                }
            } else {
                // Call Back
                if ( $.isFunction( settings.ScrollDown ) ) {
                    settings.ScrollDown.call(this);
                }
            }

            lastAnimation = timeNow;
        }

        $(this).bind('mousewheel DOMMouseScroll', function(event) {
            event.preventDefault();
            var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail;
            init(event, delta);
        });

       });
       }
      }(jQuery));

2 个答案:

答案 0 :(得分:4)

这是因为settings.ScrollUp.call(this);这里this没有引用div的内部函数,因此this成为init内部函数内部的其他东西,试试这个: - < / p>

  return this.each( function() {
     var $this=this; // create variable here 
      .....
      .....
     settings.ScrollUp.call($this); //use it here like this  in init function

Demo

答案 1 :(得分:0)

看看这是否有帮助。

我使用jQuery .hover()来存储鼠标所在的div 然后只使用该变量(var hoverDiv)而不是&#34;这个&#34;

<style>
  body {background: #2A2B30;}
  .wrapper {margin-top: 100px;}
  .wrapper div.content {border-radius: 7px; border: 1px solid #000; min-height: 120px; margin-top: 30px; background: #ededed; padding: 30px; font-size: 20px;}
</style>
  <div class="container">
  <div class="wrapper clearfix">
    <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
      <div class="blk content"> </div>
    </div>
    <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
      <div class=" content"> </div>
    </div>
    <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
      <div class="blk content"> </div>
    </div>
    <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 content-wrapper">
      <div class=" content"> </div>
    </div>
  </div>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
/*
@see http://stackoverflow.com/questions/31340479/jquery-plugin-callback-this-cant-return-element
*/
(function($) {
  $.fn.scroll = function( options ) {
    var settings = $.extend({
      // selector     : $(this),
      lastAnimation  : null,
      quietPeriod    : null,
      animationTime  : null,
      ScrollUp     : null,
      ScrollDown     : null
    }, options);
    return this.each(function() {
      var lastAnimation = settings.lastAnimation;
      var quietPeriod = settings.quietPeriod;
      var animationTime = settings.animationTime;
      function init(event, delta) {
        deltaOfInterest = delta;
        var timeNow = new Date().getTime();
        if( timeNow - lastAnimation < quietPeriod + animationTime ) {
          event.preventDefault();
          return;
        }
        if ( deltaOfInterest < 0 ) {
          // Call Back
          if ( $.isFunction( settings.ScrollUp ) ) {
            settings.ScrollUp.call(this);
          }
        } else {
          // Call Back
          if ( $.isFunction( settings.ScrollDown ) ) {
            settings.ScrollDown.call(this);
          }
        }
        lastAnimation = timeNow;
      }
      $(this).bind('mousewheel DOMMouseScroll', function(event) {
        event.preventDefault();
        var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail;
        init(event, delta);
      });
    });
  }
}(jQuery));

$(function() {
  var hoverDiv = null;
  $('.blk').hover(function(e) {
      hoverDiv = $(this);
    }, 
    function(e) {
      hoverDiv = null;
    }
  );
  $('.blk').scroll({
    lastAnimation   : 0,
    quietPeriod   : 500,
    animationTime   : 800,
    ScrollUp : function() {
      if(hoverDiv) {
        hoverDiv.css('background', 'red');
      }
    },
    ScrollDown : function() {
      if(hoverDiv) {
        hoverDiv.css('background', 'blue');
      }
    }
  });
});
</script>