console
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>portal</title>
</head>
<body>
<div id="app-root"></div>
<div id="modal-root"></div>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<script typ src="https://cdn.jsdelivr.net/npm/@rustle/oops/dist/oops.umd.js"></script>
<script type="text/babel">
const React = oops
const { render, Fragment, useState, createPortal, memo, useEffect } = React
const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root');
const el = document.createElement('div')
el.onclick = e => {
console.log('nativeEvent', e.target)
}
function Modal(props) {
useEffect(() => {
modalRoot.appendChild(el)
return () => modalRoot.removeChild(el)
})
return (
createPortal(props.children, el)
)
}
function Parent(props) {
const [clicks, handleClick] = useState(0)
return (
<div onClick={e => {
console.log(e, e.target, e.currentTarget, e.nativeEvent);
handleClick(clicks + 1)
}}>
<p>Number of clicks: {clicks}</p>
<p>
Open up the browser DevTools
to observe that the button
is not a child of the div
with the onClick handler.
</p>
<Modal>
<Child />
</Modal>
</div>
)
}
function Child() {
return (
<div className="modal">
<button>Click</button>
</div>
)
}
render(<Parent />, appRoot)
</script>
</body>
</html>
#app-root {
height: 10em;
width: 10em;
background: lightblue;
overflow: hidden;
}
#modal-root {
position: relative;
z-index: 999;
}
.modal {
background-color: rgba(0,0,0,0.5);
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}