Javascript.RU

Кроссбраузерное событие onDOMContentLoaded

Для инициализации страницы исторически использовалось событие window.onload, которое срабатывает после полной загрузки страницы и всех объектов на ней: счетчиков, картинок и т.п.

Событие onDOMContentLoaded - гораздо лучший выбор в 99% случаев. В этой статье рассмотрен код и основные приемы для его кроссбраузерной реализации.

Это событие срабатывает, как только готов DOM документ, до загрузки картинок и других не влияющих на структуру документа объектов.

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

"Родное" событие 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
	*/
}

Разберем его по шагам.

  1. Код будет пытаться поймать событие onDOMContentLoaded различными способами. Вполне может получиться так, что несколько способов сработают независимо.

    Поэтому завернем обработчик handler в функцию ready(), единственный смысл которой - гарантировать, что handler будет вызван не более одного раза.

  2. Событие onDOMContentLoaded поддерживают достаточно новые Firefox, Opera, Safari/Chrome. Нет гарантии, что версия посетителя поддерживает это событие, но попробовать стоит.
  3. Браузер Internet Explorer не поддерживает onDOMContentLoaded, поэтому для него используются обходные пути.
    1. Функция tryScroll() пытается скроллить документ вызовом doScroll. Если получается - значит, документ загрузился, если нет - заказывает повторную попытку через setTimeout, и так пока документ наконец не будет готов. На практике это очень надежный способ, но есть проблемы с фреймами, поэтому используется только для окон верхнего уровня.
      Дополнительный фильтр - проверка document.body
    2. Событие document.onreadystatechange с проверкой readyState="complete", как и onDOMContentLoaded/onload, срабатывает после загрузки документа. Но, к сожалению, оно происходит уже после загрузки картинок. Поэтому onreadystatechange - вообще говоря, не то, что нам надо. Но это событие работает для фреймов, и при этом срабатывает до window.onload. Поэтому будем использовать и этот способ.
  4. Для тех браузеров, в которых не сработали предыдущие методы (например, очень старый Firefox), добавим вызов обработчика при событии window.onload.
    1. Для совсем древних браузеров, в которых нет addEventListener/attachEvent, вы можете раскомментировать и строчку (4.1). При этом, разумеется, возможен конфликт с другими обработчиками onload.

Этот код взят, с небольшими упрощениями, из библиотеки jQuery, а методы придуманы различными авторами.

Код из примера выше позволяет навешивать только один обработчик. Для поддержки нескольких - добавим дополнительную обертку:

readyList = []

function onReady(handler) {

	if (!readyList.length) {
		bindReady(function() {
			for(var i=0; i<readyList.length; i++) {
				readyList[i]()
			}
		})
	}

	readyList.push(handler)
}

Функция onReady при первом вызове вешает обработчик bindReady, который запускает все функции из списка readyList, а в дальнейшем просто добавляет новый обработчик в этот список.

Следующий пример демонстрирует использование onReady:

<html>
<head>
<script src="bindReady.js"></script>
<script src="onReady.js"></script>

<script>
  onReady(function() {
    var divs = document.body.getElementsByTagName('div')
    alert(divs[divs.length-1].innerHTML)
  })
</script>

<link rel="stylesheet" href="my.css" type="text/css">
</head>
<body>

<img src="img5.php"/>

<div>done</div>
</body>
</html>

Открыть в новом окне

Обработчик onReady выводит содержимое последнего тэга <div>, так что мы видим, что документ действительно загружен и разобран.

Картинка <img src="img5.php"/> загружается скриптом, который ждет 5 секунд. Это сделано для демонстрации, что onDOMContentLoaded вызывается до полной загрузки.

В новых Firefox, Safari/Chrome и во всех Internet Explorer поддерживается атрибут defer тэга <script>. Он позволяет загружать скрипт не блокируя загрузку страницы, а параллельно с ней.

Такая отложенная загрузка скриптов позволяет странице грузиться и отображаться быстрее. Обычно откладывают загрузку для толстых библиотек.

Скрипт является объектом, необходимым для загрузки страницы, и событие onDOMContentLoaded всегда срабатывает после загрузки скриптов.

Но Internet Explorer заканчивает рендеринг документа и делает скроллинг возможным до загрузки скриптов с атрибутом defer.
Поэтому doScroll сработает до загрузки таких скриптов.

Поэтому в браузере Internet Explorer описанный код (а значит и код jQuery) при наличии <script defer> будет работать некорректно, а именно - выполняться до загрузки таких скриптов.

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

В качестве альтернативы событию onDOMContentLoaded и функции bindReady можно рассмотреть скриптовую вставку в самом конце <body>:

<body>
...
<script>handler()</script>
</body>

Основной плюс такого подхода - работает везде, не нужен дополнительный кросс-браузерный код поддержки события.

Основной минус - меньшее удобство, нужен дополнительный код в HTML. Кроме того, тег <body> не закрыт, поэтому body.appendChild может не работать.

Исходные коды вы можете скачать в архиве.


Автор: PeaceCoder, дата: 11 января, 2010 - 20:13
#permalink

Вопрос на счет фреймов. Какое из событий в них происходит? DOMContentLoaded или window.onload ? Я когда махался с фреймами то у меня почемуто DomContentLoaded фрейма не выдавал событие и onload тоже не во всех браузерах.


Автор: Илья Кантор, дата: 11 января, 2010 - 20:17
#permalink

Какой браузер? Вы событие ловите внутри фрейма или снаружи?


Автор: PeaceCoder, дата: 12 января, 2010 - 00:05
#permalink

Событие ловил с наружи. А вот в каждом браузере по разному. в частности в FF3.5 DOMContentLoaded для фреймма не выдавал событие.


Автор: Илья Кантор, дата: 12 января, 2010 - 00:11
#permalink

Снаружи это событие не ловится...


Автор: Kolyaj, дата: 12 января, 2010 - 12:17
#permalink

>> * меньшее удобство, нужен дополнительный код в HTML
Чем удобство добавления скрипта в начало страницы отличается от удобства добавления скрипта в конец страницы? И какой нужен дополнительный код в HTML?


Автор: Илья Кантор, дата: 12 января, 2010 - 12:34
#permalink

В конце HTML нужен тэг script с вызовом ready.
При использовании функции bindReady - такой скриптовой вставки не нужно.


Автор: Kolyaj, дата: 12 января, 2010 - 13:05
#permalink

Если подключать все скрипты в конце страницы, то вообще никаких ready не надо, и код сильно упрощается.


Автор: Kiranatus (не зарегистрирован), дата: 1 сентября, 2010 - 17:32
#permalink

Точно! Или, добавить проверку переменной gbLoaded в функции, которым нужна полная загрузка документа, а в конце HTML просто добавить:
...
gLoaded = true;

Таким образом не придётся ждать загрузки картинок.


Автор: CTAPbIu_MABP (не зарегистрирован), дата: 17 января, 2010 - 01:59
#permalink
setTimeout(tryScroll, 0)

у оперы 9 были проблемы если поставлен таймаут 0, ставьте хотя бы 10


Автор: Hank (не зарегистрирован), дата: 16 июня, 2020 - 21:56
#permalink

yes, this sounds right! lubbock fence companies


Автор: Гость (не зарегистрирован), дата: 16 июня, 2020 - 22:35
#permalink

thanks, this is great! excavating near me


Автор: Misha_White, дата: 25 февраля, 2010 - 07:51
#permalink

В восьмом эксплорере не сработал пример...


Автор: Гость (не зарегистрирован), дата: 9 февраля, 2011 - 14:32
#permalink

Тоже самое. В IE8 сообщение появляется после загрузки страницы.


Автор: Shahurik, дата: 15 апреля, 2010 - 00:52
#permalink

В конце кода (отметка 4.1) можно предотвратить конфликт с поставленным обработчиком window.onload:

else
{
    var fn = window.onload || function(){};
    window.onload = function()
    {
        fn();
        ready();
    }
}

Автор: e.kubyshin, дата: 18 августа, 2010 - 14:20
#permalink

вот нагуглил DOM ready


Автор: Mikle, дата: 24 сентября, 2010 - 18:28
#permalink

Между 14 и 15 строчкой в "Код кроссбраузерной поддержки"
нужно добавить:
window.addEventListener( "load", ready(), false );
--
без этого не работает в "хроме" и "сафари"


Автор: Илья Кантор, дата: 6 декабря, 2010 - 23:35
#permalink

Можно подробнее? Что не работает?


Автор: brutaler (не зарегистрирован), дата: 4 августа, 2011 - 23:46
#permalink

Без этого не срабатывает handler в последних хроме и ff.


Автор: Гость_1 (не зарегистрирован), дата: 24 ноября, 2010 - 00:45
#permalink

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

Вроде бы не рабодает все равно с defer. Пример: в хеад - jquery с defer, в конце подключаю файл с кодом, который использует jquery. Если бы скрипты выполнялись последовательно, тогда не выскакивало бы '$ is not defined'. Правильно? Или когда яваскрипт подключен, а не встроен в страницу браузер уже не гарантирует последовательную работу? Что-то запутался


Автор: Гость_1 (не зарегистрирован), дата: 28 ноября, 2010 - 21:43
#permalink

Очень хотелось бы услышать комментарии к этому вопросу. Спасибо.


Автор: Илья Кантор, дата: 2 декабря, 2010 - 22:50
#permalink

Скрипт с DEFER может сработать как до так и после onDOMContentLoaded.


Автор: Гость_1 (не зарегистрирован), дата: 3 декабря, 2010 - 19:39
#permalink

Это не проясняет что вы имели в виду под "Корректно работает со скриптами с defer. Браузер гарантирует последовательное выполнение скриптов, поэтому к моменту выполнения этой вставки все скрипты будут загружены.". Или я в чем-то запутался. Пожалуйста "разжуйте" есть есть время. Спасибо.


Автор: Илья Кантор, дата: 6 декабря, 2010 - 22:27
#permalink

Немного исправил статью. По взаимодействию с DEFER:

DOMContentLoaded может быть как до так и после скриптов с Defer. Обычно после, в Firefox может быть до, если скрипт в кеше.


Автор: Гость (не зарегистрирован), дата: 8 июля, 2011 - 22:55
#permalink

почитав комментарии, понял что этот код, мало того что громоздкий, имеет кучу нюансов, так он ещё и ни фига не гарантирует Sad
скорее в 99% и 999тысчяных процентов, он нафиг ни кому ненужен.
А автору принцип KISS. В коде и без этого забот хватает, а насчёт кросс браузерности, даже в самом худшем варианте,
if(ослик)alert("осликов на сайт не пускаем");
Почему миллионы разработчиков должны что то изобретать, когда ИЕ жопу морщит(извините но других слов ненашол). Объявить байкот ИЕ, хотя бы на личных сайтах, и они сами очень быстро все проблемы связанные с кроссбраузерностью, раз и на всегда устранят, иначе ИЕ безнадёжно устареет.


Автор: tenshi, дата: 17 июля, 2011 - 10:48
#permalink

что мешает просто проверять /^(interactive|complete)$/.test( document.readyState ) и не париться? работает во всех современных браузерах.

.ня


Автор: popov654, дата: 9 сентября, 2011 - 01:02
#permalink

Хорошо, когда работает во всех, а не только в современных. Хотя бы начиная с Firefox1.5/2.0, IE6, Netscape8/9, Opera9 и Safari3


Автор: lex-tomsk2@yandex.ru (не зарегистрирован), дата: 2 января, 2012 - 18:59
#permalink

Немного подумав об "Альтернатива событию onDOMContentLoaded", выношу на СУД свое решение:
создаем ready.js с кодом:

var ready={
	handlers : [],
	add : function(name,handler){
		if(document.body) {
			handler();
			return;
			}
		this.handlers[name]=handler;
	},
	work : function(){
		if(!document.body) {setTimeout("ready.work()",200);return;}
		for(var name in this.handlers){
			this.handlers[name]();
		}
	}
}
ready.work()

Подключаем его в начале страницы, внутри страницы используем регистрацию:

ready.add('name',function(){
	alert("Документ : "+ ((document.body) ? ("yes") : ("no")))
	});

В комментариях код не нуждается Dance3 .


Автор: Гость (не зарегистрирован), дата: 24 января, 2012 - 06:11
#permalink

Не лучшее решение.
Сразу бросаются в глаза "тяжелые зависимости", вроде setTimeout('ready.work();'...);. Плюс исполнение кода в неявном eval'е и итерация по элементам массива циклом for-in.
Плюс, если предполагется множество обработчиков, то логичнее вызывать их в порядке добавления, чего не гарантирует выбранный Вами тип цикла.
Да и проверка document.body не гарантирует ожидаемого.

Для большей уверенности, в том, что это сработает там, где кто-либо преопределил прототип Array или ожидает срабатывания обработчиков в порядке их назначения используйте

function Ready() {
	var handlers = [];
	
	(function waitBody()
	{
		if (document.body)
			for (var i = 0, l = handlers.length; i < l; ++i)
				handlers[i]();
		else
			setTimeout(function() {
				waitBody();
			}, 200);
	})();
	
	return {
		addHandler : function (handler) {
			if (document.body)
				handler();
			else
				handlers.push(handler);
		}
	};
}

А использовать:

var customObject = new Ready();
customObject.addHandler(function(){
    alert("Документ : "+ ((document.body) ? ("yes") : ("no")))
    });

Автор: lex-tomsk2@yandex.ru (не зарегистрирован), дата: 5 февраля, 2012 - 19:41
#permalink

Согласен, что немного поспешил с ready.js.
Да и если честно - не знал, что в setTimeout можно передавать функцию... Blink

Переделал с учетом критики:

Ready={
	pr:"onDocumentReady_", // защита от изменений прототипа массива
	handlers:[],
	add:function(name,handler){
		if(document.body && !this.handlers[this.pr+name]){
			handler();
		}
		this.handlers[this.pr+name]=handler;
	},
	work:function(){                /* интересное место */
		if(!document.body) {setTimeout(this.work,200);return;}
		for(name in this.handlers){
			if(name.indexOf(this.pr)==0) this.handlers[name]();
		}
	}
};
Ready.work();

Параметр name передавать необходимо, чтобы исключить повторное выполнение.
В замыканиях я не силен, поэтому если можно их избежать без вреда для кода, то избегаю.
Интересное место - сначала думал, что передаваемая функция будет работать в глобальном контексте (по аналогии со строкой), и нужно будет ставить Ready.work, но все оказалось намного приятнее.
Толком не протестировал. Но вроде должно работать.

Вопрос к предыдущему Гостю: что Вы имеете в виду, когда говорите, что document.body не гарантирует ожидаемого? Я думаю, что если body доступен, то уже можно работать с его содержимым.


Автор: Раед, дата: 19 марта, 2012 - 15:02
#permalink

если body доступен, то уже можно работать с его содержимым.

Не факт, document.body может быть доступен до загрузки всего содержимого


Автор: Раед, дата: 7 мая, 2012 - 10:51
#permalink

Есть ещё 1 простой вариант без поддержки фреймов. Можно проверять document.documentElement.innerHTML на наличие закрывающего тега body. Странно, что до этого раньше никто не додумался, или я чего-то не понимаю?


Автор: DarkDaemon, дата: 30 мая, 2013 - 03:14
#permalink

Пробовал так, но работает это не всегда:

docreadytimer = setInterval("if (document.getElementsByTagName('html')[0].innerHTML.indexOf('/body') > 0){clearInterval(docreadytimer); start();}", 50);

Видимо, современные браузеры достраивают документ и выводят его пользователю в ходе загрузки и еще до загрузки всего содержимого, т.е. в структуру документа проставляют < /body >< /html >


Автор: Joker99 (не зарегистрирован), дата: 26 апреля, 2014 - 20:27
#permalink

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


Автор: Гость (не зарегистрирован), дата: 24 августа, 2012 - 09:29
#permalink

Спасибо за код. Почти везде работает.


Автор: Гость (не зарегистрирован), дата: 29 августа, 2014 - 18:16
#permalink

Не могу понять логику кода. Помогите пожалуйста. Возможно я что-то недопонимаю. Попытался разобрать исходный код автора пошагово:

пункт_1. в OnReady в качестве аргумента "Хэндлера-1" передаётся функция, которая выводит алёртом значение последнего Дива.

пункт_2. внутри функции OnReady:
пункт_2-а) благодаря тому, что readyList[] пустой = вызывается функция bindReady, которой в качестве аргумента "Хэндлера-2" передаётся функция, которая вызывает все функции из списка readyList[], который пока ещё ПУСТ(!).
пункт_2-б) ПОСЛЕ вызова функции bindReady, переданный в неё из функции OnReady "Хэндлер-1" отправляется в массив readyList[].

пункт_3. внутри функции bindReady:
доходим по логике до 18-й строки кода, где, предположим, мы получим TRUE и выполнится функция tryScroll().

пункт_4. внутри функции tryScroll():
тут called=False, идём дальше, и предполагаем, что document.body=TRUE => тогда запускается блок TRY, в котором вызывается функция ready().

пункт_5. внутри функции ready():
called становится true, и запускается handler(), т.е. функция которая была передана в функцию bindReady через аргумент handler, т.е. выше упомянутый "Хэндлер-2", который запускает все функции из списка readyList[], который к данному моменту ПУСТ (!) из-за того, что из пункта "2-а" мы улетели в пункт "3" (и пункт "2-б" ещё не выполнялся). ТО ЕСТЬ, по идее НЕЧЕМУ выполняться.

пункт_6.
- из функции ready() возвращаемся в блок TRY;
- крутим tryScroll пока документ не будет ГОТОВ;
- выходим из конструкции if () на 30 строке кода;
- на 33-й строке ready() вешается как обработчик (при этом в теле этой функции на данный момент до сих пор содержится handler() который есть "Хэндлер-2", то есть выполнение ПУСТОГО списка readyList);
- и улетаем из функции bindReady обратно в функцию OnReady, из которой её вызывали, и попадаем на пункт "2-б" в котором добавляется "Хэндлер-1" в список функций вызываемых "Хэндлером-2" (который уже нигде по коду не вызывается);
- выходим из функции OnReady.

ВОПРОС: Откуда же тогда, и на каком этапе кода, будет вызван обработчик "Хэндлер-1", который собственно и отвечает за показ Названия Последнего тэга Дива с помощью алёрта ???


Автор: Гость (не зарегистрирован), дата: 3 сентября, 2014 - 16:32
#permalink

Не правильнее в строке 42 вместо:

if (window.addEventListener)

сделать

esle if (window.addEventListener)


Автор: dufus (не зарегистрирован), дата: 13 октября, 2014 - 12:57
#permalink

Добрый день. А почему функция onReady не срабатывает если ее запихнуть в условие ?.....к примеру

if (/(home)/i.test(url)|| window.location.pathname.charAt(1) === '') {
 onReady(function() {
		document.getElementById("tab-menuSrc").style.display="block";
		document.getElementById("menuSrc").className="menuSrcOnMouseOver";
		document.getElementById("tab-menuServices").style.display="none";
  })
}

Автор: Разработчик (не зарегистрирован), дата: 12 июня, 2018 - 21:22
#permalink

Очень понравился материал, но можно и подробнее


Автор: Devlin Martin (не зарегистрирован), дата: 5 августа, 2020 - 12:12
#permalink

О, благодаря этому обмену вы раскрыли многие мои идеи, поэтому я могу узнать больше о многих ценных вещах. run 3


Автор: Гость (не зарегистрирован), дата: 12 апреля, 2022 - 21:36
#permalink

Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 01:25
#permalink

Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 14:29
#permalink

Автор: brownlaur57 (не зарегистрирован), дата: 1 июля, 2022 - 12:12
#permalink

Hi there, I am here to find new friends who love playing online games. We can make friends and play tunnel rush in our free time. It's so funny, let's try it!


Автор: danielusa, дата: 30 июля, 2022 - 07:19
#permalink

wow, I went crazy reading your post, it's very good and informative. and if you have free time then I invite you to play the game wordle and io games with me.


Автор: Гость (не зарегистрирован), дата: 6 октября, 2022 - 06:49
#permalink

Hope someone can explain more detail. I have the same problem five nights at freddy's.


Автор: keo nha cai (не зарегистрирован), дата: 6 октября, 2022 - 07:08
#permalink

I was looking for another article by chance and found your article keo nha cai I am writing on this topic, so I think it will help a lot. I leave my blog address below. Please visit once.


Автор: Гость (не зарегистрирован), дата: 10 октября, 2022 - 12:28
#permalink

cuphead I can make out a great deal of essential information.


Автор: kemmer (не зарегистрирован), дата: 11 октября, 2022 - 10:30
#permalink

Вы вызываете мое неугасающее восхищение за то, что написали такое замечательное произведение. Мне очень понравилось читать эту статью, и я думаю, что она может быть лучшей из тех, что я читал до сих пор. В идеале вы должны поддерживать один и тот же высокий стандарт на протяжении всего выполнения этого задания. fnf mod


Автор: tomusa, дата: 14 ноября, 2022 - 11:56
#permalink

The information you share is very good and exciting, I will definitely follow your next posts. krunker


Автор: Zac Macintyre (не зарегистрирован), дата: 5 января, 2023 - 15:20
#permalink

Photo gallery is filled and approved for the use of the offers. The discount of the Diesel Gas Station Near Me are ensured for the challenges. Mandatory look is fit for the mixing of the goals for the native and all joys for the main field for the citizens.


Автор: kevintexas0106 (не зарегистрирован), дата: 9 марта, 2023 - 04:45
#permalink

I am very impressed with the information drift boss you share, which will play an important role in adding material to the topic the impossible quiz people are researching.


Автор: Гость (не зарегистрирован), дата: 13 марта, 2023 - 07:09
#permalink

This is an article full of interesting and useful information. You can share it on many subway surfers websites so that everyone can learn and learn together.


Автор: Гость (не зарегистрирован), дата: 29 марта, 2023 - 11:40
#permalink

I appreciate your efforts over the past time, you have shown everyone that this article of yours wordle deserves everyone's recognition. Great article!


Автор: lunadam (не зарегистрирован), дата: 20 апреля, 2023 - 07:50
#permalink

Before images and other backrooms game items that do not alter the structure of the document have finished loading, this event is fired as soon as the DOM document is ready. Because images can take a while to load, this is particularly practical because the onDOMContentLoaded handler can alter the page and instantiate interfaces right backrooms immediately without having to wait for everything to load.


Автор: revelationresist (не зарегистрирован), дата: 21 апреля, 2023 - 12:59
#permalink

No ready is required and the code is substantially streamlined if all the scripts are connected at the end of the page. flappy bird


Автор: Гость (не зарегистрирован), дата: 19 мая, 2023 - 10:09
#permalink

I've heardle realized the importance of taking care of my physical health to maintain energy levels throughout the day


Автор: Гость (не зарегистрирован), дата: 20 мая, 2023 - 06:43
#permalink

If all the scripts are linked to the bottom of the page, no ready is needed, and the code is greatly streamlined.


Автор: Dilan Turner (не зарегистрирован), дата: 24 мая, 2023 - 09:13
#permalink

Автор: Andrea Newsom (не зарегистрирован), дата: 24 мая, 2023 - 09:25
#permalink

Автор: Keiren Harrison (не зарегистрирован), дата: 24 мая, 2023 - 09:44
#permalink

Awesome post, thank you for sharing this one. https://asbestosremovalbrooklyn.com/asbestos-removal-brooklyn-ny/


Автор: Гость (не зарегистрирован), дата: 5 июня, 2023 - 05:00
#permalink

You've come this far and I think that's great, keep chasing your dreams and one day you'll reach the top and then you'll see how great you've become . pge outage map


Автор: Frank Miranda (не зарегистрирован), дата: 7 июня, 2023 - 18:25
#permalink

Your work is great. You can learn so much from dealing with you. vampire survivors


Автор: adamusa (не зарегистрирован), дата: 8 июня, 2023 - 10:46
#permalink

I wish I knew about this article sooner because the information in it is amazing and exactly what I was looking for. mapquest directions florida


Автор: clamb (не зарегистрирован), дата: 12 июня, 2023 - 09:43
#permalink

Great information, I will recommend it to my friends for them to check out. Thanks for sharing! If you have more time, please visit: trap the cat


Автор: 3d product animation (не зарегистрирован), дата: 18 июля, 2023 - 11:46
#permalink

3D product animation services are the next big thing for businesses that want to go global and provide a better customer experience. We at Atellier Studio offer the best 3D rendering and visualization services, which allow you to have a realistic view of your products from any angle.


Автор: elijahnelson (не зарегистрирован), дата: 26 июля, 2023 - 09:39
#permalink

Since images and other media files can sometimes take a significant amount of time to load, mapquest driving directions using DOMContentLoaded allows the page to feel more responsive to users as it doesn't wait for these resources to be fully fetched.


Автор: Raymond Lane (не зарегистрирован), дата: 31 июля, 2023 - 10:12
#permalink

This is very useful information for me. Thank you. Besides, I would like to share with you a website that I found very interesting, which is:dinosaur game


Автор: Гость (не зарегистрирован), дата: 7 августа, 2023 - 12:17
#permalink

This is extremely helpful information for me. geometry dash scratch


Автор: Гость (не зарегистрирован), дата: 22 августа, 2023 - 05:53
#permalink

You are on a mission to engage and educate your fnf game audience. The information you provide has been very helpful to me. And you succeeded brilliantly!


Автор: Гость (не зарегистрирован), дата: 31 августа, 2023 - 12:28
#permalink

Enter the wild and wacky world of subway surfers online where the only rule is egg-stermination!


Автор: Noah1 (не зарегистрирован), дата: 8 сентября, 2023 - 12:15
#permalink

Это фантастический и информативный пост, к которому я обязательно вернусь и прочитаю еще раз. immaculate grid Спасибо.


Автор: where am i (не зарегистрирован), дата: 5 октября, 2023 - 18:44
#permalink

JavaScript и все DOM-элементы - это всё, ради чего мы здесь, чтобы помочь мне манипулировать объектами. my location


Автор: Гость (не зарегистрирован), дата: 9 октября, 2023 - 13:55
#permalink

Действительно впечатляющая статья! Есть много полезной информации. Я постараюсь следовать вместе с where am i.


Автор: rosiewilsonnsjh (не зарегистрирован), дата: 17 октября, 2023 - 07:25
#permalink

Thank you for providing the text.Connections Game


Автор: SEO (не зарегистрирован), дата: 18 октября, 2023 - 11:29
#permalink

I am happy to find this post very useful for me, as it contains lot of information. I always prefer to read the quality content and this thing I found in you post. Thanks for sharing. MCPE Apk


Автор: lalisa167 (не зарегистрирован), дата: 8 ноября, 2023 - 05:37
#permalink

You really overloaded me with knowledge, and I appreciate it. after gaining new knowledge from the posts I've read on your blog. I'm excited to gain knowledge from your practical experience. I am grateful that you shared.
papa;s freezeria


Автор: Гость (не зарегистрирован), дата: 27 ноября, 2023 - 12:42
#permalink

Traverse the globe without leaving your gaming chair as you join the worldwide community of Watermelon Game players, all connected by a love for strategic fruit merging and avoiding the chaos of excessive stacking.


Автор: jeffreestar (не зарегистрирован), дата: 23 декабря, 2023 - 05:22
#permalink

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


Автор: ryanrobbie (не зарегистрирован), дата: 9 января, 2024 - 12:59
#permalink

The suggestions you mentioned above are impressive. Although the topic may not be new, the article presents reasonable and modern arguments mapquest driving directions


Автор: Гость (не зарегистрирован), дата: 18 января, 2024 - 06:42
#permalink

The recommendations you made above are very good. The essay offers logical and contemporary reasons, even if the subject may not be entirely fresh space bar clicker


Автор: جزوه سیتی (не зарегистрирован), дата: 21 февраля, 2024 - 01:06
#permalink

دانلود برترین جزوه در وب جزوه سیتی


Автор: Kussyat (не зарегистрирован), дата: 23 февраля, 2024 - 12:08
#permalink

You can show off your super-driving skills in the Drift Boss game.


Автор: Гость (не зарегистрирован), дата: 5 марта, 2024 - 07:14
#permalink

To relax and have fun visit our website 2048


Автор: Гость (не зарегистрирован), дата: 5 марта, 2024 - 07:14
#permalink

To relax and have fun visit our website 2048


Автор: Kiramann (не зарегистрирован), дата: 15 марта, 2024 - 07:26
#permalink

Stickman Boost is a thrilling first-person shooter video game. To complete the level, you will need to take control of a stickman and guide him through it while guiding him around obstacles by moving, sliding, or jumping.


Автор: dallasflynn (не зарегистрирован), дата: 25 марта, 2024 - 12:23
#permalink

It teaches me a lot of interesting things shell shockers


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
8 + 2 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum