- Реализация и альтернатива основных JQuery функций на чистом JavaScript
- $(document).ready( Function ); или $( Function );
- $.ajax( Object );
- Глобальная функция $(. );
- JavaScript document.ready() – Document Ready JS and jQuery Example
- How to Use the $(document).ready() Method in jQuery
- How to Use the DOMContentLoaded Event in JavaScript
- Summary
- $( document ).ready()
- Last Updated
- Suggestions, Problems, Feedback?
- Chapters
- Books
Реализация и альтернатива основных JQuery функций на чистом JavaScript
Когда я начинал учить веб-программирование, встретил лучший из всех, по моему мнению, фреймворков — JQuery. В то далёкое время нельзя было представить нормальное программирование без него, так как он мог делать одной строкой то, что делал JavaScript за 95.
В сегодняшнее время, JavaScript очень изменился. В него добавили большой функционал, который сокращает количество кода в разы и делает программирование более удобным. Но даже с этими обновлениями он не может воспроизвести некоторые, даже самые простые, функции из JQuery, и когда мы решаем отказаться от этого фремворка, то чувствует некую трудность из за этого.
Так вот, в этой статье я хочу рассказать о реализациях некоторых функций из JQuery на чистом JavaScript.
$(document).ready( Function ); или $( Function );
Для тех кто не знает, это функция готовности DOM дерева. Т.е. эта функция запускается, когда DOM страницы был полностью загружен.
Начиная с IE9+ эту функцию можно заменить с помощью события DOMContentLoaded повешенного на document .
document.addEventListener('DOMContentLoaded', function() < // Ваш скрипт >, false);
Если вам нужна поддержка начиная с IE4+, то можно воспользоваться более старым методом — с помощью события readystatechange повешенного на document и проверкой readyState .
document.onreadystatechange = function() < if(document.readyState === 'complete')< // Ваш скрипт >>;
Если же мы посмотрим в исходники JQuery, то выйдет следующая функция:
var ready = (function() < var readyList, DOMContentLoaded, class2type = <>; class2type["[object Boolean]"] = "boolean"; class2type["[object Number]"] = "number"; class2type["[object String]"] = "string"; class2type["[object Function]"] = "function"; class2type["[object Array]"] = "array"; class2type["[object Date]"] = "date"; class2type["[object RegExp]"] = "regexp"; class2type["[object Object]"] = "object"; var ReadyObj = < // Является ли DOM готовым к использованию? Установите значение true, как только оно произойдет. isReady: false, // Счетчик, чтобы отслеживать количество элементов, ожидающих до начала события. См. #6781 readyWait: 1, // Удерживать (или отпускать) готовое событие holdReady: function(hold) < if (hold) < ReadyObj.readyWait++; >else < ReadyObj.ready(true); >>, // Обрабатывать, когда DOM готов ready: function(wait) < // Либо трюк не работает, либо событие DOMready/load и еще не готовы if ((wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady)) < // Убедитесь, что тело существует, по крайней мере, в случае, если IE наложает (ticket #5443). if (!document.body) < return setTimeout(ReadyObj.ready, 1); >// Запоминаем что DOM готов ReadyObj.isReady = true; // Если обычное событие DOM Ready запускается, уменьшается и ожидает, если потребуется, if (wait !== true && --ReadyObj.readyWait > 0) < return; >// Если функции связаны, выполнить readyList.resolveWith(document, [ReadyObj]); // Запуск любых связанных событий //if ( ReadyObj.fn.trigger ) < // ReadyObj( document ).trigger( "ready" ).unbind( "ready" ); //>> >, bindReady: function() < if (readyList) < return; >readyList = ReadyObj._Deferred(); // Поймать случаи, когда $(document).ready() вызывается после // события браузера, которое уже произошло. if (document.readyState === "complete") < // Обращайтесь к нему асинхронно, чтобы позволить скриптам возможность задержать готовность return setTimeout(ReadyObj.ready, 1); >// Mozilla, Opera и webkit nightlies в настоящее время поддерживают это событие if (document.addEventListener) < // Используем удобный callback события document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); // Откат к window.onload, который всегда будет работать window.addEventListener("load", ReadyObj.ready, false); // Если используется тип событий IE >else if (document.attachEvent) < // Обеспечить запуск перед загрузкой, // Возможно, поздно, но безопасно также для iframes document.attachEvent("onreadystatechange", DOMContentLoaded); // Откат к window.onload, который всегда будет работать window.attachEvent("onload", ReadyObj.ready); // Если IE, а не frame // Постоянно проверяем, готов ли документ var toplevel = false; try < toplevel = window.frameElement == null; >catch (e) <> if (document.documentElement.doScroll && toplevel) < doScrollCheck(); >> >, _Deferred: function() < var // список callback callbacks = [], // stored [ context , args ] fired, // Чтобы избежать запуска, когда это уже сделано firing, // Чтобы узнать, отменена ли отсрочка cancelled, // Отложенный deferred = < // done( f1, f2, . ) done: function() < if (!cancelled) < var args = arguments, i, length, elem, type, _fired; if (fired) < _fired = fired; fired = 0; >for (i = 0, length = args.length; i < length; i++) < elem = args[i]; type = ReadyObj.type(elem); if (type === "array") < deferred.done.apply(deferred, elem); >else if (type === "function") < callbacks.push(elem); >> if (_fired) < deferred.resolveWith(_fired[0], _fired[1]); >> return this; >, // Разрешить с заданным контекстом и аргументами resolveWith: function(context, args) < if (!cancelled && !fired && !firing) < // Убедитесь, что имеются аргументы (#8421) args = args || []; firing = 1; try < while (callbacks[0]) < callbacks.shift().apply(context, args); //shifts a callback, and applies it to document >> finally < fired = [context, args]; firing = 0; >> return this; >, // решить с этим в качестве контекста и приведенных аргументов resolve: function() < deferred.resolveWith(this, arguments); return this; >, // Отложено ли это решение? isResolved: function() < return !!(firing || fired); >, // Отмена cancel: function() < cancelled = 1; callbacks = []; return this; >>; return deferred; >, type: function(obj) < return obj == null ? String(obj) : class2type[Object.prototype.toString.call(obj)] || "object"; >> // Проверка готовности DOM для Internet Explorer function doScrollCheck() < if (ReadyObj.isReady) < return; >try < // Если используется IE, то используйте трюк Диего Перини // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); >catch (e) < setTimeout(doScrollCheck, 1); return; >// И выполнить функцию ожидания ReadyObj.ready(); > // Функция очистки для document ready if (document.addEventListener) < DOMContentLoaded = function() < document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); ReadyObj.ready(); >; > else if (document.attachEvent) < DOMContentLoaded = function() < // Убедимся, что тело существует, по крайней мере, в случае, если IE наложает (ticket #5443). if (document.readyState === "complete") < document.detachEvent("onreadystatechange", DOMContentLoaded); ReadyObj.ready(); >>; > function ready(fn) < // Прикрепление слушателя ReadyObj.bindReady(); var type = ReadyObj.type(fn); // Добавление callback'а readyList.done(fn); // ReadyList является результатом _Deferred() >return ready; >)();
Запуск функции происходить таким образом:
$.ajax( Object );
Для тех кто не знает, эта функция выполняет асинхронный HTTP (Ajax) запрос.
Как бы это ни было банально, но альтернативой для Jquery.ajax() является XMLHttpRequest
Для начала, нам бы следовало создать кроссбраузерную функцию для отправки, т.к. в разных браузерах функция отправки может быть разной. Она создаётся таким образом:
function getXmlHttp() < var xmlhttp; try < xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); >catch (e) < try < xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); >catch (E) < xmlhttp = false; >> if (!xmlhttp && typeof XMLHttpRequest !== 'undefined') < xmlhttp = new XMLHttpRequest(); >return xmlhttp; >
А вот сам пример стандартного POST запроса с обработкой ошибок:
var xmlhttp = getXmlHttp(); // Получаем нашу функцию xmlhttp.open('POST', '/someurl', true); // Отправляем POST запрос на адрес "/someurl" // Вызываем функцию при изменении статуса запроса xmlhttp.onreadystatechange = function() < if (xmlhttp.readyState !== 4) return; // Если запрос не завершён, то ничего не делаем // Немного о статусах: // Статус 0 — Объект XMLHttpRequest был создан, но метод open() ещё не вызывался. // Статус 1 — Был вызван метод open(). На этом этапе методом setRequestHeader() могут быть установлены заголовки запроса (request headers), после чего, для начала выполнения запроса, может быть вызван метод send() . // Статус 2 — Был вызван метод send() и получены заголовки ответа (response headers) . // Статус 3 — Получена часть ответа. Если responseType это пустая строка или имеет значение "text", responseText будет содержать загруженную порцию текста ответа. // Статус 4 — Операция доставки данных завершена. Это может означать как то, что передача данных полностью завершена успешно, так и то, что произошла ошибка. clearTimeout(timeout); // Удаляем Timeout, если запрос завершён if (xmlhttp.status == 200) < // Если запрос был отправлен успешно и мы получили ответ, то обрабатываем информацию console.log(xmlhttp.responseText); >else < // Если же у нас ошибка, то отправляем её в обработчик handleError(xmlhttp.statusText); >> // Указываем данные, которые нам нужно отправить xmlhttp.send("a=5&b=4"); // Создаём таймер на 10 секунд. Он нужен для того, чтобы, когда ответ от сервера не приходит, выдать ошибку var timeout = setTimeout( function()< xmlhttp.abort(); handleError('Time over') >, 10000); // Создаём функцию обработки ошибок function handleError(message) < // Тут мы принимает текст ошибки и распологаем ним как хотим console.log('Ошибка: ' + message); >
Глобальная функция $(. );
Если кто не знает, этой функцией создаётся глобальный JQuery объект.
Тут я не буду расписывать полный функционал этой функции, так как это займёт у меня минимум неделю, а просто напишу, как создаётся подобная вещь по примеру JQuery.
Для начала создадим обычную функцию, к примеру, Library с аргументами (селектор и контекст).
var Library = function (selector, context) <>;
Далее пишем общую функцию. В JQuery значения, которые попадают в функцию перебираются с помощью условий и выводится результат
var init = function (selector, context) < // Для начала мы создадим массив, // в который будем скидывать элементы var array = []; /** Сначала мы проработаем вариан, * когда кодер указал селектор * или HTML код в первом аргументе */ if (typeof selector === 'string' ) < /** Нам нужно попарсить HTML код * чтобы узнать селектор это или код. * Для парсинка в JQuery используется * следующее регулярное выражение: * /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/ */ if (/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/.exec(selector)) < // Сначала я распарсю код var DOM = new DOMParser().parseFromString(selector, 'text/html'); var DOMList = DOM.body.childNodes; // Тут ещё нужно вспомнить про context и проверить его на значения if (!context || <>.toString.call(context) !== '[object Object]') < context = null; >; // Далее добавляем элементы новый в массив for (var i = 0; i < DOMList.length; i++) < if (context) < for (var attr in context) < DOMList[i].setAttribute(attr, context + ''); >; >; array[array.length] = DOMList[i]; >; return array; > else < // Тут нужно проверить // является ли свойство // context элементом, // в котором нужно искать // объект var DOMList = <>.toString.call(context) === '[object HTMLElement]' ? context.querySelectorAll(selector) : document.querySelectorAll(selector); // Теперь перекидываем все элементы в массив // и выводим for (var i = 0; i < DOMList.length; i++) < array[array.length] = DOMList[i]; >; return array; >; // Тут мы проверим, является ли первый аргумент массивом > else if (<>.toString.call(selector) === '[object Array]') < // Перекидываем значения и выводим for (var i = 0; i < selector.length; i++) < array[array.length] = selector[i]; >; return array; // Далее я проверю, может это объект или один элемент > else if (<>.toString.call(selector) === '[object Object]' || <>.toString.call(selector) === '[object HTMLElement]') < // Запихиваем объект в массив и выводим array[0] = selector; return array; // Теперь проверяем, может это живой массив элементов? >else if (<>.toString.call(selector) === '[object HTMLCollection]' || <>.toString.call(selector) === '[object NodeList]') < // Перекидываем значения и выводим for (var i = 0; i < selector.length; i++) < array[array.length] = selector[i]; >; return array; // Если ничего не подходит, то выводим пустой массив > else < return array; >>;
Теперь мы можем добавить запуск этой функции через основную
var Library = function (selector, context) < // Получаем массив из основной функции var array = new init(selector, context); /** Тут мы создаём объект. * К его proto присваиваем * прототип главной функции, * чтобы потом можно было * создавать дополнительный * функционал */ var object = < __proto__: Library.prototype >; // Далее мы перекидываем элементы // Из массива в объект и создаём // параметр length, чтобы потом можно // было узнать, сколько элементов // в объекте for (var i = 0; i < array.length; i++) < object[i] = array[i]; >; object.length = array.length; return object; >;
JavaScript document.ready() – Document Ready JS and jQuery Example
Ihechikara Vincent Abba
When working with JavaScript and the Document Object Model (DOM), you might want your script to run only when the DOM has loaded.
You can do this using the $(document).ready() method in jQuery, or the DOMContentLoaded event in vanilla JavaScript.
In this article, you’ll learn how to make your JavaScript code run only when the DOM has loaded using jQuery and vanilla JavaScript.
How to Use the $(document).ready() Method in jQuery
Before JavaScript runs in the browser, it waits for the contents of the document to load. This includes stylesheets, images, and so on.
As a convention, placing the script element just before the closing body tag makes the script wait for the rest of the document to load before running.
We also can make this process faster in jQuery by using the $(document).ready() method. The $(document).ready() method only waits for the DOM to load, it doesn’t wait for stylesheets, images, and iframes.
In the code above, the $(document).ready() method will only run after the DOM has loaded. So you’ll only see «Hello World!» in the console after the $(document).ready() method has started running.
In summary, you can write all your jQuery code inside the $(document).ready() method. This way, your code will wait for the DOM to be loaded before running.
How to Use the DOMContentLoaded Event in JavaScript
Just like jQuery’s $(document).ready() method, the DOMContentLoaded event fires once the DOM has loaded – it doesn’t wait for stylesheets and images.
Here’s how to use the DOMContentLoaded event:
document.addEventListener("DOMContentLoaded", () => < console.log("Hello World!"); >);
Once the DOM has loaded, the DOMContentLoaded event will detect it and run.
You should use the DOMContentLoaded event when:
- You have certain functionalities in your webpage that should fire immediately without waiting for the rest of the page content.
- You have a script tag placed within the head element.
Summary
In this article, we talked about the $(document).ready() method in jQuery, and the DOMContentLoaded event in vanilla JavaScript.
We use them to execute JavaScript code when the DOM has loaded.
The interesting part of these functionalities is that they let JavaScript code run without waiting for images and stylesheets to load completely in a web page.
$( document ).ready()
A page can’t be manipulated safely until the document is «ready.» jQuery detects this state of readiness for you. Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute. Code included inside $( window ).on( «load», function() < . >) will run once the entire page (images or iframes), not just the DOM, is ready.
// A $( document ).ready() block.
$( document ).ready(function( )
console.log( "ready!" );
>);
Experienced developers sometimes use the shorthand $() for $( document ).ready() . If you are writing code that people who aren't experienced with jQuery may see, it's best to use the long form.
// Shorthand for $( document ).ready()
$(function( )
console.log( "ready!" );
>);
You can also pass a named function to $( document ).ready() instead of passing an anonymous function.
// Passing a named function instead of an anonymous function.
function readyFn( jQuery )
// Code to run when the document is ready.
>
$( document ).ready( readyFn );
// or:
$( window ).on( "load", readyFn );
The example below shows $( document ).ready() and $( window ).on( "load" ) in action. The code tries to load a website URL in an and checks for both events:
html>
head>
script src="https://code.jquery.com/jquery-1.9.1.min.js"> script>
script>
$( document ).ready(function( )
console.log( "document loaded" );
>);
$( window ).on( "load", function( )
console.log( "window loaded" );
>);
script>
head>
body>
iframe src="http://techcrunch.com"> iframe>
body>
html>
Last Updated
Suggestions, Problems, Feedback?
Chapters
Books
Copyright 2023 OpenJS Foundation and jQuery contributors. All rights reserved. See jQuery License for more information. The OpenJS Foundation has registered trademarks and uses trademarks. For a list of trademarks of the OpenJS Foundation, please see our Trademark Policy and Trademark List. Trademarks and logos not indicated on the list of OpenJS Foundation trademarks are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. OpenJS Foundation Terms of Use, Privacy, and Cookie Policies also apply. Web hosting by Digital Ocean | CDN by StackPath