Головна функція jQuery
Основна задача jQuery - пошук елементів в DOM і робота з ними.
Пошук елементів здійснюється по селектору:
$(селектор).метод();
$('#content .box').html('Hello!');
$('menu > li:first-child > a').css('color', 'red');
jQuery майже повністю складається з функцій, є лише декілька властивостей, найчастіше вживаніша - length.
Все, що знаходить функція по селектору - це jQuery-набір елементів. Навіть якщо ми шукаємо один елемент по ідентифікатору. Навіть якщо серед багатьох елементів вибираємо один, це все одно буде масив з одного елемента. Якщо ж на сторінці не буде знайдено цього елемента - буде повернено порожній jQuery-набір, у якого length === 0.
console.dir($('p'));
console.dir($('p').eq(0));
console.dir($('h1'));
console.dir($('.hello'));
Масив цей - специфічний, він є обгорткою до колекції елементів js.
var p = document.getElementsByTagName('p');
$(p) - jQuery-набір абзаців
$(document.body) - jQuery-набір з одного елемента body
$(window) - jQuery-window
Давайте напишемо свою подібну функцію:
function $$(selector){
return document.querySelectorAll(selector);
}
$$('nav menu li').forEach(...);
Функція в javascript - це також об'єкт, вона може мати властивості і методи. Розберіть наступний код та виконайте його в консолі:
function hello(){ alert('hello'); }
hello.hey = function(){ alert(this.ho); };
hello.ho = 'ho-ho-ho';
hello();
hello.hey();
Функції jQuery можна застосовувати тільки до jQuery-наборів і не можна - до елементів JS.
Ще одна особливість jQuery - ланцюжки викликів (або колбасіни викликів, сардельки :).
Ви можете до одного і того ж елемента застосувати декілька методів:
$('a.active').removeClass('active').css('color', 'blue')
.attr('href', '#').children('span').addClass('uncative').hide();
Зверніть увагу, що методи застосовують модифікації до всього набору елементів, не потрібно робити перебір.
Ланцюжки викликів можливо застосовувати тому що більшість методів повертає те, що приходить на вхід функції:
jQuery.fn.addClass(function(cls){
this.forEach(function(elem){
elem.classList.add(cls);
});
return this;
});
Екскурс в історію
Щоб зрозуміти чому "взлетіла" і чому останнім часом втрачає популярність бібліотека jQuery, розгляньте код добавляння класу active до елементів div.box до 2012 року (підтримка IE8-), новий варіант (ie10+) і з використанням jQuery:
let boxes = document.getElementsByTagName('div');
for (var i = 0; i < boxes.length; i++) {
var classes = boxes[i].className.split(' ');
for (var j = 0; j < classes.length; j++) {
if (classes[j] == 'box') {
addClass(boxes[i], 'active');
break;
}
}
}
function addClass(elem, className) {
var classes = elem.className.split(' ');
var double = false;
for (var i = 0; i < classes.length; i++) {
if (classes[i] == className) {
double = true;
break;
}
}
if (!double) {
classes.push('className');
elem.className = classes.join(' ');
}
}
document.querySelelectorAll('.box').forEach(function(box){
box.classList.add('active');
});
$('.box').addClass('active');
Збереження елементів у змінні
Не завжди можна обійтися одним ланцюжком викликів. Буває, що знайдені елементи потрібно використати декілька разів у різних частинах коду.
Вважається поганою практикою робити повторні пошуки елементів, зайвий раз заставляти JS оббігати все дерево DOM в пошуку потрібних тегів, тому намагаємося робити чистий код, з мінімумом повторів пошуку. Адже кожний $(...) - це виклик функції.
Серед розробників є негласна домовленість - змінну з результатом пошуку починати з символа долара, цим ми говоримо, що у змінній зберігається jQuery-набір:
let p = document.getElementsByTagName('p');
let $p = $('p');
console.dir(p);
console.dir($(p));
console.dir($p);
console.dir($p[0]);
console.dir($p.get(0));
console.dir($p.eq(0));