为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

jeck猫 2023-09-18 17:22:14
我想制作一个由按钮激活的“弹出”框,以减少所有其他元素的不透明度。当用户点击框外时,它应该消失并且不透明度应该恢复正常。然而,这两个功能是相互冲突的。它需要我单击按钮两次才能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.jsfunction 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()。
查看完整描述

1 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

最简单的解决方法是存储对“新音频”的引用button,并检查这是否是target单击的document。如果是这样,则从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 之前获取,而 istarget则不是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添加一个标志,并且仅在单击 时将事件侦听器添加到文档,并且仅在显示该框时删除事件侦听器。disableshowButtonshowButton


您可以稍后重构它以适合您的特定用例。这个想法是考虑该应用程序可能处于的各种状态并创建函数来管理该状态。


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>


查看完整回答
反对 回复 2023-09-18
  • 1 回答
  • 0 关注
  • 47 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信