1

当您使用 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 是完整的?

顺便说一句,该示例在 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 处理程序?

非常感谢,马塞尔

4

2 回答 2

0

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

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

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

defer属性可以在原始页面上设置,因为您需要它的精确副本。如果包含脚本的位置无关紧要(例如,document.write在包含的文件中使用时,包含它位置很重要),您可以设置它。

作为defer一个布尔属性,当它只是存在()或(使用 XHTML 时)设置为自身时( ),它就会被激活。在您的情况下,脚本包含将显示为:deferdefer="defer"

<script type="text/javascript" src="some.js" defer></script>

关于您的更新的更新:您仍应在主页中插入一个 Doctype(考虑使用HTML 5 one)。

而且我认为您附加onload活动的方式是您能做的最好的。

但考虑到您想要实现的目标(没有超链接的打印预览):您也可以使用“打印”media属性和样式超链接,如文本;这比您正在做的事情要容易得多,并且在禁用 JavaScript 时它可以工作。

于 2010-08-28T17:05:56.057 回答
0

我可以使上面的示例在 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 侦听器。

谢谢,马塞尔

于 2010-09-06T22:43:40.073 回答