Головна функція 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));