Javascript 调用Document.close后Document.links为空

Javascript 调用Document.close后Document.links为空,javascript,firefox,window.open,Javascript,Firefox,Window.open,当您使用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.getElem

当您使用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,说明文档未完全构建。是否有一种方法可以注册此reportLinks调用的onload事件,以便确保document.links已完成

顺便说一句,谷歌浏览器在这两种情况下都可以很好地使用这个例子

在回答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处理程序

非常感谢,,
马塞尔

正如我在评论中所说,这是一个非常奇怪的问题。但我认为这是因为包含外部脚本会导致新页面的页面呈现延迟,并且其DOM可能无法检查

添加新属性似乎可以解决此问题,这一事实支持了我的怀疑:

此布尔属性设置为向浏览器指示脚本将在解析文档后执行

可以在原始页面上设置“延迟”属性,因为您需要它的精确副本。如果脚本包含在何处并不重要(例如,在使用document.write时),则可以对其进行设置。在包含的文件中写入脚本与在何处包含脚本无关

因为defer是一个布尔属性,当它只是存在defer或使用XHTML时,将其设置为自身defer=defer。在您的情况下,脚本包含内容如下:

<script type="text/javascript" src="some.js" defer></script>
关于更新的更新:您仍然应该在主页中插入DOCTYPE,考虑使用.< /P> 而且我认为你附加你的onload事件的方式是你能做的最好的


但是考虑到你想要实现一个没有超链接的打印预览的目标:你也可以像文本一样使用打印和样式超链接;这比你正在做的事情要简单得多,当JavaScript被禁用时,它就可以工作。

我能使上述示例在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侦听器

谢谢,
Marcel

您真的应该包括一个触发的Doctype;在使用HTML时,您不必再这样做;脚本元素的语言属性非常奇怪;在函数调用reportLinksw.document.links上放置断点并单步执行代码时,一切正常;但是当我在reportLinks中放置断点时,我会得到一个空数组作为参数链接!我已经改写了这个例子。见后面的帖子。一个问题:我如何理解defer='true':这将在文档完全构建后执行脚本。那你把它放在哪里呢?它必须设置在弹出窗口的html中,并在您使用write函数传递的html中添加脚本作为字符串?其中,这非常类似于将对reportLinks的调用放入注册为弹出窗口的onload处理程序的函数中。但是如何才能为弹出窗口注册onload侦听器呢。再次感谢!我更新了我的答案。关于弹出窗口的onload事件:由于您只是创建一个新窗口,它有自己的DOM和onload事件。例如,如果它是在some.js中定义的,那么onload处理程序将在主窗口以及新创建的窗口上触发。谢谢 s、 现在我明白了:延迟包含的脚本。看看我的延伸问题。在那里你可以看到我对弹出窗口的onload的意思。