Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   DOMContentLoaded (https://javascript.ru/forum/events/29819-domcontentloaded.html)

cyber 12.07.2012 17:47

DOMContentLoaded
 
щас разбираюсь с событием DOMContentLoaded по этой статье http://javascript.ru/tutorial/events/ondomcontentloaded , и возникло пару вопросов, вот сам скрипт

function bindReady(handler){

	var called = false

	function ready() { // (1)
		if (called) return
		called = true
		handler()
	}

	if ( document.addEventListener ) { // (2)
		document.addEventListener( "DOMContentLoaded", function(){
			ready()
		}, false )
	} else if ( document.attachEvent ) {  // (3)

		// (3.1)
		if ( document.documentElement.doScroll && window == window.top ) {
			function tryScroll(){
				if (called) return
				if (!document.body) return
				try {
					document.documentElement.doScroll("left")
					ready()
				} catch(e) {
					setTimeout(tryScroll, 0)
				}
			}
			tryScroll()
		}

		// (3.2)
		document.attachEvent("onreadystatechange", function(){

			if ( document.readyState === "complete" ) {
				ready()
			}
		})
	}

	// (4)
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    /*  else  // (4.1)
        window.onload=ready
	*/
}

не пойму почему в старых ИЕ он срабатывает после полной загрузки страницы, как я понял функция tryScroll , должна срабатывает до загрузки картинок?
Почему для браузеров которые не поддерживают DOMContentLoaded , сделать добавление
document.body.appendChild()
, если боди еще не загрузился то откладывать повторную попытку timeout?
Помогите разобратся.

cyber 13.07.2012 13:28

неужели такой сложный вопрос?

melky 13.07.2012 18:26

Цитата:

Сообщение от cyber
Почему для браузеров <...> сделать добавление, и если боди еще не загрузился, то откладывать повторную попытку timeout?

в первый раз это увидел. отсебятина?

Цитата:

Сообщение от cyber
не пойму почему в старых ИЕ он срабатывает после полной загрузки страницы, как я понял функция tryScroll , должна срабатывает до загрузки картинок?

а что, если так же, по нулевому таймауту, проверять document.body.innerHTML, или что-то в этом роде?

cyber 13.07.2012 20:14

Цитата:

Сообщение от melky (Сообщение 188566)
в первый раз это увидел. отсебятина?

угу=)
вот что получилось
<!DOCTYPE HTML>
<html>
  <head>
    <script>
    
    
		var scr = document.createElement('script');
		   scr.type = 'text/javascript';
		   scr.innerHTML = 'handler()';
			  scr.id = 'DomLoadedScript';
		
			(function body_end(){
				
				try {
					
					document.body.appendChild(scr);
					} catch(e){
						
						setTimeout(body_end,0);
						}
				
				}());
    </script>
  
  </head>
  <body>


<script >


function handler(){
	alert('готов');
	
	}
</script>
<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>

</body>
</html>

cyber 13.07.2012 20:33

блин лоханулся, не работает старых ИЕ =)
сам ответил на свой вопрос(почему не этот вариант не используется)

cyber 13.07.2012 21:19

Цитата:

Сообщение от melky (Сообщение 188566)
а что, если так же, по нулевому таймауту, проверять document.body.innerHTML, или что-то в этом роде?

спасибо за подсказку.
получилась такая простенькая кроссбразуерная функция
function ready(fnc){
	
if(document.addEventListener){
	
  document.addEventListener('DOMContentLoaded',fnc,false);
	
	} else {
			(function body_end(){
				
				try {
					
					document.body.innerHTML
					 fnc();
					} catch(e){
						
						setTimeout(body_end,0);
						}
				
				}());
			  
		
		} 
}

Раед 13.07.2012 22:05

Цитата:

Сообщение от cyber
получилась такая простенькая кроссбразуерная функция

Что-то мне подсказывает что она будет работать неправильно

cyber 13.07.2012 22:13

Цитата:

Сообщение от Раед (Сообщение 188594)
Что-то мне подсказывает что она будет работать неправильно

проверил работает вроде нормально(в старых ие тоже)

Раед 14.07.2012 00:22

Цитата:

Сообщение от cyber
проверил работает вроде нормально(в старых ие тоже)

Пробуйте на страницах с большим количеством разнообразного контента

devote 14.07.2012 01:05

Цитата:

Сообщение от Раед
Что-то мне подсказывает что она будет работать неправильно

конечно будет работать не правильно... Ибо innerHTML у body появляется сразу после того как открывается тег body, а не когда оно закрывается, то-есть содержимое тега может быть не полным при его определении.. Так же в других случаях с appendChild или еще что-то..

это легко проверить:
<body>
<script>
    alert( document.body.innerHTML ); // хотя документ еще не сформирован
</script>
<div></div>
</body>
увидим лишь то что идет до тега script

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

cyber 14.07.2012 01:15

да, я до этого додумался уже, только почему то забыл написать(сел в WOT поиграть:))
вот что мне пришло на в голову
<!DOCTYPE HTML>
<html>
  <head>
    <script>
    
    
		var scr = document.createElement('script');
		   scr.type = 'text/javascript';
			  scr.id = 'DomLoadedScript';
		
			(function body_end(){
				
				try {
					
					document.body.appendChild(scr);
                      alert(document.body.innerHTML);
					} catch(e){
						
						setTimeout(body_end,0);
						}
				
				}());
    </script>
  
  </head>
  <body>


<script >


function handler(){
	alert('готов');
	
	}
</script>
<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>

</body>
</html>

переделал немного совю первую функцию, в боди можно добавить только после полной загрузки=)

devote 14.07.2012 01:19

Цитата:

Сообщение от cyber
в боди можно добавить только после полной загрузки=)

кто тебе это сказал?
<body>
<script>
    document.body.appendChild( document.createElement('b') );
    alert( document.body.innerHTML );
</script>
<div></div>
<script>
    alert( document.body.innerHTML );
</script>
</body>
в потоке можно делать что угодно

devote 14.07.2012 01:24

cyber, вот на твоем примере:
<!DOCTYPE HTML>
<html>
  <head>
    <script>
     
     
        var scr = document.createElement('script');
           scr.type = 'text/javascript';
              scr.id = 'DomLoadedScript';
         
            (function body_end(){
                 
                try {
                     
                    document.body.appendChild(scr);
                      alert(document.body.innerHTML);
                    } catch(e){
                         
                        setTimeout(body_end,0);
                        }
                 
                }());
    </script>
   
  </head>
  <body>
 
 
<script >
 
 
function handler(){
    alert('готов');
     
    }
</script>
<script>
    for( var i = 0; i < 10000; i++ ) {} // просто задержка, вместо задержки может быть тысяча тегов иль еще чего.
</script>
<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>
 
</body>
</html>
в результате видим алерт с содержимым:
<script>
 
 
function handler(){
    alert('готов');
     
    }
</script>
<script>
    for( var i = 0; i < 10000; i++ ) {} // просто задержка, вместо задержки может быть тысяча тегов иль еще чего.
</script><script type="text/javascript" id="DomLoadedScript"></script>

cyber 14.07.2012 01:27

у меня такой алерт
<script>
 
 
function handler(){
    alert('готов');
     
    }
</script>
<script>
    for( var i = 0; i < 10000; i++ ) {} // просто задержка, вместо задержки может быть тысяча тегов иль еще чего.
</script>
<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg">
 


<script type="text/javascript" id="DomLoadedScript"></script>

cyber 14.07.2012 01:29

потом по тестю на большой странице.
а какие еще есть варианты для старых браузеров?

devote 14.07.2012 01:29

Цитата:

Сообщение от cyber
у меня такой алерт

а у меня другой.. и это уже говорит о том что раз на раз не приходится.. тут все зависит от интерпретатора скрипта, на сколько он отложит выполнение setTimeout

devote 14.07.2012 01:31

Цитата:

Сообщение от cyber
а какие еще есть варианты для старых браузеров?

никаких, только то что используют везде.

И еще вопрос а нафига тебе это? То что давно всеми используется нормально работает.

cyber 14.07.2012 03:22

Цитата:

Сообщение от devote (Сообщение 188657)
никаких, только то что используют везде.

И еще вопрос а нафига тебе это? То что давно всеми используется нормально работает.

дак я пытался взять скрипт из этой статьи http://javascript.ru/tutorial/events/ondomcontentloaded вроде понял как он пашет, да вот только в ие не работает,а проверить почему не могу нужно скачать xp для виртуалки что бы запустить и посмотреть ошибки...
вот код со страницей что бы запустить http://learn.javascript.ru/play/Xegrjb.

cyber 14.07.2012 03:41

вот работает везде(покрайнимере я не нашел где не работате )
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	
    <script >
var DOM = {}

function ready(){
	
if(!document.addEventListener){
	
  document.addEventListener('DOMContentLoaded',DOM.loaded,false);
	
	} else {
			var scr = document.createElement('script');
		   scr.type = 'text/javascript';
		   scr.text = 'DOM.loaded()';
			  scr.id = 'DomLoadedScript';
		
			(function body_end(){
				
				try {
					
					document.body.appendChild(scr);
					} catch(e){
						
						setTimeout(body_end,0);
						}
				
				}());
		
		} 
}

DOM.loaded = function (){
	
	handler();
	 img_src();
	}


ready();

	



</script>
  
  

</head>
<body>

<script >
function img_src(){
	
	alert(document.body.innerHTML);
	}

function handler(){
	alert('готов');
	
	}
</script>
<img src="http://worldoftanks.ru/dcont/fb/media/batchat_ru_june_clear/1920x1200.jpg">
<img id="img" src="http://wallpaper.goodfon.ru/image/302908-2880x1800.jpg"/>

</body>
</html>

devote 14.07.2012 03:47

Цитата:

Сообщение от cyber
дак я пытался взять скрипт из этой статьи

function DOMReady( callback ) {
  
    if ( document.readyState === "complete" ) {
        return setTimeout( callback, 1 );
    }
  
    var loaded = function( doScroll ) {
        if ( document.removeEventListener ) {
            document.removeEventListener( 'DOMContentLoaded', loaded, false );
            window.removeEventListener( 'load', loaded, false );
            loaded = null;
            callback();
        } else if ( document.detachEvent ) {
            if ( document.readyState === "complete" || doScroll === null ) {
                document.detachEvent( 'onreadystatechange', loaded );
                window.detachEvent( 'onload', loaded );
                loaded = null;
                callback();
            }
        }
    }
  
    if ( document.addEventListener ) {
        document.addEventListener( "DOMContentLoaded", loaded, false );
        window.addEventListener( "load", loaded, false );
    } else if ( document.attachEvent ) {
        document.attachEvent( "onreadystatechange", loaded );
        window.attachEvent( "onload", loaded );
  
        var toplevel = false;
        try {
            toplevel = window.frameElement == null;
        } catch( _e_ ) {}
  
        if ( document.documentElement.doScroll && toplevel ) {
            var check = function() {
                if ( !loaded ) return;
                try {
                    document.documentElement.doScroll( "left" );
                } catch( _e_ ) {
                    setTimeout( check, 0 );
                    return;
                }
                loaded( null );
            }
            check();
        }
    }
}

cyber 14.07.2012 03:55

devote,сенк щас посмотрим что и как=)

cyber 14.07.2012 03:58

и снова не работает в ие=)

devote 14.07.2012 04:00

Цитата:

Сообщение от cyber
и снова не работает в ие=)

да сорри, это я ошибку сделал.. исправил

cyber 14.07.2012 04:04

Цитата:

Сообщение от devote (Сообщение 188697)
да сорри, это я ошибку сделал.. исправил

спасибо:thanks: :victory:
работает, теперь можно идти спать, а завтра разберусь=)
кстати , а почему этот велосипед плохой
http://javascript.ru/forum/events/29...tml#post188682

cyber 14.07.2012 20:03

сел разбирать твой код, и не могу понять зачем юзать onreadystatechange
если оно срабатывает того когда и onload?

devote 14.07.2012 20:06

Цитата:

Сообщение от cyber
если оно срабатывает того когда и onload?

всегда по разному, зависит от обстоятельств.. например код в iframe будет работать иначе. Или еще какие обстоятельства могут произойти, это же ИЕ

cyber 14.07.2012 20:20

Цитата:

Сообщение от devote (Сообщение 188863)
всегда по разному, зависит от обстоятельств.. например код в iframe будет работать иначе. Или еще какие обстоятельства могут произойти, это же ИЕ

хм...
все зависит от политической ситуации в зимбабве ?=)
а для чего это toplevel = window.frameElement == null;

devote 14.07.2012 20:38

Цитата:

Сообщение от cyber
а для чего это toplevel = window.frameElement == null;

ну это для iframe и нужно

cyber 15.07.2012 04:49

Цитата:

Сообщение от devote (Сообщение 188877)
ну это для iframe и нужно

не ну это я понял=)
я не совсем понял что возвращает свойство frameElement , прочитал в нескольких источниках но так и не понял .сколько не запускал оно возвращает null , тогда зачем оно? или это проверка скрипт запускают в фрейме или нет?

devote 15.07.2012 05:54

Цитата:

Сообщение от cyber
сколько не запускал оно возвращает null

все верно, если оно возвращает null, значит можно проверять document.documentElement.doScroll( "left" ); в противном случае запуск скорее всего был во фрейме и использование document.documentElement.doScroll нам не даст никаких результатов.


Часовой пояс GMT +3, время: 11:05.