关于Opera bug的jQuery动画滚动顶部

时间:2011-02-02 22:37:21

标签: javascript jquery dom opera

有没有人尝试使用

$(“html, body”).animate({scrollTop:0}, 'slow');
在Opera浏览器上

它会产生一种奇怪的效果,特别是如果你在一个长页面上滚动,它似乎首先到达顶部,然后向下滚动到正确的点。这是一种奇怪的令人不安的影响......

有什么解决方法可以解决吗?感谢

5 个答案:

答案 0 :(得分:13)

过去没有正确定义属性。我认为它是由IE引入的,然后进行逆向工程以由不同的用户代理实现。自CSSOM(仍然是工作草案)中描述以来。截至今天,Opera确实存在一个错误,正在修复过程中。

##可能是黑客。

解决方案将是

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

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

为什么?

  • 在Firefox和IE怪癖模式下,您必须在“body”上设置属性以使页面滚动,而如果您在“html”上设置它则会被忽略。
  • 在Firefox和IE标准模式下,您必须在“html”上设置属性以使页面滚动,而如果将其设置在“body”上则忽略它。
  • 在Safari和Chrome中,在任一模式下,您必须在“正文”上设置属性以使页面滚动,而如果您在“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 );
        }
    }

答案 1 :(得分:5)

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

答案 2 :(得分:0)

$("body:not(:animated)").animate({ scrollTop: destination}, 500 );
return false;

对我来说也适用于歌剧。

编辑:虽然

在Firefox中不起作用

答案 3 :(得分:0)

我也遇到过这个问题。这是我使用的,它的工作原理。这不是浏览器嗅探,但对我而言,它并不是特别好的代码。它暂时适用。

在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的正文。

在Opera中,它试图滚动html和body,从而导致大规模的怪异,scrollTop返回一个大于0的数字,所以你只调用html而你没有得到闪烁的废话。

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

不要忘记你的防御默认()或那将是你将不得不担心的另一个奇怪的闪烁。 ;)

嘿,我不是JS忍者,但是我努力尝试这对我有用,我现在没时间按照我的意愿调查它,所以我想我会发布这个在这里和帮助。如果我错了,我会举起双手说出来。 ;)请反馈。 :d

汤姆。

答案 4 :(得分:0)

是的! 我对animate({scrollTop: })函数中调用的click()函数的操作有疑问。

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

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

这样的事情:

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

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