Document.links пусто после вызова document.close - PullRequest
1 голос
/ 28 августа 2010

При выполнении следующего примера с использованием 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)

По предложению Марселя К. Я переписал пример, добавил код, так как я действительно хотел бы, чтобы дело пошло. А теперь тестируем его, и этот простой пример, похоже, работает с 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, в котором я хочу отключить все открытые ссылки после открытия. Но в этом случае обработчик загрузки никогда не вызывается ... Как я могу зарегистрировать обработчик загрузки в этом случае наиболее надежным способом?

Большое спасибо, Marcel

Ответы [ 2 ]

0 голосов
/ 07 сентября 2010

Единственный способ сделать приведенный выше пример переносимым через Firefox, Chrome и IE - это зарегистрировать слушателя загрузки через встроенный JavaScript в HTML-коде, загруженном во всплывающем окне. В следующем примере кода показано, как.

<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>

Код - всего лишь простой пример, который на самом деле мало что делает. Я использовал его для отключения всех ссылок на всплывающей странице предварительного просмотра.

Всегда приветствуется более простой способ регистрации прослушивателя загрузки для всплывающего окна, переносимого через браузер.

Спасибо, Marcel

0 голосов
/ 28 августа 2010

Как я сказал в комментарии, это очень странная проблема.Но я думаю, что это происходит потому, что включение внешнего скрипта вызывает задержку рендеринга страницы (новой страницы), и его DOM может быть не готов к проверке.

Мое подозрение подтверждается тем фактом, что добавление(новый) Атрибут defer, кажется, решает эту проблему:

Этот логический атрибут установлен, чтобы указывать браузеру, что сценарий должен быть выполнен последокумент был проанализирован.

Атрибут defer может быть установлен на исходной странице, если вы хотите получить его точную копию.Вы можете установить его, если не имеет значения, где находится скрипт (например, при использовании document.write во включенном файле он имеет значение , в каком месте вы его включаете).

Поскольку defer является логическим атрибутом, он активируется , когда он просто присутствует (defer) или (при использовании XHTML) установлен на себя (defer="defer").В вашем случае включение сценария будет выглядеть следующим образом:

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

Обновление относительно вашего обновления: вам все равно следует вставить Doctype на главной странице (рассмотрите возможность использования HTML 5 one ).

И я думаю, что способ, которым вы прикрепили свое onload событие, - лучшее, что вы можете сделать.

Но учитывая цель, которую вы хотите достичь (печатьпредварительный просмотр без гиперссылок): вы также можете использовать атрибут «print» media и стилизовать гиперссылки, например, текст;это способ проще, чем то, что вы делаете, и работает, когда JavaScript отключен.

...