Обработка клика вне элемента на JS (и также на jQuery)

Прежде, чем начать, сразу скажу, что в этом уроке вы найдёте две реализации обработки клика вне блока – на чистом JavaScript и на jQuery.

Кроме того, если вы хотить прокачать свои знания в JavaScript, jQuery и даже React.js, то хочу порекомендовать вам свой видеокурс!

Когда бывает нужно скрыть (закрыть) элемент по клику за его пределами? Первое, что мне приходит в голову, это всплывающие (popup) окна и выпадающие (dropdown) меню. Понятное дело, что применение может быть гораздо шире.

Всплывающее окно на jQuery
Попап можно закрыть нажатием на escape или кликнув вне его. Хотя правильнее назвать это модальным окном.

Согласитесь, что намного удобнее осуществлять закрытие модального окна по клику вне окна, чем тащить указатель мыши к крестику и кликать по нему. А в некоторых ситуациях крестик и вовсе использовать не удастся (выпадающие кастомные селекты или меню).

И да, как только люди с этим не шаманят! Решений в интернете полно, но оптимальными их не назовёшь. Самое часто встречающееся из них, это когда скрипт проверяет, находится ли указатель мыши над элементом или нет.

Ну вот зачем усложнять код?

Хотя на самом деле ответ действительно очевиден — разработчики не знают, что можно сделать правильнее и проще, и делают так, как могут. Давайте разберем алгоритм:

  1. У нас открыто всплывающее модальное окно, меню или что-то ещё.
  2. Нам нужно, чтобы оно закрывалось не только на крестик (если таковой вообще имеется), но и по клику где-нибудь за его границами.
  3. Значит нам нужно событие «Когда произошёл клик по странице».
  4. В событие нужно добавить два условия «Если клик был не по нашему элементу» и «Если клик был не по дочерним элементам нашего элемента».
  5. Если оба условия выполняются, скрываем элемент.

Клик вне элемента на чистом JS

const div = document.querySelector( '#popup');
 
document.addEventListener( 'click', (e) => {
	const withinBoundaries = e.composedPath().includes(div);
 
	if ( ! withinBoundaries ) {
		div.style.display = 'none'; // скрываем элемент т к клик был за его пределами
	}
})

И, так как мы всё-же говорили о закрытии модального окна, то я не могу в качестве бонуса не предоставить вам код его закрытия при нажатии на клавишу Escape на клавиатуре.

document.addEventListener('keydown', function(e) {
	if( e.keyCode == 27 ){ // код клавиши Escape, но можно использовать e.key
		div.style.display = 'none';
	}
});

Клик вне элемента jQuery

jQuery(function($){
	$(document).mouseup( function(e){ // событие клика по веб-документу
		var div = $( "#popup" ); // тут указываем ID элемента
		if ( !div.is(e.target) // если клик был не по нашему блоку
		    && div.has(e.target).length === 0 ) { // и не по его дочерним элементам
			div.hide(); // скрываем его
		}
	});
});

Для разнообразия я использовал событие mouseup, т.е. когда кнопка мыши была нажата и уже отпущена. Для данного примера можно ещё добавить событие onclick на крестике, чтобы окно также закрывалось при клике на крестик.

И также в качестве бонуса – закрытие модального окна при нажатии клавиши Escape на клавиатуре:

$(document).on('keyup', function(e) {
	if ( e.key == "Escape" ) {
		$( "#popup" ).hide();
	}
});

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Комментарии — 26

Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал