jquery - 什么会导致 jQuery 的 unbind 功能无法按预期工作?

标签 jquery jquery-plugins scroll unbind

看看下面的代码(此外,您将需要 jquery.jsjquery.viewport.jsjquery.scrollTo.js )。

我期望此脚本的行为是,每当我滚动页面时,红色行( <tr> 具有类 alwaysVisible 的元素)应插入到最顶部可见行( <tr> 元素)的正下方那张 table 的。然后,应该滚动页面,以便这些红色行中的第一行“恰好”出现在视口(viewport)的顶部。实际发生的情况是makeVisibleWhatMust();被重复调用,直到我到达页面末尾。我以为$(window).unbind('scroll');会保留makeVisibleWhatMust();以免再次被调用,但显然这不起作用。

有什么想法吗?

这是我编写的 JavaScript:

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

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Scroll Tables Test Page</title>

    <script type="text/javascript" src="jQuery.js"></script>
    <script type="text/javascript" src="jquery.viewport.js"></script>
    <script type="text/javascript" src="jquery.scrollTo.js"></script>
    <script type="text/javascript" src="scrollTable.js"></script>

    <style type="text/css">
      table th, table td
      {
    border: 1px solid #000;
    padding: .3em;
      }
      .alwaysVisible
      {
    background: #F66;
      }
    </style>
  </head>
  <body>
    <table class="scrollTable">
      <thead>
    <tr class="alwaysVisible">
      <th>Row name</th>
      <th>Content</th>
    </tr>
    <tr class="alwaysVisible">
      <th>Row 2</th>
      <th>Row 2</th>
    </tr>
      </thead>
      <tbody>
    <script type="text/javascript">
      for(var i = 0; i < 50; ++i)
      {
        document.writeln("<tr><td>Row " + i + "</td><td>Content</td></tr>");
      }
    </script>
      </tbody>
      <tfoot>
    <tr>
      <td>Footer</td>
      <td>Footer 2</td>
    </tr>
      </tfoot>
    </table>
    <div id="testContainer">TEST CONTAINER</div>
  </body>
</html>

最佳答案

我认为你的问题是 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 仍在滚动时重新绑定(bind)滚动处理程序。因此,就会发生您意想不到的事件。

一个简单的解决方案是使用一个标志来告诉 makeVisibleWhatMust scrollTo 正在滚动,并在以下情况下使用 scrollTo 回调来清除该标志:完成了,像这样:

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/

关于jquery - 什么会导致 jQuery 的 unbind 功能无法按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6206985/

相关文章:

javascript - 无需打开即可打印 pdf

javascript - 动画一个 - 停止另一个 |查询

javascript - Angularjs 和 Jquery datepicker 数据绑定(bind)

javascript - 我如何水平滚动到页面中的下一篇文章(或 # 等)?

react-native - KeyboardAvoidingView、SafeAreaView 和 ScrollView 的最佳顺序

javascript - 第一行 Id 值适用于 JSON 对象中的所有行 Id

javascript - 图像选择器jquery插件:How to get img-src of selected images(multiple selection case)

jquery - BxSlider如何在没有动画的情况下移动到下一张幻灯片?

javascript - 使 Jquery.ScrollTo 根据速度而不是持续时间工作

jquery - 如何在页面加载时启动 jQuery Fancybox?