【问题标题】:jQuery animate scrolltop on Opera bugOpera 错误上的 jQuery 动画滚动顶部
【发布时间】:2011-06-20 07:49:57
【问题描述】:

有人用过吗

$(“html, body”).animate({scrollTop:0}, 'slow');

在 Opera 浏览器上?

它会产生一种奇怪的效果,尤其是当您在长页面上滚动时,似乎页面先到顶部,然后再向下滚动到正确的位置。这是一种奇怪的令人不安的效果......

有什么办法可以解决吗?谢谢

【问题讨论】:

  • @caamel 考虑创建一个演示(例如在 jsfiddle 中)
  • 不需要在窗口上应用scrollTop()吗?我认为这是正确的做法。

标签: javascript jquery dom opera


【解决方案1】:

过去没有正确定义该属性。我认为它是由 IE 引入的,然后进行逆向工程以由不同的用户代理实现。它已经在CSSOM 中进行了描述(仍然是一个工作草案)。到今天为止,Opera 中确实还有一个 bug,正在修复中。

## 可能的黑客攻击。

解决办法是

$(window.opera?'html':'html, body').animate({ 
  scrollTop:0}, 'slow' 
);

要小心,因为如果 Opera 在某个时间点修复它,代码可能会表现得很奇怪。

为什么?

  • 在 Firefox 和 IE quirks 模式下,您必须在“body”上设置该属性才能使页面滚动,而如果您在“html”上设置该属性,则会被忽略。
  • 在 Firefox 和 IE 标准模式下,您必须在“html”上设置该属性才能使页面滚动,而如果您在“body”上设置该属性,则会被忽略。
  • 在 Safari 和 Chrome 中,无论是哪种模式,您都必须在“body”上设置该属性以使页面滚动,而如果您在“html”上设置该属性,则会被忽略。

由于页面处于标准模式,他们必须在“html”和“body”上都设置它,否则它将无法在 Safari/Chrome 中运行。

现在是坏消息;在 Opera 中,当您读取正文的 scrollTop 时,它正确为 0,因为正文在文档中不可滚动。但如果您在“html”或“body”上设置滚动偏移量,Opera 将滚动视口。结果,动画设置了两个属性,一个用于“html”,一个用于“body”。第一个从正确的位置开始,而第二个从 0 开始,导致闪烁和奇怪的滚动位置。

不涉及用户代理嗅探的更好解决方案

来自http://w3fools.com/js/script.js

    // find out what the hell to scroll ( html or body )
    // its like we can already tell - spooky
    if ( $docEl.scrollTop() ) {
        $scrollable = $docEl;
    } else {
        var bodyST = $body.scrollTop();
        // if scrolling the body doesn't do anything
        if ( $body.scrollTop( bodyST + 1 ).scrollTop() == bodyST) {
            $scrollable = $docEl;
        } else {
            // we actually scrolled, so, er, undo it
            $body.scrollTop( bodyST - 1 );
        }
    }

【讨论】:

    【解决方案2】:

    这个http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html#opera 可能是一个更好的解决方案,无需使用任何 Opera 特定功能并考虑怪癖模式。

    【讨论】:

      【解决方案3】:
      $("body:not(:animated)").animate({ scrollTop: destination}, 500 );
      return false;
      

      为我工作,在歌剧中也是如此。

      编辑:虽然在 Firefox 中不起作用

      【讨论】:

        【解决方案4】:

        我也遇到过这个问题。这就是我使用的并且有效。这不是浏览器嗅探,但对我来说这不是特别好的代码。现在可以了。

        在 Opera 11 / IE 8 / FF 3.6 的 html 元素上调用 scrollTop 会返回一个大于零的数字

        在 Chrome 10 / Flock 3.5 / Safari 5(适用于 Windows)中的 html 元素上调用 scrollTop 返回 0

        所以只需测试一下:

        如果浏览器是 Opera,则在 scrollTop 上测试大于 0 的数字,然后仅在 html 上调用 scrollTop,一个 la

        var html = document.getElementsByTagName('html')[0];

        var body = document.getElementsByTagName('body')[0];

        $(html).animate({scrollTop:0+'px'},{'duration':1000,'easing':'swing'});

        如果浏览器是 Chrome、Flock 或 Safari,那么 scrollTop 将返回 0 并且您对此进行测试,并采取相应措施:

        $(html,body).animate({scrollTop:0+'px'},{'duration':1000,'easing':'swing'});

        因此,您将为标准模式 FF 和 IE 设置对 html 的效果(也应涵盖怪癖。呃),并为 Chrome 和 Safari 设置正文。

        在尝试滚动 html 和 body 的 Opera 中,从而导致大量怪异,scrollTop 返回一个大于 0 的数字,因此您只调用 html 并且您不会得到闪烁的废话。

        所以你可以在必要时安全地使用 html 和 body,或者当浏览器是 Opera 时只使用 html。

        并且不要忘记您的 preventDefault() ,否则您将不得不担心这将是另一个奇怪的闪烁。 ;)

        嘿,我不是 JS 忍者,但我很努力,这对我有用,而且我现在没有时间尽可能多地调查它,所以我想我会发布这个在这里和帮助。如果我错了,我会举起双手说出来。 ;) 所以请反馈。 :D

        汤姆。

        【讨论】:

          【解决方案5】:

          是的! 我在click() 函数中调用animate({scrollTop: }) 函数时遇到问题。

          最好的方法是http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html#opera,这里是Divya Manian写的。

          在开始滚动事件之前,需要在调用滚动函数或动画函数之前使用event.preventDefault()来结束点击事件。

          类似这样的:

          $(<clicked_element>).click(function(event){
              event.preventDefault();
              $('html, body').animate({scrollTop: <value>}, 600);
          });
          

          编辑:将滚动方法应用于$('html, body') 元素很重要

          【讨论】:

            猜你喜欢
            • 2012-08-01
            • 1970-01-01
            • 2011-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多