隐藏弹出框功能恢复打开的弹出框功能

我想通过一个按钮激活一个“弹出”框,以降低所有其他元素的不透明度。当用户点击开箱时,它应该消失并且不透明度应该恢复正常。但是,这两个功能是相互冲突的。它需要我点击两次按钮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>


编辑

我发现它需要两次单击,因为在第一次单击时showBox() 会调用,但紧随其后的是 outsideClickListener,此时元素现在可见并且用户单击了元素的“外部”。这将恢复 的样式更改showBox()。


哆啦的时光机
浏览 104回答 1
1回答

江户川乱折腾

最简单的解决方法是存储对“新音频”的引用button并检查是否是target单击的document。如果是这样,那么return从函数中不更新DOM.const button = document.querySelector('button')button.addEventListener('click', showBox);// ..function hideOnClickOutside(element) {&nbsp; const outsideClickListener = event => {&nbsp; &nbsp; if (event.target === button) return&nbsp;// ..请记住,使用您拥有的当前代码,该hideOnClickOutside函数只会在第一次isVisible为 true 而target不是button,因为您在该条件下删除了事件侦听器。function showBox(e) {&nbsp; document.body.style.opacity = "0.5";&nbsp; 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.jsfunction hideOnClickOutside(element) {&nbsp; const outsideClickListener = event => {&nbsp; &nbsp; if (event.target === button) return&nbsp;&nbsp; &nbsp; if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null&nbsp; &nbsp; &nbsp; element.style.display = 'none';&nbsp; &nbsp; &nbsp; removeClickListener()&nbsp; &nbsp; &nbsp; document.body.style.opacity = "1";&nbsp; &nbsp; }&nbsp; }&nbsp; const removeClickListener = () => {&nbsp; &nbsp; document.removeEventListener('click', outsideClickListener)&nbsp; }&nbsp; document.addEventListener('click', outsideClickListener)}hideOnClickOutside(document.querySelector('div'));<button>New Audio</button><div style="display: none">&nbsp; <button>Record Directly</button></div>另一个问题是,一旦showBox调用该函数,您实际上可能希望在button外部考虑该函数。让我们重构您的代码以存储对showButtonand的引用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.jsfunction toggleDisabled(bool) {&nbsp; &nbsp; showButton.attributes.disabled = bool;&nbsp; &nbsp; isDisabled = bool;}function toggleDisplay(display, opacity) {&nbsp; &nbsp; document.body.style.opacity = opacity;&nbsp; &nbsp; box.style.display = display;}function showBox(event) {&nbsp; if (!isDisabled) {&nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; event.stopPropagation();&nbsp; &nbsp; toggleDisplay("block", 0.5);&nbsp; &nbsp; toggleDisabled(true);&nbsp; &nbsp; document.addEventListener('click', outsideClickListener);&nbsp; }}function outsideClickListener(event) {&nbsp; if (!box.contains(event.target) && isVisible(box)) { // or use: event.target.closest(selector) === null&nbsp; &nbsp; toggleDisplay("none", 1);&nbsp; &nbsp; toggleDisabled(false);&nbsp; &nbsp; document.removeEventListener('click', outsideClickListener)&nbsp; }}<button id="show-button">New Audio</button><div id="box" style="display: none">&nbsp; <button>Record Directly</button></div>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript