Android 的 Firefox onload 事件期间 window.innerWidth 的值错误?
Wrong value for window.innerWidth during onload event in Firefox for Android?
好的,所以,我面临的问题是:我的移动 Firefox 浏览器没有检索 window.innerWidth
、document.documentElement.clientWidth
甚至 [=15= 的宽度的正确值] 样式在页面加载后占据整个客户端 window。
我没疯,我的代码在所有其他浏览器中都运行良好!出于某种原因,Firefox 使用默认值初始化这些值,然后稍后获取正确的值。如果在任何时候我用 alert()
打断了我的 JavaScript,这些属性随后会神奇地变得准确。
我在互联网上搜索了一个答案,我所能找到的只是一个 hack 解决方法:使用 window.setTimeout
延迟这些属性的使用,直到它们有时间正确填充。这很疯狂!用户想要速度,而不是为了在 Firefox 浏览器上查看我的网站而额外延迟。
我不明白的是,我可以设置一个 div
来在值变得准确之前完美地填充客户端 window。我在 css 中通过将 div 的 id 的宽度和高度设置为 100% 来执行此操作。 document.documentElement
与 document.getElementById("my_div");
在所有文档元素加载后基本相同,因此,当浏览器没有正确的尺寸时,浏览器如何知道 div
应该有多大客户 window 第一?
我已经尝试 运行 我的代码在 window.addEventListener("load",function(event_){ //My Code });
中,但仍然不会生成这些值。 window.onload
之后是否有页面加载事件?
如果有人能告诉我为什么只有 Firefox 移动版似乎显示出这种奇怪的行为,我会给你五分好评。
这里有一些用于重现问题的示例代码:
<!DOCTYPE HTML>
<html>
<head>
<!-- Added " after javascript during edit. -->
<script type="text/javascript">
window.addEventListener("load",function(event_){
var output=document.getElementById("output");
/* Returns some default value like 980. */
output.innerHTML=window.innerWidth;
alert("After this alert, the value will change.");
/* Returns an accurate value like 511. */
output.innerHTML=window.innerWidth;
});
</script>
<!-- Added title during edit. -->
<title>Title</title>
</head>
<body>
<p id="output">Default Output</p>
</body>
</html>
我的 Firefox android 版本是 35.0.1。我的 Android 版本是 4.4.4。在我的设备上,Firefox 在输出 p 元素中显示“980”,显示警报,然后再次显示“980”。页面刷新后,前两个步骤保持不变,但警报后的输出变为 360。document.documentElement.clientWidth
也会出现这种情况。我尝试的任何属性似乎都无法获得正确的值。似乎 Firefox 在页面加载后在访问客户端 window 的维度之前有某种延迟...
我在没有JQuery的情况下尝试了verge.airve.com插件,它的初始反馈仍然是980。它在Chrome上也初始化为980,这很奇怪,因为Chrome没有它按预期工作......
经过多次争论,找到了解决方案! Firefox 显然会在加载后调整 window 的大小(我想这是很好的衡量标准,谁知道呢)!因此,除了 window.onload 之外,还可以通过添加一个调整大小事件处理程序来避免这个问题!有关详细信息,请参阅下面接受的答案。
确保在加载整个文档并调整大小时完成测量。
window.onload = showViewport;
window.onresize = showViewport;
function showViewport() {
var output=document.getElementById("output");
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var height= Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
output.innerHTML = "Viewport size is " + width + "x" + height;
}
<body>
<p id="output">Default Output</p>
</body>
我可以确认这个问题,例如在 Android 4.1.2 上的 Firefox 38.0.1 中。创建了一个 js bin 用于测试目的。
我想检查 window.innerWidth 在不同分辨率(手机、平板电脑和台式机尺寸)上的自定义 DOM 操作,因此获得正确的 window.innerWidth 值已经处于 document.ready() 状态,而不仅仅是 window.load().
$('#inline').html($(window).width());
$(document).ready(function() {
$('#ready').html(window.innerWidth);
});
$(window).load(function() {
$('#load').html(window.innerWidth);
});
setTimeout(function() {
$('#setTimeout').html(window.innerWidth);
}, 1000);
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JS Bin</title>
</head>
<body>
<p><span id="inline"></span></p>
<p>$(document).ready(): <span id="ready"></span></p>
<p>$(window).load(): <span id="load"></span></p>
<p>setTimeout(1000): <span id="setTimeout"></span></p>
</body>
</html>
(我只想添加评论,而不是回答,但还没有这样做的声誉:-)
Firefox 40.0 在 Android 4.4.4 下的问题 (innerWidth === 980) 仍然存在。 1 毫秒的等待是一种规避。将
window.onload = myProgram;
替换为
window.onload = function() {setTimeout(myProgram, 1)};
同时,我在将一个相当精致的网站适配到小屏幕时遇到了这个问题。 Firefox 遵守“@media only screen and (max-width: 768px)”之后的 CSS。然而,当人们试图根据设备宽度设置事件处理程序时,Firefox 会惨遭失败。我需要在所有拾取设备宽度的位置等待 0.5 秒的上述技巧。这个等待时间对于 Nexus 7 (2012) 是必要的,但谁知道其他设备需要什么?
我在 CodeNameOne
和 Android
中使用 BrowserComponent
时遇到了同样的问题
我的解决方案是将 js 放在函数中,就像这样
function runScripts()
{
//get width here
}
并监听 BrowserComponent
的 onLoad
事件以在浏览器完全加载后执行此脚本
像这样:
BrowserComponent browser = new BrowserComponent();
browser.addWebEventListener("onLoad", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
browser.execute("runScripts()");
}
});
browser.setURL("http://www.URL.com");
在 html 中处理 window.onload
不足以等待提供适当的宽度
除此解决方案外,我还发现 window.setTimeout(runScripts, 500);
可以以浪费半秒为代价获得正确的文档宽度
window.setTimeout(yourFunction, 1);
这对我来说很有效,1 毫秒就足够了。
我发现一个非常 hack 的解决方案是在 header 中调用一个假的 link。我的猜测是时间延迟允许在脚本执行之前更新 window.innerWidth 和 window.innerHeight。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/fake.css"/>
我遇到了同样的问题,在使用 Firefox 的 android 设备上获取 window.innerWidth 时宽度变了。我尝试了上面的一些建议,但没有成功 - 可能以错误的方式实施示例?
但是,通过使用下面的代码,据我测试,我得到的系统似乎 100% 正常工作。它也几乎没有延迟,因为它一旦获得稳定的结果就会打破循环。
var canvasWidth = 0;
var canvasHeight = 0;
var previousWidth = -1;
var previousHeight = -1;
while ((canvasWidth != previousWidth) || (canvasHeight != previousHeight))
{
previousWidth = canvasWidth;
previousHeight = canvasHeight;
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
}
好的,所以,我面临的问题是:我的移动 Firefox 浏览器没有检索 window.innerWidth
、document.documentElement.clientWidth
甚至 [=15= 的宽度的正确值] 样式在页面加载后占据整个客户端 window。
我没疯,我的代码在所有其他浏览器中都运行良好!出于某种原因,Firefox 使用默认值初始化这些值,然后稍后获取正确的值。如果在任何时候我用 alert()
打断了我的 JavaScript,这些属性随后会神奇地变得准确。
我在互联网上搜索了一个答案,我所能找到的只是一个 hack 解决方法:使用 window.setTimeout
延迟这些属性的使用,直到它们有时间正确填充。这很疯狂!用户想要速度,而不是为了在 Firefox 浏览器上查看我的网站而额外延迟。
我不明白的是,我可以设置一个 div
来在值变得准确之前完美地填充客户端 window。我在 css 中通过将 div 的 id 的宽度和高度设置为 100% 来执行此操作。 document.documentElement
与 document.getElementById("my_div");
在所有文档元素加载后基本相同,因此,当浏览器没有正确的尺寸时,浏览器如何知道 div
应该有多大客户 window 第一?
我已经尝试 运行 我的代码在 window.addEventListener("load",function(event_){ //My Code });
中,但仍然不会生成这些值。 window.onload
之后是否有页面加载事件?
如果有人能告诉我为什么只有 Firefox 移动版似乎显示出这种奇怪的行为,我会给你五分好评。
这里有一些用于重现问题的示例代码:
<!DOCTYPE HTML>
<html>
<head>
<!-- Added " after javascript during edit. -->
<script type="text/javascript">
window.addEventListener("load",function(event_){
var output=document.getElementById("output");
/* Returns some default value like 980. */
output.innerHTML=window.innerWidth;
alert("After this alert, the value will change.");
/* Returns an accurate value like 511. */
output.innerHTML=window.innerWidth;
});
</script>
<!-- Added title during edit. -->
<title>Title</title>
</head>
<body>
<p id="output">Default Output</p>
</body>
</html>
我的 Firefox android 版本是 35.0.1。我的 Android 版本是 4.4.4。在我的设备上,Firefox 在输出 p 元素中显示“980”,显示警报,然后再次显示“980”。页面刷新后,前两个步骤保持不变,但警报后的输出变为 360。document.documentElement.clientWidth
也会出现这种情况。我尝试的任何属性似乎都无法获得正确的值。似乎 Firefox 在页面加载后在访问客户端 window 的维度之前有某种延迟...
我在没有JQuery的情况下尝试了verge.airve.com插件,它的初始反馈仍然是980。它在Chrome上也初始化为980,这很奇怪,因为Chrome没有它按预期工作......
经过多次争论,找到了解决方案! Firefox 显然会在加载后调整 window 的大小(我想这是很好的衡量标准,谁知道呢)!因此,除了 window.onload 之外,还可以通过添加一个调整大小事件处理程序来避免这个问题!有关详细信息,请参阅下面接受的答案。
确保在加载整个文档并调整大小时完成测量。
window.onload = showViewport;
window.onresize = showViewport;
function showViewport() {
var output=document.getElementById("output");
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var height= Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
output.innerHTML = "Viewport size is " + width + "x" + height;
}
<body>
<p id="output">Default Output</p>
</body>
我可以确认这个问题,例如在 Android 4.1.2 上的 Firefox 38.0.1 中。创建了一个 js bin 用于测试目的。
我想检查 window.innerWidth 在不同分辨率(手机、平板电脑和台式机尺寸)上的自定义 DOM 操作,因此获得正确的 window.innerWidth 值已经处于 document.ready() 状态,而不仅仅是 window.load().
$('#inline').html($(window).width());
$(document).ready(function() {
$('#ready').html(window.innerWidth);
});
$(window).load(function() {
$('#load').html(window.innerWidth);
});
setTimeout(function() {
$('#setTimeout').html(window.innerWidth);
}, 1000);
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JS Bin</title>
</head>
<body>
<p><span id="inline"></span></p>
<p>$(document).ready(): <span id="ready"></span></p>
<p>$(window).load(): <span id="load"></span></p>
<p>setTimeout(1000): <span id="setTimeout"></span></p>
</body>
</html>
(我只想添加评论,而不是回答,但还没有这样做的声誉:-)
Firefox 40.0 在 Android 4.4.4 下的问题 (innerWidth === 980) 仍然存在。 1 毫秒的等待是一种规避。将
window.onload = myProgram;替换为
window.onload = function() {setTimeout(myProgram, 1)};
同时,我在将一个相当精致的网站适配到小屏幕时遇到了这个问题。 Firefox 遵守“@media only screen and (max-width: 768px)”之后的 CSS。然而,当人们试图根据设备宽度设置事件处理程序时,Firefox 会惨遭失败。我需要在所有拾取设备宽度的位置等待 0.5 秒的上述技巧。这个等待时间对于 Nexus 7 (2012) 是必要的,但谁知道其他设备需要什么?
我在 CodeNameOne
和 Android
BrowserComponent
时遇到了同样的问题
我的解决方案是将 js 放在函数中,就像这样
function runScripts()
{
//get width here
}
并监听 BrowserComponent
的 onLoad
事件以在浏览器完全加载后执行此脚本
像这样:
BrowserComponent browser = new BrowserComponent();
browser.addWebEventListener("onLoad", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
browser.execute("runScripts()");
}
});
browser.setURL("http://www.URL.com");
在 html 中处理 window.onload
不足以等待提供适当的宽度
除此解决方案外,我还发现 window.setTimeout(runScripts, 500);
可以以浪费半秒为代价获得正确的文档宽度
window.setTimeout(yourFunction, 1);
这对我来说很有效,1 毫秒就足够了。
我发现一个非常 hack 的解决方案是在 header 中调用一个假的 link。我的猜测是时间延迟允许在脚本执行之前更新 window.innerWidth 和 window.innerHeight。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/fake.css"/>
我遇到了同样的问题,在使用 Firefox 的 android 设备上获取 window.innerWidth 时宽度变了。我尝试了上面的一些建议,但没有成功 - 可能以错误的方式实施示例?
但是,通过使用下面的代码,据我测试,我得到的系统似乎 100% 正常工作。它也几乎没有延迟,因为它一旦获得稳定的结果就会打破循环。
var canvasWidth = 0;
var canvasHeight = 0;
var previousWidth = -1;
var previousHeight = -1;
while ((canvasWidth != previousWidth) || (canvasHeight != previousHeight))
{
previousWidth = canvasWidth;
previousHeight = canvasHeight;
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
}