10 советов, как составлять JavaScript без jQuery
JQuery - отличная библиотека. Она появилась примерно в то же время, когда IE6 считался браузером номер один. В то время было много специфических нюансов и различий между разными приложениями.
Их было довольно утомительно обходить, а JQuery - это идеальный инструмент для написания кода для разных браузеров:

Однако сегодня веб-браузеры очень серьезно продвинулись по сравнению с теми временами. Мы можем спокойно использовать все возможности ES5, а кроме того в нашем распоряжении есть невероятные HTML5 API, которые делают работу с DOM намного приятнее.
Разработчики теперь имеют возможность выбора, для некоторых проектов они могут не использовать JQuery, но при этом сохраняют производительность на прежнем уровне.
Не поймите меня превратно - JQuery прекрасная библиотека, и случаев, когда она вам понадобится, будет намного больше, чем наоборот. Тем не менее, для более мелких проектов, таких как простые страницы, с ограниченными JS-взаимодействиями, расширения браузеров и мобильные сайты, вы можете использовать Vanilla JS.
Ниже приводятся 10 советов, которые помогут вам в работе.
- 1. Ожидание готовности документа
- JS
- 2. Выбор элементов
- JS
- HTML
- 3. Установка и удаление обработчиков событий
- JS
- HTML
- CSS
- 4. Действия с классами и атрибутами
- JS
- HTML
- CSS
- 5. Получение и установка содержимого элемента
- JS
- HTML
- 6. Вставка и удаление элементов
- JS
- HTML
- 7. Переходы по дереву DOM
- JS
- HTML
- CSS
- 8. Обработка массивов через цикл
- JS
- 9. Анимация
- JS
- HTML
- CSS
- 10. AJAX
1. Ожидание готовности документа
Первое, что вы делаете, когда создаете JQuery, это укладываете код в вызов $(document).ready() так, чтобы вы знали, когда DOM готов к действиям. Без JQuery мы имеем событие DOMContentLoaded. Вот как оно используется:
JS
// Добавляем ожидание события DOMContentLoaded ко всему документу и вызываем анонимную функцию.
// Вы можете заключить код в функцию,
// и он будет выполняться сразу после того, как завершится загрузка.
document.addEventListener('DOMContentLoaded', function () {
// Наше гавайское приветствие высветится на экране, как только загрузится страница,
console.log('Aloha');
});
2. Выбор элементов
Когда-то, мы могли выбирать элементы только по ID, классам и именам тегов, и JQuery с его смарт CSS-подобными селекторами был нашим спасителем. Теперь браузеры исправили этот недочет и представили два важных приложения - querySelector и querySelectorAll:
JS
// Этот единственный аргумент является строкой, содержащей один или больше CSS-селекторов.
var lochNess = document.querySelector(".monsters");
console.log("It's from Scotland - " + lochNess.textContent);
// Мы также можем извлечь элемент определенного типа или класса, используя document.querySelectorAll.
// Этот код возвращает NodeList всех элементов, отвечающих нашему критерию.
var scary = document.querySelectorAll(".monsters");
console.log("Hide and seek champions: ");
for (var i = 0; i < scary.length; i++) {
console.log(scary[i].innerHTML);
}
HTML
<ul>
<li class="monsters">Несси</li>
<li class="monsters">Бигфут</li>
<li class="monsters">Чупакабра</li>
</ul>
3. Установка и удаление обработчиков событий
Обработчики событий являются фундаментальной частью построения веб-приложений. Когда-то существовало два основных лагеря, которые отличались между собой тем, как они работали - IE и остальные. Но сегодня мы просто используем AddEventListener:
JS
var btn = document.querySelectorAll("button"),
list = document.querySelector("ul");
// Мы вызываем метод addEventListener для отслеживания нужного нам события (в данном случае кнопки).
// Этот код запускает обработчик, который ожидает, пока в элементе не будет зафиксирован клик кнопки.
btn[0].addEventListener("click", function () {
// Когда на список наведен курсор мыши, мы хотим включить увеличение списка.
// Для этого мы добавляем обработчик событий непосредственно в список,
// и, когда пользователь наводит на него курсор мыши, вызывается функция увеличения.
list.addEventListener("mouseover", enlarge);
});
// Чтобы отключить увеличение мы можем просто использовать removeEventListener.
btn[1].addEventListener("click", function () {
// Удаление обработчика событий не работает для анонимных функций, так что всегда используйте проименованные функции.
list.removeEventListener("mouseover", enlarge);
});
// Давайте создадим функцию увеличения.
var enlarge = function () {
// Добавляем класс увеличения для маркированного списка.
list.classList.add("zoomed");
// Когда пользователь убирает курсор мыши со списка, он возвращается к нормальному размеру через удаление класса.
list.addEventListener("mouseout", function () {
list.classList.remove("zoomed")
});
};
// Теперь мы хотим окрашивать названия в разные цвета при нажатии на них мышью.
// Когда на одном из элементов списка зарегистрирован 'click', он должен менять свой цвет на зеленый.
// Благодаря делегированию событий мы можем добавить обработчик событий непосредственно ко всему родительскому объекту.
// Таким образом, мы можем не добавлять отдельный обработчик событий к каждому элементу списка <li>.
list.addEventListener("click", function (e) {
// Обеспечиваем, чтобы менялся цвет только выбранного элемента, задавая цель события.
e.target.classList.add('green');
});
HTML
<button>Отключить увеличение</button>
<br><br>
Кликните на любое название, что оно стало зеленого цвета
<ul>
<li>Чюбака</li>
<li>Хан Соло</li>
<li>Люк</li>
<li>Боба Фетт</li>
</ul>
CSS
.green {
color: green;
}
.zoomed {
cursor: pointer;
font-size: 23px;
}
addEventListener применен с третьим аргументом (useCapture), но некоторое время это было опционально. В результате, код выглядит еще больше похожим на JQuery.
4. Действия с классами и атрибутами
Производить действия с именами классов элемента без JQuery раньше было очень неудобно. Благодаря свойству classList теперь это осталось в прошлом. А если вам нужно управлять атрибутами, в вашем распоряжении есть setAttribute:
JS
console.log(classes);
});
btn[2].addEventListener("click", function () {
// Он поддерживает добавление и удаление классов.
classes.add("red");
});
btn[3].addEventListener("click", function () {
// Вы можете также установить переключатель для класса включить/отключить
classes.toggle("hidden");
});
HTML
<div id='myDiv' class="square"></div>
<button>Display id</button>
<button>Display classes</button>
<button>Color red</button>
<button>Toggle visibility</button>
CSS
.square {
width: 100px;
height: 100px;
margin-bottom: 20px;
border: 1px solid grey;
border-radius: 5px;
}
.hidden {
visibility: hidden;
}
.red {
background-color: red;
}
5. Получение и установка содержимого элемента
JQuery имеет удобные методы text() и html(). Вместо них вы можете использовать свойства textContent и innerHTML, которые применяются уже очень давно:
JS
myText.textContent = " Koalas are the best animals ";
});
// Если мы хотим забрать весь HTML-узел (в том числе и теги),мы можем использовать innerHTML.
var myHtml = myText.innerHTML;
console.log("innerHTML: " + myHtml);
// Чтобы заменить html просто предложите новый контент.
// Естественно мы не ограничены в применении текста только этим одним случаем.
btn[1].addEventListener('click', function () {
myText.innerHTML = "<button> Penguins are the best animals </button>";
});
HTML
<p id="myParagraph"><strong> Какое животное самое лучшее? </strong></p>
<button>Коала</button>
<br>
<button>Пингвин</button>
6. Вставка и удаление элементов
Хотя с помощью JQuery это делается намного проще, добавление и удаление элементов DOM возможно и с помощью простого JavaScript. Вот, как можно добавить, удалить и заменить любой элемент, который вы хотите:
JS
// Вставка верхнего слоя:
// Возьмите говядину (это сэндвич) и примените для нее insertBefore.
// Первый аргумент для insertBefore и будет элементом, который мы хотим добавить.
// Второй аргумент будет узлом, перед которым вставляется новый элемент.
beef.parentNode.insertBefore(topSlice, beef);
// Нижний слой:
// Здесь нам придется применить маленькую хитрость!
// Предложите следующий ближайший элемент в качестве второго аргумента для insertBefore,
// таким образом, мы можем осуществить вставку непосредственно после элемента, который нам нужен.
beef.parentNode.insertBefore(bottomSlice, beef.nextSibling);
};
var removePickles = function () {
// Наконец мы хотим избавиться от этих элементов. Это тоже можно сделать с помощью javascript!
HTML
<button>Добавить к ланчу мясо </button>
<button>Добавить в сэндвич сыр</button>
<button>Убрать соленые огурцы</button>
<h3>Мой ланч</h3>
<ul id="lunch">
<li><h4>Мой сэндвич</h4></li>
<li>Хлеб</li>
<li id="pickles">Соленые огурцы</li>
<li id="Beef">Мясо</li>
<li>Майонез</li>
<li>Хлеб</li>
</ul>
7. Переходы по дереву DOM
Каждый истинный JS-ниндзя знает, что в DOM сокрыты огромные возможности. По сравнению с JQuery, простые DOM API предлагают ограниченный набор функций по выборке элементов высшего или одного уровня. Тем не менее, есть еще много вещей, которые вы можете сделать для путешествий по дереву DOM:
JS
snakes.addEventListener('click', function (e) {
// Для того чтобы получить доступ к родительским элементам дерева DOM мы используем метод parentNode .
var parent = e.target.parentNode;
console.log("Parent: " + parent.id);
// И наоборот, вызов метода .children выдает все подчиненные элементы выбранного объекта.
console.log("Children: ");
var children = e.target.children;
// Этот код возвращает HTMLCollection (тип массива), так что мы должны перебрать каждый элемент подчиненного содержимого.
for (var i = 0; i < children.length; i++) {
console.log(children[i].textContent);
}
});
birds.addEventListener('click', function (e) {
HTML
Кликните на объект, чтобы увидеть все его подчиненные элементы
<div id="snakes">
Змеи
<ul id="venomous">
Ядовитые
<li>Кобра</li>
<li>Гремучая змея</li>
</ul>
<ul id="non-venomous">
Не ядовитые
<li>Питон</li>
<li>Анаконда</li>
</ul>
</div>
Кликните на название любой птицы, чтобы увидеть список всех птиц того же вида
<div>
Птицы
<ul id="birds">
<li>Фламинго</li>
<li>Чайка</li>
<li>Ворон</li>
<li>Додо</li>
</ul>
</div>
CSS
div {
color: white;
background-color: #93d0ea;
font-family: sans-serif;
width: 180px;
text-align: center;
padding: 10px;
margin: 5px;
}
8. Обработка массивов через цикл
Некоторые из полезных методов, предоставляемых JQuery, доступны в стандарте ES5. Для перебора массивов, мы можем использовать forEach и map вместо их JQuery версий - each() и map(). Только обратите внимание на различия в аргументах и значении по умолчанию для this в обратных вызовах:
JS
var ninjaTurtles = ["Donatello", "Leonardo", "Michelangelo", "Raphael"];
// ForEach автоматически перебирает массив .
ninjaTurtles.forEach(function (entry) {
console.log(entry);
});
// Метод map вызывает функцию для каждого элемента массива и создает новый массив с результатами обработки.
var lovesPizza = ninjaTurtles.map(function (entry) {
return entry.concat(" loves pizza!");
});
console.log(lovesPizza);
9. Анимация
Метод анимации JQuery превосходен для всего, что вы можете соединить самостоятельно, и если для приложения вам нужны сложные сценарии анимации, вы все равно должны использовать его.
Но благодаря чудесам CSS3 некоторые простые варианты анимации могут быть обработаны с помощью небольшой библиотеки наподобие Animate.css, которая позволяет вызывать для элементов анимацию, добавлять или удалять имена классов:
JS
circle.classList.add('animated');
// Мы перебираем каждую из кнопок и добавляем к каждой обработчик событий.
for (var i = 0; i < btn.length; i++) {
// Здесь определяется анонимная функция, чтобы сделать возможным использование переменной i.
(function (i) {
btn[i].addEventListener('click', function () {
// Чтобы запустить анимацию, вам нужно просто добавить к объекту определенный класс.
// В нашем случае все имена классов содержатся в атрибуте data-animation каждой кнопки.
var animation = btn[i].getAttribute('data-animation');
HTML
<button data-animation="bounce">Bounce</button>
<button data-animation="pulse">Pulse</button>
<button data-animation="fadeInLeftBig">Fade in</button>
<button data-animation="fadeOutRightBig">Fade out</button>
<button data-animation="flip">Flip</button>
<div id="circle"></div>
CSS
body {
text-align: center;
}
#circle {
border-radius: 50%;
margin: 50px auto;
width: 50px;
height: 50px;
background-color: #93d0ea;
}
10. AJAX
AJAX являлся еще одной технологией, с которой не было определенности для разных браузеров. Теперь мы уже можем использовать тот же код везде.
Однако создание экземпляров объектов и отправка AJAX запросов с помощью XMLHttpRequest по-прежнему очень громоздки, так что лучше делать это с помощью библиотеки.
Но вы не обязаны подключать исключительно для этой цели весь JQuery. Вы можете использовать одну из многочисленных легких библиотек. Вот пример построения AJAX запроса напрямую, с помощью небольшой библиотеки reqwest:
JS
// Этот простой пример регистрирует тело url-адреса (html-файл) в консоли.
// В принципе можно вручную выполнить запрос GET, но это несколько утомительное занятие.
var request = new XMLHttpRequest();
request.open('GET', 'http://tutorialzine.com/misc/files/my_url.html', true);
request.onload = function (e) {
if (request.readyState === 4) {
// Проверяем, успешно ли прошло получение данных.
if (request.status === 200) {
console.log(request.responseText);
} else {
console.error(request.statusText);
}
}
};
Заключение
Стремление к минимализму, к веб-странице без лишних наворотов является достойной целью, что принесет вам дивиденды в виде быстрой загрузки и лучшего пользовательского опыта взаимодействия. Но вы должны быть осторожны - никто не выиграет от того, что вы будете вновь изобретать колесо, которое уже изобрел JQuery.
Не жертвуйте полезными практиками исключительно ради малого количества байтов. В то же время есть огромное количество случаев, где эти советы прекрасно применимы. Попробуйте в следующий раз обойтись ваниллой, возможно, вам больше ничего и не понадобится!