【问题标题】:What can make jQuery's unbind function not work as expected?是什么让 jQuery 的 unbind 功能无法按预期工作?
【发布时间】:2011-06-01 20:04:43
【问题描述】:

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

我希望这个脚本的行为是,每当我滚动页面时,红色行(<tr>alwaysVisible 的元素)应该插入到最顶部可见行(<tr> 元素)的下方那张桌子的。然后,页面应该滚动,以便这些红色行中的第一行“完全”出现在视口的顶部。实际发生的是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>

【问题讨论】:

    标签: jquery jquery-plugins scroll unbind


    【解决方案1】:

    我认为你的问题是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 回调清除标志,如下所示:

    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/

    【讨论】:

    • @mu 太短:我认为你对这个问题是正确的,但你的解决方案不起作用。我得到与以前完全相同的结果。现在我真的不明白..
    • @Shawn:我在 JavaScript 中有错字(右括号太多)。我修复了这个问题并添加了一个 jsfiddle 链接。
    • @mu 太短:所以它确实有效!这很奇怪,因为当我“本地”测试它时,完全相同的代码不起作用,但在 JSFiddle 中起作用。我想知道是什么可以解释我的“本地设置”(将代码保存在文本文件中并在 Firefox 中打开 html 文件)和 JSFiddle(也在 Firefox 中运行)之间的这种行为差异。我想这个问题值得自己提出一个问题.无论如何,感谢(工作)解决方案!
    • @Shawn:完全展开的小提琴版本是否有效?试试这个:fiddle.jshell.net/ambiguous/ZEx6M/1/show/light
    • @mu 太短:是的,效果很好(或者至少,它按预期工作!我确实认为最终结果有点不稳定,但那是另一个故事:p)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    相关资源
    最近更新 更多