Reputation: 2717
I have a modal that covers whole window, but only because there is a need for a darkening background to the modal that is set on .open.modal
. HTML looks like this:
<div class="modals">
<div class="open modal">
<div class="modal_inner">
<div class="white">
<div class="x"><img src="/assets/meeting/close.png"></div>
<div class="all">
<!-- ALL CONTENT HERE -->
</div>
</div>
</div>
</div>
<div class="open modal">
<!-- OTHER MODAL CAN BE OPEN ON TOP -->
</div>
</div>
When user clicks outside .white
(.open.modal
or above) I want to close the modal.
How do I register a Javascript event that will fire if clicked between the parent (in this case body
or bellow) and the child (in this case .white
)?
I have this in React.
Upvotes: 0
Views: 579
Reputation: 1074435
There are two standard ways to approach it:
Hook click
on .open.modal
and do the real work there
Hook click
on .white
and prevent bubbling, so clicks on .white
don't reach .open.modal
, and thus don't trigger its handler
So for instance:
handleOpenModalClick(event) {
// Do the work
}
handleWhiteClick(event) {
event.stopPropagation();
}
Example:
class Example extends React.Component {
handleOpenModalClick(event) {
// Do the work
console.log("Do it");
}
handleWhiteClick(event) {
event.stopPropagation();
}
render() {
return (
<div>
<div className="open modal" onClick={this.handleOpenModalClick}>
<div className="white" onClick={this.handleWhiteClick}>
xxx
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById("react")
);
.open.modal {
background: #ccc;
padding: 20px;
}
.white {
background: white;
}
<div id="react"</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Hook click
on .open.modal
, and when received, check the elements between event.target
and .open.modal
and check if .white
is there. If so, don't do the work.
handleClick(event) {
let node = event.target;
while (node && node !== event.currentTarget) {
if (node.classList.contains("white")) {
return; // Skip it
}
}
// Do the work
}
Example:
class Example extends React.Component {
handleClick(event) {
let node = event.target;
while (node && node !== event.currentTarget) {
if (node.classList.contains("white")) {
return; // Skip it
}
}
// Do the work
console.log("Do it!");
}
render() {
return (
<div>
<div className="open modal" onClick={this.handleClick}>
<div className="white">
xxx
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById("react")
);
.open.modal {
background: #ccc;
padding: 20px;
}
.white {
background: white;
}
<div id="react"</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Upvotes: 1