#javascript #html #reactjs #onclick #hide
#javascript #HTML #reactjs #onclick #скрыть
Вопрос:
Я работаю над веб-сайтом, и в настоящее время у меня есть значок svg для выхода из системы. при нажатии на значок появляется наложение с опцией выхода. когда пользователь нажимает на выход, он должен выполнять определенную операцию, а когда пользователь нажимает вне div, наложение должно быть скрыто. мне не удается достичь этого.
я попытался сфокусироваться на div с помощью tabIndex, но тогда опция выхода из системы больше не доступна.
Header.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
class MainHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
logOutShown: false
};
}
render() {
var guiResult = [];
if (this.state.logOutShown) {
guiResult.push(
<div className="Login__Overlay__Frame">
<div className="User__Login__Overlay">
<div className="Login__Content" tabIndex="1" onFocus={this.alerting.bind(this)} onBlur={this.toggleOverlay.bind(this)}>Signout</div>
</div>
</div>
);
}
return (
<div className="Header__Icon">
<div className="Icons__Log__In" tabIndex="0" onClick={this.validate.bind(this)} onBlur={this.toggleOverlay.bind(this)}/>
{guiResult}
</div>
);
}
toggleOverlay(){
console.log("toggle overlay");
this.setState({ logOutShown: false});
}
validate() {
console.log("validate:");
this.setState(
{
logOutShown: true
}
);
}
Комментарии:
1. Вы можете добавить обработчики для наложения
<div className="User__Login__Overlay" onClick={this.toggleOverlay.bind(this)}>
2. Вы можете проверить щелчок при наложении, но есть проблема !!. Когда вы нажимаете на что-либо внутри наложения, это тоже отображается. Что я обычно делаю, так это создаю компонент для выполнения наложения, а внутри наложения находится контейнер, и этот контейнер подключается к onClick и вызывает
event.stopPropagation()
. Затем это остановит нажатие на ваш контент, вызывающее событие на оверлее.3. @Keith сейчас я попробую, создав новый компонент для наложения. может быть, вы можете предоставить мне общую структуру нового компонента, которая будет выглядеть так, как я запутался в этом «и внутри наложения есть контейнер, и этот контейнер подключается к onClick и вызывает event.stopPropagation()»
4. @Kirill как упоминал Кит, это не сработало.
5. Я посмотрю, смогу ли я создать быстрый фрагмент. дайте нам 10..
Ответ №1:
Вы можете использовать хорошо написанную библиотеку, подобную этой: react-outside-click-handler
пример:
import OutsideClickHandler from 'react-outside-click-handler';
function MyComponent() {
return (
<OutsideClickHandler
onOutsideClick={() => {
alert('You clicked outside of this component!!!');
}}
>
Hello World
</OutsideClickHandler>
);
}
Редактировать:
Сегодня, когда я редактирую этот комментарий, множество новых библиотек привносят эту функцию в ваш код.
Если вы используете библиотеку компонентов, проверьте, существует ли в ней утилита. (чакра, мантия, материал-пользовательский интерфейс).
Другое решение существует внутри библиотек hooks, таких как react-use.
Ответ №2:
Вот простой пример, я использую перехватчики реакции здесь вместо классов, но вы тоже можете использовать классы..
Основная часть — это onClick в контейнере div, если вы запустите приведенный ниже пример и нажмете на диалоговое окно, оно не закроется, но нажатие на наложение закроет.
e.stopPropagation()
В div контейнера — это то, что останавливает события содержимого, запускающие события на оверлее. Вместо использования stopPropagation
другим вариантом является проверка target
amp; currentTarget
внутри onClick наложения..
const {useState} = React;
function Overlay(props) {
const {contents} = props;
const [open, setOpen] = useState(true);
if (open) {
return <div className="overlay" onClick={() => setOpen(false)}>
<div onClick={(e) => {
//stop clicks getting to the overlay
e.stopPropagation();
}}className="overlay-container">
{contents()}
</div>
</div>
}
return null;
}
ReactDOM.render(<React.Fragment>
This is some content to overlay.<br/>
for testing..
<Overlay contents={() =>
<div>This is the contents, clicking here wont effect ovelay</div>
}/>
</React.Fragment>, document.querySelector('#mount'));
.overlay {
position: fixed;
background-color: rgba(100,100,100,0.5);
left: 0;
top: 0;
bottom: 0;
right: 0;
}
.overlay-container {
border: 1px solid black;
background-color: white;
position: absolute;
top: 30px;
left: 30px;
width: 200px;
height: 80px;
padding: 5px;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="mount"></div>
Ответ №3:
Используйте ссылки react https://reactjs.org/docs/refs-and-the-dom.html#creating-refs
Вы проверяете наличие target
события и используете это для show/hide
кнопки выхода.
добавьте прослушиватель событий при монтировании компонента.
componentWillMount() { document.addEventListener("click", this.handleClickOutside, false); }
удалите прослушиватель событий, когда компонент смонтирован.
componentWillUnmount() { document.removeEventListener("click", this.handleClickOutside, false); }
выполните проверку внешнего щелчка примерно так
handleClickOutside(e) {
if(this.submitPopoverRef.contains(e.target)) {
// the click happened in the component
// code to handle the submit button
// submit();
return;
}
// click happened outside the component
// hide the popover
this.handleClick(); // set the state false
}
<div ref={node => this.submitPopoverRef = node}>
... Your code here...
</div>
Ответ №4:
Основываясь на ответе @keith: использование перехватчиков реакции, а также классов: предполагается, что родительский и дочерний разделы, где вы хотели бы, чтобы родительский div обрабатывал щелчок ТОЛЬКО тогда, когда щелчок не был внутри дочернего div:
const clickedParent = () => {};
const clickedChild = () => {};
<div onClick={clickedParent}>
<div className="selc-hd-so-remove" onClick={e=> { e.stopPropagation(); clickedChild(); }} > Child Div Clicked</div>
</div>
Parent Div Clicked
</div>
Ответ №5:
Необходимо использовать stopPropagation
для дочерних элементов
export default function App() {
const parentHandler = () => {
console.log("Parent");
};
const childHandler = (e) => {
e.stopPropagation();
console.log("Child");
};
return (
<div className="App">
<div onClick={parentHandler}>
<div onClick={childHandler}>Child Div</div>
Parent Div
</div>
</div>
);
}