Нативні еквіваленти jQuery методів – Частина 2: Робота з атрибутами та властивостями
Це друга частина постів, присвячена нативним еквівалентам jQuery методів. Якщо ви пропустили першу частину вибірки DOM елементів, тоді чому ви ще тут? Переходь прямо зараз Частина 1: Вибір DOM елементів або переходь до Частина 3: Обробники подій або Частина 4: Створення, вставка, переміщення та видалення елементів.
У цій частині ми розглянемо маніпуляції з властивостями та атрибутами – включаючи імена класів та data-* атрибутів.
Нагадаю, що атрибути задаються за допомогою HTML, а властивості належать до DOM. Оскільки DOM елементи – це об’єкти, як і будь-які інші JavaScript об’єкти у них є властивості, і вони можуть бути будь-якого типу (рядок, бульова, функції і т.д.), в той час як атрибути можуть бути лише рядками.
Отже, щоб змінити властивість DOM елемента ви можете отримати або задати його або за допомогою точки (dot notation) або квадратних дужок, якщо необхідно.
// get
elem.property // or elem[propery]
// set
elem.property = 'some value'; // or elem[propery] = 'some value'
Наприклад, щоб задати елементу властивість ID:
jQuery
// get
$(elem).prop('id');
// set
$(elem).prop('id', 'myID');
Нативний JS
// get
elem.id;
// set
elem.id = 'myID';
Отримання атрибутів
jQuery
$(elem).attr(name);
Нативний JS
elem.getAttribute(name);
Завдання атрибутів
jQuery
$(elem).attr(name, value);
Нативний JS
elem.setAttribute(name, value);
Видалення атрибутів
jQuery
$(elem).removeAttr(name);
Нативний JS
elem.removeAttribute(name);
Пам’ятайте, jQuery працює з одним або колекціями елементів. Якщо ви працюєте з колекцією, яку повернули власні методи, як getElementsByClass
, querySelectorAll
і т.д., ви повинні пройти циклом і отримати/задати/видалити атрибути окремо.
var elems = document.querySelectorAll('.my-class');
for (i = 0; i < elems.length; ++i) {
elems[i].setAttribute(name, value);
}
І хоча набагато інформативніший, ніж jQuery метод, рідні методи, як правило, набагато швидше jsPerf.
Перевірка існування атрибутів
Що найцікавіше, jQuery не має методу для перевірки елемента на певний атрибут, поки рідного методу не існує.
jQuery
var attr = $(elem).attr(name);
// attr() can return undefined or false depending on the browser
if (typeof attr !== typeof undefined && attr !== false) {
// elem has the attribute specified
}
Нативний JS
var attr = elem.hasAttribute(name); // returns a boolean
if ( attr ) {
// elem has the attribute specified
}
Додатково прочитати: getAttribute, setAttribute, removeAttribute, hasAttribute
Задання імені класу
jQuery
$(elem).addClass('my-class');
Нативний JS
// for old browsers
elem.className = 'my-class'
// or if you don't want to overwrite the currently set classNames
elem.className += ' my-class'
// for not-so-old-browsers
elem.setAttribute('class', 'my-class');
Отримання імені класу
jQuery
$(elem).attr('class');
Нативний JS
elem.className
Видалення імені класу
jQuery
$(elem).removeClass('my-class');
Нативний JS
Ось тут він виходить брудним, якщо ви підтримуєте IE <10, неіснуючий рідний метод видалення окремого класу, якщо елемент має більше одного набору.
Якщо вам необхідно підтримувати старі браузери, і ви впевнені, що є лише один заданий клас на елементі, використовуйте наступне:
elem.className = '';
// or
elem.removeAttribute('class');
В іншому випадку можливо ви захочете використати деякий рядковий збіг:
var classToRemove = 'some-class';
elem.className = elem.className.replace(new RegExp("(^|\\s)" + classToRemove.split(" ").join("|") + "(\\s|$)", "gi"), " ")
Якщо ви не підтримуєте IE <10, можете використати сучасний classList
API. classList
має add
, remove
, toggle
, contains
і item
методи.
add
// add a specified class
elem.classList.add('my-class')
Метод add
лише додає клас, якщо він відсутній.
remove
// remove a specified class
elem.classList.remove('my-class')
toggle
// toggle a specified class
elem.classList.toggle('my-class')
Цей метод toggle
буде видаляти клас, якщо він існує, або додав його, якщо його немає.
contains
// check the element has the specified class
elem.classList.contains('my-class') // returns a boolean
Додатково прочитати: classList
HTML5 Data атрибути (data-*)
jQuery
// get
$(elem).attr('data-something')
// or
$(elem).data('data-something')
// set
$(elem).attr('data-something', 'some-value')
// or
$(elem).data('data-something', 'some-value')
Переконайтеся, що ви знаєте про підводні камені, при отриманні та завданні за допомогою jQuery
data()
методу.
Нативний JS
// get
elem.getAttribute('data-something')
// set
elem.setAttribute('data-something')
Набір даних властивостей доступний для сучасних браузерів (IE 11+). Ви можете отримати та задати data-* атрибути легко, але врахуйте, що data-
шматочок видаляється, а решта пишеться в camelCase («Верблюжої» нотацією), тому data-some-attribute
перетвориться на someAttribute
.
Приклад:
<div class="some-class" data-my-custom-attr="some-value"></div>
// get
elem.dataset.myCustomAttr
// set
elem.dataset.myCustomAttr = 'new-value';
// check
if ( 'myCustomAttr' in elem.dataset ) {
// elem has the attribute 'data-my-custom-attr'
}
Додатково прочитати: dataset
Підтримка нових та старих браузерів
Іноді з’являється непросте завдання, необхідно підтримувати старі браузери, варто створювати свої власні допоміжні функції, щоб вони брали на себе цей головний біль. Існує купа рішень та поліфілів, їх можна знайти в інтернеті, але є ті, які я регулярно використовую для маніпуляцій із іменами класів. Вони перевіряють на наявність classList
API і використовують його, в іншому випадку вони використовують методи, що підтримуються старими браузерами.
var hasClass = function(elem,className) {
return elem.classList ? elem.classList.contains(className) : !!elem.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
}
var addClass = function(elem, className) {
elem.classList ? elem.classList.add(className) : hasClass(className) || (elem.className = elem.className.trim() + " " + className)
};
var removeClass = function(elem, className) {
elem.classList ? elem.classList.remove(className) : hasClass(className) && (elem.className = elem.className.replace(new RegExp("(^|\\s)" + className.split(" ").join("|") + "(\\s|$)", "gi"), " "))
};
Застосування
// add a class
addClass(myElem, 'some-class');
// remove a class
removeClass(myElem, 'some-class');
// check a class exists
if (hasClass(myElem, 'some-class') {
// myElem has the class 'some-class'
}
Ось і все для цієї частини. Настройтесь наступного разу, коли ми розглянемо рідні варіанти обробників подій, як click()
, on()
, hover()
і т.д., і поринемо в делегування подій.