[英]Hide popup box function reverting open popup box function
我想制作一个由按钮激活的“弹出”框,以减少所有其他元素的不透明度。 当用户单击开箱即用时,它应该消失并且不透明度应该恢复正常。 但是,这两个功能是相互冲突的。 它需要我单击showBox()
按钮才能调用showBox()
。 除非我重新调用hideOnClickOutside(document.querySelector('div'));
在浏览器的控制台中。
为什么我必须单击“新音频”两次,为什么除非重新调用,否则hideOnClickOutside()
不起作用?
function showBox() { document.body.style.opacity = "0.5"; document.querySelector('div').style.display = "block"; } document.querySelector('button').addEventListener('click', showBox); const isVisible = elem => !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js function hideOnClickOutside(element) { const outsideClickListener = event => { if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null element.style.display = 'none'; removeClickListener() document.body.style.opacity = "1"; } } const removeClickListener = () => { document.removeEventListener('click', outsideClickListener) } document.addEventListener('click', outsideClickListener) } hideOnClickOutside(document.querySelector('div'));
<button>New Audio</button> <div style="display: none"> <button>Record Directly</button> </div>
hideOnClickOutside()
函数取自另一个 StackOverflow 答案
我发现它需要点击两次,因为在第一次点击时, showBox()
被调用,但紧接着,outsideClickListener 也是如此,此时元素现在可见,并且用户点击了元素的“外部”。 这将恢复showBox()
的样式更改。
最简单的解决方法是存储对“新音频” button
的引用并检查它是否是单击document
的target
。 如果是,则从函数return
而不更新DOM
。
const button = document.querySelector('button')
button.addEventListener('click', showBox);
// ..
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (event.target === button) return
// ..
请记住,使用您拥有的当前代码, hideOnClickOutside
函数仅在第一次isVisible
为 true 并且target
不是button
时才会获取,因为您在该条件下删除了事件侦听器。
function showBox(e) { document.body.style.opacity = "0.5"; document.querySelector('div').style.display = "block"; } const button = document.querySelector('button') button.addEventListener('click', showBox); const isVisible = elem => !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js function hideOnClickOutside(element) { const outsideClickListener = event => { if (event.target === button) return if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null element.style.display = 'none'; removeClickListener() document.body.style.opacity = "1"; } } const removeClickListener = () => { document.removeEventListener('click', outsideClickListener) } document.addEventListener('click', outsideClickListener) } hideOnClickOutside(document.querySelector('div'));
<button>New Audio</button> <div style="display: none"> <button>Record Directly</button> </div>
另一个问题是,一旦调用了showBox
函数,您实际上可能希望将button
考虑在外部。 让我们重构您的代码以存储对showButton
和box
引用,添加一个标志以disable
showButton
并仅在单击showButton
将事件侦听器添加到文档,并仅在显示框时移除事件侦听器。
您可以稍后重构它以适合您的特定用例。 这个想法是考虑这个应用程序可以处于的各种状态并创建函数来管理该状态。
const box = document.querySelector('#box'); const showButton = document.querySelector('#show-button'); showButton.addEventListener('click', showBox); let isDisabled = false; const isVisible = elem => !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js function toggleDisabled(bool) { showButton.attributes.disabled = bool; isDisabled = bool; } function toggleDisplay(display, opacity) { document.body.style.opacity = opacity; box.style.display = display; } function showBox(event) { if (!isDisabled) { event.preventDefault(); event.stopPropagation(); toggleDisplay("block", 0.5); toggleDisabled(true); document.addEventListener('click', outsideClickListener); } } function outsideClickListener(event) { if (!box.contains(event.target) && isVisible(box)) { // or use: event.target.closest(selector) === null toggleDisplay("none", 1); toggleDisabled(false); document.removeEventListener('click', outsideClickListener) } }
<button id="show-button">New Audio</button> <div id="box" style="display: none"> <button>Record Directly</button> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.