Окончательное решение для раскрывающегося меню «щелкните снаружи, чтобы закрыть»

внешний интерфейс React.js
Окончательное решение для раскрывающегося меню «щелкните снаружи, чтобы закрыть»

Сценарий: проект React.

Вообще говоря в Интернете при возникновении такой проблемы:

  1. Добавьте к элементу Dom метод, который щелкает, чтобы открыть раскрывающееся меню.e.stopPropagation()предотвращение всплытия событий
  2. Затем добавьте событие клика в документ:

    document.addEventListener('click', this.offDropMenu, false)

Однако это, как правило, применимо только к обычным раскрывающимся меню навигации.Нажатие на меню будет переключать страницы, а затем меню исчезнет, ​​например:

Но когда вы сталкиваетесь с таким сложным меню, что вам следует делать, если вы не хотите, чтобы меню исчезало, когда пользователь щелкает внутри меню?


В том же сообщении в Интернете снова будет сказано: добавьте addEventListener в самый внешний Div раскрывающегося меню, чтобы прослушивать событие click, и напишите в событии только один e.stopPropagation().


Действительно, нажатие внутри меню не прыгает, а события внутри все блокируются!

Нет реакции на клики...

Должен ли я добавлять стоп-пузырьки к каждому дочернему элементу?

Я долго думал над этим🤔, и придумал очень примитивный и жестокий метод, который заключается в том, чтобы избегать меню в соответствии с положением клика мыши😂

(⚠️Этот код может причинить дискомфорт Великому Богу~)

Затем посмотрите на функцию и сделайте бизнес-требование, это то, что вы ставите.

До одного дня я обнаружил, что элемент DOM имеет родной методcontains()Просто чтобы убедиться, что узел является потомком другого узла, верните логическое значение:

document.documentElement.contains(document.body)  // true

Это просто волшебство! Это относится только к этой сцене, независимо от того, булькаете вы или нет:


Но также столкнулся с проблемой, то есть e.stopPropagation() не может предотвратить пузырение.


Ссылаться наСистема событий React, если по какой-то причине вы хотите использовать нативные события браузера, вы можете использоватьnativeEventприобретение имущества.

e.nativeEvent.stopImmediatePropagation() можно заменить на e.stopPropagation() для достижения эффекта.

Теперь введите ссылку разведки, после просмотра данных сделаны следующие выводы:
1. Чтобы повысить эффективность, React делегирует события документу, поэтому e.stopPropagation() не потому, что не может предотвратить всплытие, а когда он прекращает всплывать, событие было передано в документ, и ничто не может его остановить. Вы можете интуитивно понять это, привязав alert(3) к document.body, 3 появляется перед 1.
2. e.stopPropagation() не работает. Браузер поддерживает хорошую вещь. e.stopImmediatePropagation() не только предотвращает всплытие, но и предотвращает запуск других событий на текущем элементе, вызывающем событие. Таким образом, даже если вы привязаны к документу, это не может остановить меня.
3. Этого недостаточно, React инкапсулирует нативные события и предоставляет много хороших вещей, но при этом упускает некоторые возможности. e.stopImmediatePropagation() — это пропущенная часть, однако он дал открытие: e.nativeEvent, найдите stopImmediatePropagation() из собственного объекта события, завершите.

Вышеприведенное исходит изCNblog

Разница между stopImmediatePropagation и stopPropagation

  • стопиммедиатепропагейшн :
Блокирует выполнение прослушивателей событий для текущего узла и всех последующих узлов в потоке событий. То есть прослушиватель событий, влияющий на текущий узел.
  • остановить распространение:
Блокирует выполнение прослушивателей событий для всех последующих узлов текущего узла в потоке событий. То есть это не повлияет ни на какой мониторинг событий текущего узла (currentTarget).

Например 🌰: добавьте к элементу три события клика (порядок регистрации соответствует порядку выполнения кода)


  1. еслиe.stopPropagation(), результатом выполнения будет последовательное появление 1, 2, 2.1, 3. Потому что это не повлияет на события текущего узла
  2. еслиe.stopImmediatePropagation(), результат 1, 2, 2.1.


Резюме: просто полезноcontains()Метод, я помню, что я видел этот атрибут, когда я впервые узнал его В конечном счете, я еще не заложил прочный фундамент!