Opera 错误上的 jQuery 动画滚动顶部
Posted
技术标签:
【中文标题】Opera 错误上的 jQuery 动画滚动顶部【英文标题】:jQuery animate scrolltop on Opera bug 【发布时间】:2011-06-20 07:49:57 【问题描述】:有人用过吗
$(“html, body”).animate(scrollTop:0, 'slow');
在 Opera 浏览器上?
它会产生一种奇怪的效果,尤其是当您在长页面上滚动时,似乎页面先到顶部,然后再向下滚动到正确的位置。这是一种奇怪的令人不安的效果......
有什么办法可以解决吗?谢谢
【问题讨论】:
@caamel 考虑创建一个演示(例如在 jsfiddle 中) 不需要在窗口上应用scrollTop()吗?我认为这是正确的做法。 【参考方案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')
元素很重要
【讨论】:
以上是关于Opera 错误上的 jQuery 动画滚动顶部的主要内容,如果未能解决你的问题,请参考以下文章
使用 jQuery 动画 scrollTop 总是从顶部开始