Построить цепочечную обёртку $ в стиле jQuery над несколькими DOM-узлами
Реализуйте помощник $(selector), возвращающий обёртку, чьи методы цепляются по всем найденным узлам: $('.item').addClass('on').css({ color: 'red' }).html('<b>hi</b>'). Сделайте addClass(c), removeClass(c), css(obj) и html(s), каждый применяется ко ВСЕМ найденным элементам и каждый возвращает обёртку для цепочки. Выбор через querySelectorAll.
const $ = (selector) => new DomWrapper(selector);
class DomWrapper {
constructor(selector) {
this.elements = document.querySelectorAll(selector);
}
addClass(c) {
// ваш код здесь
}
}
Допишите реализацию.
Сохранить результат querySelectorAll на экземпляре. Каждый метод проходит по this.elements, применяя изменение — classList.add/remove, Object.entries(obj) в el.style, el.innerHTML = s — затем делает return this, чтобы обёртка цеплялась. Методы живут один раз на прототипе класса, а не пересоздаются на каждый элемент, и один вызов разводит операцию по всему найденному набору.
- ✗Использовать
querySelector(один узел), когда API должен работать со всеми найденными элементами - ✗Забывать
return this, из-за чего у второго метода цепочки нет обёртки для вызова - ✗Пересоздавать обёртку или методы на каждый элемент вместо однократного определения в классе
- →Почему обёртка-класс эффективнее возврата свежего объекта методов на каждый вызов
$()? - →Как
return thisнад списком узлов позволяет одним вызовом развести операцию по многим элементам?
Решение
Класс хранит список узлов; каждый метод проходит по ним и возвращает this.
const $ = (selector) => new DomWrapper(selector);
class DomWrapper {
constructor(selector) {
this.elements = document.querySelectorAll(selector);
}
addClass(c) {
for (const el of this.elements) el.classList.add(c);
return this;
}
removeClass(c) {
for (const el of this.elements) el.classList.remove(c);
return this;
}
css(obj) {
for (const el of this.elements) {
for (const [k, v] of Object.entries(obj)) el.style[k] = v;
}
return this;
}
html(s) {
for (const el of this.elements) el.innerHTML = s;
return this;
}
}
$('.item').addClass('on').css({ color: 'red' }).html('<b>hi</b>');
Как это работает
$() создаёт один экземпляр DomWrapper, который запоминает результат querySelectorAll — все совпавшие узлы. Каждый метод проходит по this.elements и применяет изменение к каждому, после чего возвращает this. Возврат той же обёртки и есть механизм цепочки: следующий вызов работает с тем же набором узлов.
Обёртка-класс эффективнее, чем возвращать на каждом вызове $() новый объект с методами: методы заданы один раз на прототипе DomWrapper, а не пересоздаются. Один вызов вроде addClass разводит операцию сразу по всем найденным элементам.