Как закрыть модальное окно при клике вне блока
Перейти к содержимому

Как закрыть модальное окно при клике вне блока

  • автор:

Создаем кастомный хук useOutsideClick на React.js

Веб-приложения неизбежно имеют множество интерактивных элементов, и часто требуется взаимодействовать с элементами при нажатии вне их области. Возможно, вы заметили, что некоторые люди зависают в таком состоянии, когда они не знают, как закрыть модальное окно на сайте, что является плохим пользовательским опытом. Эта статья поможет вам понять, как создать свой собственный хук useOutsideClick , который можно использовать для закрытия интерактивных элементов при клике вне их области.

Что такое хуки React?

Хуки или hooks — это специальная функциональность в React, которая позволяет использовать state и другие возможности React внутри функциональных компонентов. Как правило, общий стейт React определяется в компонентах и передается в каждый дочерний компонент через пропсы. Однако, хуки позволяют использовать state и otrasную функциональность без необходимости выполнения этих действий через пропсы, что упрощает процесс разработки.

Как мы можем использовать кастомные хуки?

React предоставляет несколько хуков, которые используются для различных целей, например, useState для управления состоянием или useEffect для внедрения выполняемых на клиенте действий. Однако, React также позволяет создавать собственные хуки, которые можно использовать вместе с другим компонентом. Мы создадим свой кастомный хук, который будет использоваться для закрытия окна при клике вне его области.

Создание хука useOutsideClick

Первым шагом является создание кастомного хука, который будет использоваться для определения клика за пределами определенной области. Мы будем использовать useRef для создания ссылки на элемент, который должен проверяться при клике вне его области.

import < useState, useEffect, useRef >from 'react'; const useOutsideClick = (initialValue) => < const [isActive, setIsActive] = useState(initialValue); const ref = useRef(null); const handleClick = (e) => < if (ref.current && !ref.current.contains(e.target)) < setIsActive(!isActive); >>; useEffect(() => < document.addEventListener("click", handleClick); return () =>< document.removeEventListener("click", handleClick); >; >); return < ref, isActive, setIsActive >; >; export default useOutsideClick;

В коде выше мы создали хук useOutsideClick , который принимает начальное значение initialValue. Хук создает state isActive, который отслеживает текущее состояние активности, а также ref для ссылки на элемент, а также setIsActive для изменения состояния активности. Мы также создали функцию handleClick, которая проверяет, кликнул ли пользователь за пределами элемента ref. И если клик был выполнен вне области, то изменяется isActive.

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

Применение нашего хука useOutsideClick

После создания нашего хука, мы можем использовать его в любом компоненте, где нужно обнаружить клик внутри или за пределами элемента. Мы можем использовать полученный объект, вернувшийся функциейхука, и использовать его в соответствии с потребностями нашего компонента.

import useOutsideClick from './useOutsideClick'; function SomeComponent() < const < ref, isActive, setIsActive >= useOutsideClick(false); const handleButtonClick = () => < setIsActive(!isActive); >; return ( 
> Here is some content. Clicking outside of this content will close it.
)>
); >

Мы использовали хук useOutsideClick внутри компонента SomeComponent . В этом компоненте мы создали элемент кнопки, который является отправной точкой для изменения состояния isActive. Каждый раз, когда мы кликаем на кнопку, isActive будет изменяться, и определенная область, которую мы определили с помощью ссылки на ref, будет спрятана или показана. Хук useOutsideClick помогает нам закрыть область, если вызов клика осуществляется не на определенной области.

Вывод

Мы реализовали кастомный хук useOutsideClick , который может быть использован для закрытия любого интерактивного элемента при клике вне его области. Мы использовали useRef, useState, и useEffect хуки из React библиотеки, чтобы создать хук, который легко использовать в любом компоненте React.

#React #JavaScript #Хуки #КастомныеХуки #useOutsideClick

Курсы javascript

Вот код, который по клику на зелёном блоке div.page вызывает появление модального окна (салатовый блок по центру) с «затенением» серого цвета вокруг. Мне нужно, чтобы модальное окно и затенение исчезали при клике мыши по серому «затенению». Код JS написал, но не почему-то оно не работает (исчезновение). Подскажите, пожалуйста, что нужно исправить. Нужно сделать на чистом JS, я новичок в этом.

.page < position: relative; width: 400px; height: 500px; background-color: seagreen; >.shim-modal-content < display: none; position: fixed; width: 100%; height: 100%; background-color: grey; >.modal-content-window < position: absolute; top: 50%; left: 50%; width: 300px; height: 350px; transform: translate(-50%, -50%); background-color: lightgreen; >.shim-modal-show

var page = document.querySelector(".page"); var shimModalContent = document.querySelector(".shim-modal-content"); page.addEventListener("click", function()< shimModalContent.classList.add("shim-modal-show"); >); shimModalContent.addEventListener("click", function()< shimModalContent.classList.remove("shim-modal-show"); >);

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

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

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

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

Всплывающее окно на jQuery

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

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

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

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

  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. Преподаватель в школе Нетология.

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

Как закрыть модальное окно при клике вне него?

Есть у меня модальное окно (всё в конце), которое нормально открывается / закрывается при вызове функции. Но надо, чтобы окно закрывалось при клике вне окна (затемненный фон), а если я на него накидываю функцию закрытия окна, то при клике по окну оно закрывается (я так понял из-за того, что окно является дочерним элементом). как это реализовать?

 
Суперкрутой текст, вообще что угодно
function closeModal() < $('.modal-body').stop().animate(< marginTop: '-100%', >, 300, function()< $('.modal').animate(< opacity : 0 >, 200, function()< $('.modal').css(< 'display':'none' >); $('.modal-body').css(< 'marginTop':'100%' >); $('body').css("overflow", "auto"); >); >); > function showModal() < $('.modal').css("display", "flex"); $('body').css("overflow", "hidden"); $('.modal').animate(< opacity: '100%', >, 150, function() < $('.modal-body').animate(< marginTop: 0 >, 200); >); > 

PS изначально задано opacity: 0, а для modal-body: margin-top: 100%, сначала показывается фон, потом снизу выплывает окно

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *