调用 document.close 后 Document.links 为空
-
01-10-2019 - |
题
当您使用 Firefox 3 执行以下示例时:
<html>
<head>
<script language="javascript" type="text/javascript">
<!--
function openWindow(){
var w = window.open('', 'otherWin', 'width=600,height=600');
w.document.write(document.getElementsByTagName("html")[0].innerHTML);
w.document.close();
reportLinks(w.document.links);
}
function reportLinks(links){
var report = 'links: '+links.length;
for (var i=0;i<links.length;i++){
report += '\n (link='+links[i].href+')';
}
alert(report);
}
//-->
</script>
</head>
<body>
<p><a href="javascript: openWindow()">Open Same Content and Show Links Report</a></p>
<p><a href="javascript: reportLinks(document.links)">Show Links Report</a></p>
</body>
</html>
您将看到,单击“显示链接报告”和单击“打开相同内容并显示链接报告”时显示的链接数量均为 2。然而,当从此页面引用外部 JavaScript 文件时,行为似乎有所不同(如果需要,只需创建一个空文件 some.js )。单击“打开相同内容并显示链接报告”时,链接数量将为 0。
<html>
<head>
<script language="javascript" type="text/javascript" src="some.js"></script>
<script language="javascript" type="text/javascript">
<!--
function openWindow(){
var w = window.open('', 'otherWin', 'width=600,height=600');
w.document.write(document.getElementsByTagName("html")[0].innerHTML);
w.document.close();
reportLinks(w.document.links);
}
function reportLinks(links){
var report = 'links: '+links.length;
for (var i=0;i<links.length;i++){
report += '\n (link='+links[i].href+')';
}
alert(report);
}
//-->
</script>
</head>
<body>
<p><a href="javascript: openWindow()">Open Same Content and Show Links Report</a></p>
<p><a href="javascript: reportLinks(document.links)">Show Links Report</a></p>
</body>
</html>
这可能是加载页面和reportLinks 准确执行的时刻的问题。我假设添加了外部 some.js,该文档尚未完全构建。有没有办法可以为 onload 事件注册此 reportLinks 调用,以便我可以确定 document.links 是否完整?
顺便说一句,该示例在两种情况下都可以在 Google Chrome 中正常运行。
(在答案1之后添加)
正如 Marcel K. 所建议的那样我重写了示例,还按照我真正希望的方式添加了代码。现在对其进行测试,这个简单的示例似乎适用于 Firefox 和 Chrome。
<html>
<head>
<script type="text/javascript" src="some.js"></script>
<script type="text/javascript">
<!--
function openWindow(){
var w = window.open('', 'otherWin', 'width=600,height=600');
w.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n'+
document.getElementsByTagName("html")[0].innerHTML+'\n</html>');
w.onload=function(){
reportLinks(w.document.links);
};
w.document.close();
}
function reportLinks(links){
var report = 'links: '+links.length;
for (var i=0;i<links.length;i++){
report += '\n (link='+links[i].href+')';
}
alert(report);
}
//-->
</script>
</head>
<body>
<p><a href="javascript: openWindow()">Open Same Content and Show Links Report</a></p>
<p><a href="javascript: reportLinks(document.links)">Show Links Report</a></p>
</body>
</html>
我希望通过这个简单的示例来展示我正在编写的实际代码的简单情况。复杂 html 的打印预览屏幕,我想在打开后禁用所有 href。但在那一个中,onload 处理程序从未被调用......在这种情况下,如何以最可靠的方式注册 onload 处理程序?
非常感谢,马塞尔
解决方案 2
使上述示例在 Firefox、Chrome 和 IE 上可移植的唯一方法是通过弹出窗口中加载的 HTML 中的内联 JavaScript 注册 onload 侦听器。以下示例代码展示了如何操作。
<html>
<head>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<p><a href="javascript: openWindow()">Open Same Content and Show Links Report</a></p>
<p><a href="javascript: reportLinks(document.links)">Show Links Report</a></p>
</body>
</html>
此页面使用 script.js 文件中的脚本。下面显示了该文件的内容。
function openWindow(){
var w = window.open('', 'otherWin', 'width=600,height=600');
w.document.write(
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n'+
document.getElementsByTagName("html")[0].innerHTML+
'\n <script type="text/javascript">\n'+
' function addOnloadListener(listener){\n'+
' if (window.addEventListener) {\n'+
' window.addEventListener("load", listener, false);\n'+
' } else {\n'+
' window.attachEvent("onload",listener);\n'+
' }\n'+
' }\n'+
' addOnloadListener(function(){reportLinks(document.links);});\n'+
' </script>\n'+
'</html>');
w.document.close();
}
function reportLinks(links){
var report = 'links: '+links.length;
for (var i=0;i<links.length;i++){
report += '\n (link='+links[i].href+')';
}
alert(report);
}
当将函数 addOnloadListener 直接放入 JavaScript 文件中(不在页面中内联)时,它在 IE6 中不起作用,因为我相信它无法正确处理脚本条目的顺序。当 addOnloadListener 没有内联时,对 addOnloadListener 的内联调用不起作用,它根本找不到前面的函数:
<script type="text/javascript" src="script.js"></script>
该代码只是一个简单的示例,并没有真正做很多事情。我用它来禁用打印预览弹出页面中的所有链接。
始终欢迎一种更简单的方法来为可通过浏览器移植的弹出窗口注册 onload 侦听器。
谢谢,马塞尔
其他提示
正如我在评论中所说,这是一个非常奇怪的问题。但我认为发生这种情况是因为包含外部脚本会导致(新页面)页面渲染延迟,并且其 DOM 可能尚未准备好检查。
我的怀疑得到了以下事实的支持:添加(新的) defer
属性似乎可以解决这个问题:
设置此布尔属性是为了向浏览器指示要执行的脚本 解析文档后。
这 defer
属性可以在原始页面上设置,因为您想要它的精确副本。如果包含脚本的位置并不重要(例如,当使用 document.write
在你包含的文件中 做 无论您将其包含在哪个位置)。
作为 defer
是一个布尔属性, 它被激活 当它简单地存在时(defer
) 或(当使用 XHTML 时)设置为其自身 (defer="defer"
)。在您的情况下,脚本包含内容如下:
<script type="text/javascript" src="some.js" defer></script>
更新 关于您的更新:您仍然应该在主页中插入 Doctype(考虑使用 HTML 5 一).
我认为你的方式 onload
活动是你能做的最好的事情。
但考虑到您想要实现的目标(没有超链接的打印预览):您还可以使用“打印” media
属性 以及像文本一样设置超链接的样式;那是 方式 比你正在做的事情更容易,并且在禁用 JavaScript 时它可以工作。