一个 JavaScript 问题。
有谁知道为什么在某些浏览器中页面加载时会调用
window.onresize
?
这可以避免吗?
我在 IE、Android 手机版 Firefox 27(在 Samsung Galaxy S3 上测试)、Google Nexus 7(在 Browserstack 上测试)和 Windows Phone 8(Internet Explorer)中发现了问题。
我的测试页面如下所示:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<script type="text/javascript">
window.onresize = resize;
function resize(){
alert("resize event detected!");
}
</script>
</head>
<body>
</body>
</html>
解决方案:
var windowWidth = $(window).width();
window.onresize = resize;
function resize(){
if($(window).width()!=windowWidth){
alert("Bingo");
windowWidth = $(window).width();
}
}
据我所知,
window.onresize
默认情况下不会在页面加载时被调用在桌面浏览器上
我写了一个简单的html页面如下(很多
H1
让页面有一些内容):
<!DOCTYPE html>
<html>
<head>
<script>
var i = 0;
window.onresize = function() {
i++;
}
window.setTimeout(function() {
alert("resize called " + i + " times");
}, 2000);
</script>
</head>
<body>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
</body>
</html>
警报在以下浏览器中显示 0:
我发现您的问题似乎出在移动设备上。
onresize
可能会在页面加载时触发,因为在移动浏览器加载内容并弄清楚如何将页面缩放到屏幕尺寸后,“视觉视口” 会调整大小。
请参阅此处了解移动视口的说明:
http://www.quirksmode.org/mobile/viewports2.html
请参阅此处的表格,了解几种移动浏览器如何处理视觉视口的
onresize
事件:
http://www.quirksmode.org/dom/events/resize_mobile.html
如果是这种情况,那么我想你可能会很难与之抗争。
onresize
为了避免首次运行
onresize
的事件处理程序,您可以简单地设置一个标志,如下所示:
var initial = true;
$(window).on('resize',function(){
if(!initial)
{
// do your stuff here
}else
{
// don't do your stuff here
}
initial = false;
});
但是,正如您在评论中所说,如果
onresize
按预期工作(并且不在页面加载时运行),则这将不起作用。它假设第一次运行将在页面加载时运行。
我在 Android 版 Chrome 36 上遇到了同样的问题。当我没有预料到会发生这种情况时,在第一页加载时的某个时刻触发了调整大小事件(它会在页面渲染时导致一些轻微的视觉故障)。经过调查,我尝试删除 JavaScript 中在 document.ready 事件触发后动态附加 meta name="viewport" 标记信息的部分(我使用了 jQuery),并且不再触发 resize 事件。
一种解释可能是,在页面已经开始渲染后附加视口信息将导致触发调整大小事件(这确实有意义)。
当然,这只发生在确实考虑了元名称=“viewport”标签信息的浏览器,即主要是移动浏览器(我没有在 8.1 上测试过 IE11,但考虑到它是一个混合操作系统,它可能会考虑元名称="viewport"标签信息)。
我遇到的问题是,有时加载页面后会触发多个调整大小事件。为了确保只考虑真正的调整大小事件,我使用计时器在页面加载后的前 500 毫秒内忽略该事件。这样,它就可以在所有浏览器中工作,无论它们在加载后是否触发一个或多个调整大小事件。
var realResize = false;
setTimeout(function() {
realResize = true;
}, 500);
window.onresize = function() {
if (realResize) {
// do something
}
};
这是一篇很旧的帖子,但它帮助我解决了类似的问题
事实上,2023 年的一些移动设备会在加载过程中引发
resize
事件,更重要的是在 // 处理过程中(Brave 和 Safari,但不是 Chrome 或 Firefox!!)
当尝试识别要显示的组件以响应窗口宽度时,这会导致问题。
经过调查,我通过仅在页面完全加载后在
resize
上注册事件句柄解决了问题
使用 vue js 的代码示例,将此代码放置在路由器中
window.addEventListener("load", () => {
window.addEventListener("resize", () => {
// get the current route
const route = router.currentRoute.value;
console.log("router resize triggered on route", route.fullPath);
// force the router to reevaluate the path according to size
router.push({path: route.path, query: route.query, hash: route.hash, force: true});
});
});
function isMobile(): boolean {
return window.innerWidth < 768;
}
// The router guard to force any route to be
// --> /mobile/xxx or ---> /desktop/xxx
router.beforeEach((to, from, next) => {
// here test if the window size is small enough to be considered as a mobile
let path = to.fullPath;
path = path.replace(/\/(desktop|mobile)\//, "/");
if (isMobile() && !to.fullPath.startsWith("/mobile/")) {
return next({
path: `/mobile${path}`,
// params: to.params,
query: to.query,
hash: to.hash,
});
}
if (!isMobile() && !to.fullPath.startsWith("/desktop/")) {
return next({
path: `/desktop${path}`,
// params: to.params,
query: to.query,
hash: to.hash,
});
}
return next();
});