Opera bug 上的 jQuery 动画滚动顶部

发布于 2024-10-16 00:48:13 字数 213 浏览 7 评论 0原文

有人尝试过

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

在 Opera 浏览器上使用吗?

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

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

Has anyone tried using

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

on Opera browser?

It does a weird effect especially if you scroll on a long page, it seems like the page go first to the top and then it scroll down to the right point. It is a weird disturbing effect...

Is there any workaround to fix it? thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

憧憬巴黎街头的黎明 2024-10-23 00:48:13

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

## 可能的 hack。

解决方案要

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

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

为什么?

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

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

现在有一个坏消息;在 Opera 中,当您读取body 它正确地为 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 );
        }
    }

The attribute was not defined properly in the past. It was introduced by IE, I think, then reverse engineered to be implemented by different user agents. It has been since described in CSSOM (still a working draft). As of today, there is still a bug indeed in Opera which is being in the process to be fixed.

## Possible hack.

A solution will be

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

Be careful because if Opera fixes it at a point, the code is likely to behave strangely.

Why?

  • In Firefox and IE quirks mode, you have to set the property on the "body" to make the page scroll, while it is ignored if you set it on the "html".
  • In Firefox and IE standards mode, you have to set the property on the "html" to make the page scroll, while it is ignored if you set it on the "body".
  • In Safari and Chrome, in either mode, you have to set the property on the "body" to make the page scroll, while it is ignored if you set it on the "html".

Since the page is in standards mode, they have to set it on both the "html" and "body, or it won't work in Safari/Chrome.

Now here's the bad news; in Opera, when you read the scrollTop of the body it is correctly 0, since the body is not scrollable within the document. But Opera will scroll the viewport if you set the scrolling offset on either the "html" or "body". As a result, the animation sets two properties, once for the "html" and once for the "body". The first starts at the right place, while the second starts at 0, causing the flicker and odd scroll position.

Better solution not involving user agent sniffing

From 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 );
        }
    }
著墨染雨君画夕 2024-10-23 00:48:13

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

This http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html#opera might be a better solution without using any Opera specific functions and accounting for quirks mode.

农村范ル 2024-10-23 00:48:13
$("body:not(:animated)").animate({ scrollTop: destination}, 500 );
return false;

对我来说很有效,在歌剧中也是如此。

编辑:但在 Firefox 中不起作用

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

works for me, in opera as well.

EDIT: does not work in firefox though

不气馁 2024-10-23 00:48:13

我也遇到过这个问题。这就是我使用的并且有效。这不是浏览器嗅探,但对我来说这不是特别好的代码。目前它还有效。

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

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

所以只需测试一下:

如果浏览器是 Opera ,您在scrollTop上测试大于0的数字,并仅在html上调用scrollTop,如

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。

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

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

汤姆。

I've had this problem, too. This is what I use and it works. It's not browser sniffing, but it's not particularly nice code, to me. It works tho, for now.

Calling scrollTop on html element in Opera 11 / IE 8 / FF 3.6 returns a number larger than zero

Calling scrollTop on html element in Chrome 10 / Flock 3.5 / Safari 5 (for Windows) returns 0

So just test that:

If the browser is Opera, you test for a number larger than 0 on scrollTop, and call scrollTop on only html, a la

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

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

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

If the browser is Chrome, or Flock or Safari than scrollTop will return 0 and you test for that, acting accordingly:

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

So, you'll set the effect on html for standards mode FF and IE (quirks should be covered, too. Ugh), and body for Chrome and Safari.

In Opera, which attempts to scroll both html and body, thus leading to mass freakishness, scrollTop returns a number greater than 0, so you call only html and you don't get the flickery nonsense.

So you can safely use both html and body when necessary, or just html when the browser is Opera.

And don't forget yer preventDefault() or that'll be another weird flicker you'll have to worry about. ;)

Hey, I'm no JS ninja, but I try hard and this works for me, and I don't have time right now to investigate it as much as I'd like, so I thought I'd post this here and help. If I'm wrong I'll hold up my hands and say it. ;) So feedback, please. :D

Tom.

执妄 2024-10-23 00:48:13

是的!
我在 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')元素非常重要

Yep!
I had a problem with action of animate({scrollTop: }) function called in click() function.

The best way is http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html#opera, which was written here by Divya Manian.

One need to use event.preventDefault() before calling scroll function or animate function to end click event before start scroll event.

Something like this:

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

EDIT: It's important to apply scroll method to $('html, body') elements

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文