Селектор $(this) в jQuery: мощные приемы доступа к элементам DOM
Для кого эта статья:
- Веб-разработчики, стремящиеся улучшить свои навыки в jQuery
- Студенты и начинающие программисты, изучающие работу с DOM-элементами
Практикующие разработчики, желающие оптимизировать свой код и повысить производительность приложений
Работа с DOM-элементами часто становится головной болью для веб-разработчиков, особенно когда нужно манипулировать множеством вложенных элементов. В мире jQuery селектор
$(this)— это ваш надёжный компас в навигации по документу. Владение этим инструментом позволяет писать элегантный и производительный код без лишних селекторов и переменных. Давайте разберёмся, как$(this)превращает сложные манипуляции с дочерними элементами в изящные однострочные решения, и почему это критически важный навык для каждого jQuery-разработчика. 🚀
Осваиваете jQuery и хотите научиться эффективно управлять DOM-элементами? Обучение веб-разработке от Skypro погружает вас в практику работы с jQuery и современным JavaScript. Вы не просто изучите методы работы с
$(this), а научитесь писать чистый, производительный код для реальных проектов под руководством практикующих разработчиков. Станьте экспертом в DOM-манипуляциях и повысьте ценность на рынке труда!
Основы работы с селектором
Ключевой особенностью jQuery является работа с ключевым словом this в обработчиках событий. Когда происходит событие, this указывает на DOM-элемент, который инициировал событие. Чтобы воспользоваться всей мощью jQuery, мы оборачиваем this в jQuery-объект с помощью $(this).
Рассмотрим базовый пример:
$('.item').on('click', function() {
$(this).addClass('active'); // $(this) ссылается на кликнутый .item
console.log($(this).html()); // выводит HTML кликнутого элемента
});
В этом примере $(this) представляет элемент, на котором произошло событие клика, что позволяет нам манипулировать конкретно этим элементом, не затрагивая другие.
Алексей Воронов, Senior Frontend Developer
Во время работы над крупным банковским порталом я столкнулся с непредвиденной проблемой. У нас было около 50 однотипных карточек услуг, каждая со своим выпадающим меню. Изначально я привязал обработчик к ID каждой карточки, что привело к дублированию кода и сложностям с поддержкой.
Решение пришло с пониманием правильного использования
$(this). Мы переписали код, используя единый обработчик для всех карточек:$('.service-card .toggle-btn').on('click', function() { $(this).closest('.service-card') .find('.dropdown-menu') .slideToggle(); });Это уменьшило объем кода на 70% и сделало его гораздо более поддерживаемым. Самое важное — мы смогли динамически добавлять новые карточки без необходимости писать для них отдельные обработчики.
Важно понимать контекст, в котором используется $(this). В разных случаях он может ссылаться на разные элементы:
| Контекст использования | На что ссылается $(this) | Пример кода |
|---|---|---|
| Обработчик события | Элемент, вызвавший событие | $('.btn').click(function() { $(this) /* кнопка */ }); |
| Метод .each() | Текущий элемент итерации | $('li').each(function() { $(this) /* текущий li */ }); |
| Метод .map() | Текущий элемент маппинга | $('p').map(function() { return $(this).text(); }); |
| Глобальная область | Глобальный объект (window) | console.log($(this)); // [window] |
При работе с $(this) необходимо помнить о сохранении контекста, особенно при использовании вложенных функций или стрелочных функций в ES6:
$('.container').on('click', function() {
// Сохраняем $(this) в переменную
const $container = $(this);
// Используем во вложенных функциях
$.ajax({
url: '/data',
success: function(data) {
$container.find('.content').html(data);
// Здесь $(this) уже НЕ ссылается на .container!
}
});
});

Получение дочерних элементов методом children()
Метод .children() — один из самых эффективных способов получения прямых дочерних элементов в jQuery. Он работает только на один уровень вложенности, выбирая непосредственных потомков элемента.
$('.parent').on('click', function() {
// Получаем всех прямых потомков
$(this).children().css('color', 'red');
// Получаем прямых потомков с классом .highlight
$(this).children('.highlight').css('font-weight', 'bold');
});
Ключевое преимущество .children() — производительность. Этот метод работает быстрее, чем .find(), когда вам нужны только элементы первого уровня вложенности.
Метод поддерживает уточняющий селектор в качестве аргумента, что позволяет фильтровать дочерние элементы:
// Получить только дочерние элементы с классом active
const $activeChildren = $(this).children('.active');
// Получить только дочерние элементы определенного типа
const $paragraphs = $(this).children('p');
Рассмотрим несколько практических применений .children():
- Переключение состояний UI элементов (например, табов)
- Изменение стилей элементов одного уровня вложенности
- Быстрое итерирование по элементам списка
- Управление панелями навигации и меню
Пример с табами показывает, как эффективно использовать .children():
$('.tab-headers').on('click', '.tab', function() {
// Удаляем активный класс у всех табов
$(this).parent().children().removeClass('active');
// Добавляем активный класс кликнутому табу
$(this).addClass('active');
// Показываем соответствующий контент
const index = $(this).index();
$('.tab-content').children().hide()
.eq(index).show();
});
Важно отметить случаи, когда использование .children() может быть не лучшим выбором:
- Когда требуется доступ к элементам на разных уровнях вложенности
- При неизвестной или изменчивой структуре DOM
- Когда нужны текстовые узлы (для них лучше использовать
.contents())
Поиск вложенных элементов через метод find() в jQuery
Когда .children() ограничивается только прямыми потомками, метод .find() открывает доступ ко всем вложенным элементам на любом уровне глубины. Это делает .find() исключительно мощным инструментом для навигации по сложным DOM-структурам.
$('.container').on('click', function() {
// Находит все элементы .item внутри контейнера на любом уровне вложенности
$(this).find('.item').addClass('selected');
// Находит все span внутри параграфов
$(this).find('p span').css('color', 'blue');
});
Ключевое отличие .find() от .children() — это возможность "глубокого поиска". Метод .find() использует нативный метод querySelectorAll() браузера, что делает его высокооптимизированным при поиске по селекторам.
Марина Ковалева, Frontend Team Lead
При разработке CMS для контент-менеджеров нашей компании мы столкнулись с интересной задачей. В редакторе была возможность создавать вложенные списки неограниченной глубины, и нужно было реализовать функцию быстрого форматирования текста.
Изначально мы попытались использовать цепочку вызовов
.children()для работы с разными уровнями, но код становился запутанным:$(this).children('ul').children('li').children('ul')...Решение оказалось элегантным благодаря методу
.find():$('.format-button').on('click', function() { const formatType = $(this).data('format'); $('#editor').find('li span:contains("важно")').each(function() { if (formatType === 'highlight') { $(this).wrap('<strong class="highlight"></strong>'); } else if (formatType === 'note') { $(this).closest('li').addClass('note-item'); } }); });Это позволило создать гибкий инструмент форматирования, который мог работать с контентом любой вложенности. Наши контент-менеджеры были в восторге от такой возможности, а производительность осталась на высоком уровне даже при работе с большими документами.
Метод .find() особенно полезен в следующих случаях:
- Когда структура DOM имеет много уровней вложенности
- При работе с динамически генерируемым контентом
- Для поиска по конкретным селекторам внутри большого контейнера
- При реализации поведения делегирования событий
Пример практического использования .find() с делегированием событий:
// Делегирование событий с использованием .on() и .find()
$('#product-list').on('click', '.product-item', function() {
// Находим и скрываем все открытые описания в списке продуктов
$('#product-list').find('.product-description:visible').slideUp();
// Находим и показываем описание в кликнутом элементе
$(this).find('.product-description').slideDown();
});
При работе с .find() стоит помнить о следующих аспектах:
| Аспект | Описание | Рекомендация |
|---|---|---|
| Производительность | Медленнее чем .children() при поиске на первом уровне | Использовать .children() для непосредственных потомков |
| Селекторы | Поддерживает все селекторы CSS | Использовать оптимизированные селекторы (по ID, классу) |
| Пустой результат | Возвращает пустой набор jQuery, если элемент не найден | Проверять длину результата перед использованием |
| Цепочки методов | Идеально подходит для цепочек методов | Комбинировать с другими методами для компактности кода |
Выбор непосредственных и всех дочерних элементов
При разработке сложных интерфейсов часто возникает необходимость выбирать как непосредственных потомков, так и элементы на разных уровнях вложенности. Правильный выбор метода может значительно повлиять на производительность и чистоту кода.
Давайте сравним основные методы для работы с дочерними элементами в jQuery:
| Метод | Описание | Уровни вложенности | Селекторы | Особенности |
|---|---|---|---|---|
.children() | Прямые потомки | Только 1-й уровень | Опционально | Не включает текстовые узлы |
.find() | Все потомки | Все уровни | Обязательно | Глубокий поиск по DOM |
.contents() | Прямые потомки | Только 1-й уровень | Не поддерживает | Включает текстовые узлы и комментарии |
Child selector (>) | Прямые потомки через CSS | Только 1-й уровень | CSS синтаксис | Работает на этапе выбора |
Для работы с непосредственными потомками, особенно когда вам нужно получить доступ к текстовым узлам, метод .contents() может быть очень полезен:
// Оборачиваем каждое слово в span в параграфе
$('p').on('click', function() {
$(this).contents().each(function() {
if (this.nodeType === 3) { // текстовый узел
const words = $(this).text().split(' ');
const wrapped = words.map(word => `<span class="word">${word}</span>`).join(' ');
$(this).replaceWith(wrapped);
}
});
});
При работе с непосредственными потомками через селекторы, часто используется комбинированный подход с CSS-селектором дочернего элемента:
// Выбор непосредственных потомков при инициализации
$('.parent > .child').css('border', '1px solid red');
// Аналог через .children()
$('.parent').children('.child').css('border', '1px solid blue');
Когда требуется работать с элементами на разных уровнях вложенности, можно комбинировать методы для более точного выбора:
// Комбинирование методов для сложной навигации
$('.dropdown').on('click', function() {
// Получаем непосредственных потомков с классом item
const $items = $(this).children('.item');
// Находим все вложенные ссылки внутри активных элементов
const $activeLinks = $items.filter('.active').find('a');
// Работаем с результатами
$items.toggleClass('visible');
$activeLinks.addClass('highlighted');
});
При выборе метода для получения дочерних элементов, следует руководствоваться следующими рекомендациями:
- Используйте
.children()когда нужны только непосредственные потомки и производительность критична - Применяйте
.find()когда структура вложенности неизвестна или вам нужны элементы на разных уровнях - Выбирайте
.contents()когда работаете с текстовыми узлами или содержимым iframe - Комбинируйте методы для более сложных сценариев выбора элементов
Практические сценарии использования
Теория хороша, но реальная ценность $(this) раскрывается в практических сценариях. Рассмотрим несколько типичных задач, где комбинация $(this) с методами навигации по DOM позволяет создавать элегантные решения. 🛠️
1. Реализация аккордеона
$('.accordion-header').on('click', function() {
// Находим ближайший родительский элемент
const $item = $(this).closest('.accordion-item');
// Скрываем все открытые панели
$('.accordion-item').not($item).removeClass('active')
.find('.accordion-body').slideUp();
// Переключаем текущую панель
$item.toggleClass('active');
$(this).next('.accordion-body').slideToggle();
});
2. Динамическая фильтрация списка
$('.filter-buttons button').on('click', function() {
// Удаляем активное состояние у всех кнопок
$(this).siblings().removeClass('active');
// Активируем текущую кнопку
$(this).addClass('active');
// Получаем значение фильтра
const filterValue = $(this).data('filter');
// Применяем фильтрацию
if (filterValue === 'all') {
$('.item').show();
} else {
$('.item').hide();
$(`.item[data-category="${filterValue}"]`).show();
}
});
3. Навигация по табам с вложенными элементами
$('.tab-nav li').on('click', function() {
// Получаем индекс таба
const tabIndex = $(this).index();
// Активируем текущий таб и деактивируем остальные
$(this).addClass('active').siblings().removeClass('active');
// Показываем соответствующий контент таба
$('.tab-content > div')
.eq(tabIndex).fadeIn()
.siblings().hide();
// Обновляем вложенные элементы активного таба
const $activeTab = $('.tab-content > div').eq(tabIndex);
$activeTab.find('.sub-item').addClass('highlight');
// Инициализируем карусель внутри активного таба, если она есть
$activeTab.find('.carousel').each(function() {
$(this).slick('reinit');
});
});
4. Динамическая форма с зависимыми полями
$('.dynamic-form select[name="category"]').on('change', function() {
const category = $(this).val();
const $form = $(this).closest('form');
// Скрываем все зависимые поля
$form.find('.dependent-field').hide();
// Показываем нужные поля в зависимости от выбора
if (category) {
$form.find(`.dependent-field[data-parent="${category}"]`).show();
// Сбрасываем значения скрытых полей
$form.find('.dependent-field:hidden').find('input, select').val('');
}
});
5. Таблица с сортировкой и редактируемыми ячейками
// Сортировка при клике на заголовок
$('.sortable-table th').on('click', function() {
const column = $(this).data('column');
const $table = $(this).closest('table');
const $tbody = $table.find('tbody');
const direction = $(this).hasClass('asc') ? 'desc' : 'asc';
// Сбрасываем направление сортировки для всех колонок
$table.find('th').removeClass('asc desc');
$(this).addClass(direction);
// Сортируем строки
const rows = $tbody.find('tr').get();
rows.sort(function(a, b) {
const aValue = $(a).find(`td[data-column="${column}"]`).text();
const bValue = $(b).find(`td[data-column="${column}"]`).text();
return direction === 'asc' ? aValue.localeCompare(bValue)
: bValue.localeCompare(aValue);
});
// Добавляем отсортированные строки обратно в таблицу
$.each(rows, function(index, row) {
$tbody.append(row);
});
});
// Редактирование ячеек таблицы
$('.editable-table td[contenteditable="true"]').on('focus', function() {
// Сохраняем исходное значение
$(this).data('original', $(this).text());
}).on('blur', function() {
const newValue = $(this).text();
const originalValue = $(this).data('original');
// Если значение изменилось, отправляем на сервер
if (newValue !== originalValue) {
const rowId = $(this).closest('tr').data('id');
const column = $(this).data('column');
$.ajax({
url: '/update',
data: { id: rowId, column: column, value: newValue },
success: function() {
$(this).addClass('updated');
}
});
}
});
Эти примеры демонстрируют, как $(this) в сочетании с методами навигации по DOM позволяет создавать интерактивные интерфейсы с минимальным количеством кода. Ключевые преимущества такого подхода:
- Модульность — каждый компонент работает независимо от других
- Производительность — поиск элементов ограничен конкретным контекстом
- Поддерживаемость — код легче читать и модифицировать
- Масштабируемость — компоненты можно дублировать на странице без конфликтов
При работе с реальными проектами рекомендуется:
- Кэшировать результаты частых операций
$(this)в переменные для повышения производительности - Использовать делегирование событий для динамически создаваемых элементов
- Комбинировать методы
.children()и.find()в зависимости от структуры DOM - Применять цепочки методов для компактности и читаемости кода
- Проверять существование элементов перед выполнением операций (
.length)
Овладение техниками работы с
$(this)и методами навигации по DOM — это навык, отделяющий начинающего jQuery-разработчика от профессионала. Вместо создания сложных селекторов или множества переменных, вы можете работать контекстно, создавая компоненты, которые элегантно взаимодействуют с любым окружением. Помните: хороший код не тот, который невозможно улучшить, а тот, который выполняет задачу эффективно и понятно. Правильное использование$(this)с методами.children()и.find()— яркий пример такой эффективности. 🏆