2014-11-16 5 views
8

У меня есть html-страница с некоторым предварительным визуализированным контентом и некоторым пока не обработанным контентом. Я хочу немедленно отобразить предварительно обработанный контент, а затем начать рендеринг остальной части контента. Я не использую jQuery.Выполнение javascript после завершения загрузки страницы

См. Следующий фрагмент. Я пробовал это различными способами, включая ввод моего сценария перед тегом закрывающего тега и предоставление моего сценария для заполнения DOM в качестве обратного вызова window.onload, document.body.onload и document.addEventListener('DOMContentLoaded'). В каждом случае страница не отображает предварительно обработанный контент до тех пор, пока остальная часть содержимого не будет отображаться.

<html><head></head> 
 
    <body> 
 
    <header>What it is, my doge?</header> 
 
    <div id="main"></div> 
 
    <script> 
 
     var main = document.getElementById('main'); 
 
     for (var i = 0; i < 500; i++) 
 
     main.innerText += new Date(); 
 
    </script> 
 
    </body> 
 
</html>

<html><head></head> 
 
    <body> 
 
    <header>What it is, my doge?</header> 
 
    <div id="main"></div> 
 
    <script> 
 
     var main = document.getElementById('main'); 
 
     document.body.onload = function() { 
 
     for (var i = 0; i < 500; i++) 
 
      main.innerText += new Date(); 
 
     }; 
 
    </script> 
 
    </body> 
 
</html>

<html><head></head> 
 
     <body> 
 
     <header>What it is, my doge?</header> 
 
     <div id="main"></div> 
 
     <script> 
 
      var main = document.getElementById('main'); 
 
      window.onload = function() { 
 
      for (var i = 0; i < 500; i++) 
 
       main.innerText += new Date(); 
 
      }; 
 
     </script> 
 
     </body> 
 
    </html>

<html><head></head> 
 
     <body> 
 
     <header>What it is, my doge?</header> 
 
     <div id="main"></div> 
 
     <script> 
 
      var main = document.getElementById('main'); 
 
      document.addEventListener('DOMContentLoaded', function() { 
 
      for (var i = 0; i < 500; i++) 
 
       main.innerText += new Date(); 
 
      }); 
 
     </script> 
 
     </body> 
 
    </html>

Один случай, который работал в window.setTimeout с 0 тайм-аут. Однако это просто отбрасывает функцию, пока нечего делать. Это лучшая практика, здесь?

<html><head></head> 
 
<body> 
 
    <header>What it is, my doge?</header> 
 
    <div id="main"></div> 
 
    <script> 
 
     var main = document.getElementById('main'); 
 
     window.setTimeout(function() { 
 
     for (var i = 0; i < 500; i++) 
 
      main.innerText += new Date(); 
 
     }, 0); 
 
    </script> 
 
</body> 
 
</html>

+1

1) нам нужен код здесь. 2) ваше описание не соответствует скрипке. 3) window.onload будет запускаться после загрузки всего содержимого. Все, что вам нужно сделать, это поместить ваш вызов до '' тега – mplungjan

+0

, скрипка - это как раз пример того, что вы описываете, и это явно не работает. –

+0

@MatthewJamesDavis Как отображается ваш незарегистрированный контент? –

ответ

10

С точки зрения лучшей практике Существует не один. Что касается good, общий, и приемлемый практики, есть несколько.Вы ударил одного:

setTimeout(function() { }, 1); 

В этом случае функция выполняется в the browser's minimum timeout period после всех остальных в-концов линии обработки.

Точно так же, если вы хотите, чтобы ваша функция работает вскоре после того, как некоторое условие истинно, используйте интервал:

var readyCheck = setInterval(function() { 
    if (readyCondition) { 
    /* do stuff */ 
    clearInterval(readyCheck); 
    } 
}, 1); 

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

var upon = function(test, fn) { 
    if (typeof(test) == 'function' && test()) { 
     fn(); 
    } else if (typeof(test) == 'string' && window[test]) { 
     fn(); 
    } else { 
     setTimeout(function() { upon(test, fn); }, 50); 
    } 
}; // upon() 

... и вызывать другие функции, когда зависимости разрешаются:

upon(function() { return MyNS.Thingy; }, function() { 
    // stuff that depends on MyNS.Thingy 
}); 

upon(function() { return document.readyState == 'complete';}, function() { 
    // stuff that depends on a fully rendered document 
}); 

Или если вы хотите более авторитетного хорошей практики , следуйте примеру Google. Создание внешнего async сценария и ввести его до первого заголовка script: решение

var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; 
s.src = '/path/to/script.js'; 
var header_scripts = document.getElementsByTagName('script')[0]; 
header_scripts.parentNode.insertBefore(s, header_scripts); 

Google, теоретически работает на всех браузерах, чтобы получить внешний скрипт, выполняющий как можно скорее, не мешая загрузке документа (IE < 10?).

Если вы хотите авторитетный общий практика, проверьте источник onready решения JQuery в.

+0

любая идея почему google предлагает вам предложить вам ввести его вместо того, чтобы включать его? –

+0

@MatthewJamesDavis [Две причины] (http://stackoverflow.com/questions/14815481/why-does-google-analytics-dynamically-inject-javascript-into-the-page), о которых я знаю.Здесь может показаться только один: некоторые браузеры не поддерживают атрибут 'async'. – svidgen

+0

@MatthewJamesDavis См. Поддержку браузера для 'async' здесь: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Browser_compatibility – svidgen

0

Я думаю, что вы хотите сделать, это использовать событие OnLoad на бирке. Этот путь сначала «Что это, мой дож?» появится сообщение, когда обрабатывается javascript.

Я также установил тайм-аут внутри цикла, чтобы вы могли лучше видеть добавляемые линии.

<html> 
    <head> 
     <script> 
      myFunction = function() { 
       for (var i = 1000; i > 0; i--) { 
        setTimeout(function() { 
         main.innerText += new Date(); 
        }, 100); 
       } 
      }; 
     </script> 
    </head> 

    <body onload="myFunction()"> 
     <header>What it is, my doge?</header> 
     <div id="main"></div> 
    </body> 
</html> 
+0

Цените ответ. Однако это не так оптимально, как идея, которую я опубликовал, установив один вызов window.setTimeout за пределами обратного вызова с таймаутом 0, что намного быстрее. –

4

В зависимости от ваших требований браузера вы можете использовать тег async и импортировать сценарий после загрузки содержимого. Вероятно, это делает то же самое, что и setTimeout(func, 0), но, возможно, это немного менее взломанно.

См http://plnkr.co/edit/7DlNWNHnyX5s6UE8AFiU?p=preview

HTML:

... 
<body> 
    <h1 id="main">Hello Plunker!</h1> 
    <script async src="script.js"></script> 
</body> 
... 

script.js:

for(var i=0; i<500; ++i) { 
    document.getElementById('main').innerText += new Date(); 
} 
+0

его намного менее взломанный. метод setTimeout говорит: «Эй, остановите все, когда вы загрузите этот скрипт, затем закончите делать все, что вы делаете, а затем выполните сценарий« где асинхронный говорит », закончить все, а затем выполнить скрипт всякий раз, когда он готов» –

1

Я использовал это, чтобы осуществить раньше:

var everythingLoaded = setInterval(function() { 
    if (/loaded|complete/.test(document.readyState)) { 
    clearInterval(everythingLoaded); 
    init(); // this is the function that gets called when everything is loaded 
    } 
}, 10); 
Смежные вопросы