【发布时间】:2013-01-04 13:17:32
【问题描述】:
对于我正在进行的项目,我遇到了一个奇怪的问题,我无法在这里(或其他任何地方)找到答案。
我尝试创建一个 Fiddle 来演示会发生什么,但由于我的脚本的性质以及 jsfiddle 的运行方式,它无法正常工作。无论如何,here's a link to the Fiddle 所以至少你会有代码。
我想要发生的事情
对三个可能的 window 事件执行单个处理程序 (onViewportChange):resize、orientationchange 和 scroll。根据事件类型,处理程序将确定要做什么。听起来很简单。
我做了什么
对于本例,我已将处理程序限制为回显事件类型,以进行测试:
var onViewportChange = function(e) {
alert(e.type);
};
我将处理程序绑定到事件:(我还尝试了 .bind() 与事件数组和几个单独的绑定)
$(window).on({
'orientationchange resize scroll' : function(e){
onViewportChange(e);
}
});
HTML 完全是空的,除了任意基本元素(doctype、html、body 以及当然 jquery 和这个脚本)
实际发生的情况
现在变得奇怪了:这些事件在桌面浏览器上触发得很好(主要是因为没有触发orientationchange 事件),但在移动设备上却没有(在iOS6+ iPad 第三代和iOS6+ iPhone 5 上测试)。当我旋转我的设备时;
- iPad 和 iPhone 三个都开火了:
orientationchange、resize,然后是scroll - iPhone 上的 Chrome 会触发
resize,然后是orientationchange - 我借的一部安卓手机触发
orientationchange,后跟resize
(请注意,由于竞态条件,事件的顺序可能不准确。)
这就是我将它链接到orientationchange 事件的原因:当我删除orientationchange 事件(留下resize 和scroll)时,只有scroll 事件在设备旋转时触发,但没有更长的resize 事件。
我不明白为什么所有事件都会同时触发。至少;我可以想象在orientationchange 上触发了resize,因为窗口尺寸发生了变化,但是scroll?
有人知道为什么会这样吗?
编辑我在这里设置了一个演示:http://beta.hnldesign.nl/orientation/index.html
【问题讨论】:
-
显然,当
window.scrollTop和window.scrollLeft值在内部重新构造/重新评估时,Mobile Safari 会触发resize事件。您可以使用标志来避免触发scroll事件作为解决方法。 -
我想
scroll事件被触发是因为 Safari 尝试将用户滚动到他们在页面上的位置更改之前的位置... -
谢谢 inhan,但我将如何区分重新评估“滚动”和实际用户“滚动”?
-
您能否在
orientationchange上设置一个标志(重置标志的超时时间很短)并检查何时调用scroll事件?或者你不能保证orientationchange总是在scroll之前被调用? -
恐怕我不能保证。问题是由于竞争条件,orientationchange 和 scroll 事件发生冲突;谁先开火,谁就得到蛋糕。麻烦了,这个
标签: jquery mobile orientation mobile-safari