什么可以使jQuery的unbind函数不能按预期工作?

时间:2011-06-01 20:04:44

标签: jquery jquery-plugins scroll unbind

请查看以下代码(此外,您还需要jquery.jsjquery.viewport.jsjquery.scrollTo.js)。

我希望这个脚本的行为是每当我滚动页面时,红色行(<tr>元素与类alwaysVisible)应插入最顶部可见行({{该表的{1}}元素。然后,应该滚动页面,以便这些红色行中的第一个“完全”出现在视口的顶部。实际发生的是重复调用<tr>,直到我到达页面末尾。我认为makeVisibleWhatMust();会让$(window).unbind('scroll');再次被调用,但显然这不起作用。

任何想法为什么?

这是我写的JavaScript:

makeVisibleWhatMust();

这是一个用于测试它的HTML页面:

function makeVisibleWhatMust()
{
  $('#testContainer').text( $('#testContainer').text() + 'called\n');
  $('table.scrollTable').each
  (
    function()
    {
      var table = this;
      $($('tr.alwaysVisible', table).get().reverse()).each
      (
    function()
    {
      $(this).insertAfter( $('tr:in-viewport:not(.alwaysVisible)', table)[0] );
    }
      );
      $(window).unbind('scroll');
      $(window).scrollTo( $('tr.alwaysVisible')[0] );
      $(window).bind('scroll', makeVisibleWhatMust);
    }
  );
}

$(document).ready
(
  function()
  {
    $(window).bind('scroll', makeVisibleWhatMust);
  }
);

1 个答案:

答案 0 :(得分:0)

我认为您的问题是scrollTo使用animate

// From the plugin's source
function animate( callback ){  
    $elem.animate( attr, duration, settings.easing, callback && function(){  
        callback.call(this, target, settings);  
    });  
};

animate使用计时器来执行动画。结果是.scrollTo将在滚动完成之前返回,并且您将在scrollTo仍在滚动时重新绑定滚动处理程序。因此,当你没有期待它们的事件。

一个简单的解决方案是使用一个标志来告诉makeVisibleWhatMust scrollTo正在滚动并使用scrollTo回调来清除标志,如下所示:< / p>

function makeVisibleWhatMust() {
  // Ignore the event if we're doing the scrolling.
  if(makeVisibleWhatMust.isScrolling)
    return;
  $('#testContainer').text( $('#testContainer').text() + 'called\n');
  $('table.scrollTable').each(function() {
      var table = this;
      $($('tr.alwaysVisible', table).get().reverse()).each(function() {
        $(this).insertAfter( $('tr:in-viewport:not(.alwaysVisible)', table)[0] );
      });
      makeVisibleWhatMust.isScrolling = true;
      $(window).scrollTo($('tr.alwaysVisible')[0], {
        onAfter: function() { makeVisibleWhatMust.isScrolling = false; }
      });
    }
  );
}
makeVisibleWhatMust.isScrolling = false;

这是一个似乎有用的实时版本:http://jsfiddle.net/ambiguous/ZEx6M/1/