防止父容器内的内容使父容器消失

时间:2021-02-11 22:21:35

I have this script that uses a toggle button to show or hide a targeted parent container. There is two correct ways that the parent class container hides by

我有这个脚本使用切换按钮来显示或隐藏目标父容器。父类容器隐藏有两种正确的方法

pressing the toggle button the second time or by clicking outside the parent class container. So it works perfectly but any time I add any thing inside that

第二次按下切换按钮或通过单击父类容器外部。所以它完美无缺,但任何时候我都添加任何内容

parent class container and I click those inside contents it makes the whole parent class container disappear how can I prevent that?

父类容器,我点击内部内容,它使整个父类容器消失,我该如何防止?

Here is my code

这是我的代码

  document.addEventListener('DOMContentLoaded', function(){

document.addEventListener('click',closeContainer);

function closeContainer(obj){
     var containerVar = document.querySelector('.container');
    if(obj.target.className != 'container') {
        if (containerVar.style.display === 'flex') {
            containerVar.style.display = 'none';
        } else  if(obj.target.id == 'toggle') {
            containerVar.style.display = 'flex';
        }
    }
  }
  
});
.container{
background-color: orange;
height: 350px;
width: 350px;
margin-left: auto;
margin-right: auto;
display: none;
justify-content: center;
}

.inner-container{
 margin-top: 50px;
 background-color: red;
 height: 200px;
 width: 200px;
 display: inline-block;
}
<button id='toggle'>Toggle</button>
<div class='container'>
  <div class='inner-container'></div>
</div>

1 个解决方案

#1


4  

You need to capture click events on your container and stop propagation, then there's no need to check the target in your document's event handler:

您需要捕获容器上的单击事件并停止传播,然后无需检查文档的事件处理程序中的目标:

document.addEventListener('DOMContentLoaded', function() {

  // if click event is inside container, then stop propagation
  const container = document.querySelector('.container');
  container.addEventListener('click', function(e) {
    e.stopPropagation();
  });

  document.addEventListener('click', closeContainer);

  function closeContainer(obj) {
    var containerVar = document.querySelector('.container');
    if (containerVar.style.display === 'flex') {
      containerVar.style.display = 'none';
    } else if (obj.target.id == 'toggle') {
      containerVar.style.display = 'flex';
    }
  }

});
.container {
  background-color: orange;
  height: 350px;
  width: 350px;
  margin-left: auto;
  margin-right: auto;
  display: none;
  justify-content: center;
}

.inner-container {
  margin-top: 50px;
  background-color: red;
  height: 200px;
  width: 200px;
  display: inline-block;
}
<button id='toggle'>Toggle</button>
<div class='container'>
  <div class='inner-container'></div>
</div>

Another solution would be to only have one event handler on document and check if the target or any of its ancestors have the container class (similar to jquery's closest method):

另一种解决方案是在文档上只有一个事件处理程序,并检查目标或其任何祖先是否具有容器类(类似于jquery最接近的方法):

document.addEventListener('DOMContentLoaded', function() {

  document.addEventListener('click', closeContainer);

  function closeContainer(obj) {
    if (closest(obj.target, '.container')) return;

    var containerVar = document.querySelector('.container');
    if (containerVar.style.display === 'flex') {
      containerVar.style.display = 'none';
    } else if (obj.target.id == 'toggle') {
      containerVar.style.display = 'flex';
    }
  }

  function closest(el, selector) {
    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

    while (el) {
      if (matchesSelector.call(el, selector)) {
        return el;
      } else {
        el = el.parentElement;
      }
    }
    return null;
  }

});
.container {
  background-color: orange;
  height: 350px;
  width: 350px;
  margin-left: auto;
  margin-right: auto;
  display: none;
  justify-content: center;
}

.inner-container {
  margin-top: 50px;
  background-color: red;
  height: 200px;
  width: 200px;
  display: inline-block;
}
<button id='toggle'>Toggle</button>
<div class='container'>
  <div class='inner-container'></div>
</div>

#1


4  

You need to capture click events on your container and stop propagation, then there's no need to check the target in your document's event handler:

您需要捕获容器上的单击事件并停止传播,然后无需检查文档的事件处理程序中的目标:

document.addEventListener('DOMContentLoaded', function() {

  // if click event is inside container, then stop propagation
  const container = document.querySelector('.container');
  container.addEventListener('click', function(e) {
    e.stopPropagation();
  });

  document.addEventListener('click', closeContainer);

  function closeContainer(obj) {
    var containerVar = document.querySelector('.container');
    if (containerVar.style.display === 'flex') {
      containerVar.style.display = 'none';
    } else if (obj.target.id == 'toggle') {
      containerVar.style.display = 'flex';
    }
  }

});
.container {
  background-color: orange;
  height: 350px;
  width: 350px;
  margin-left: auto;
  margin-right: auto;
  display: none;
  justify-content: center;
}

.inner-container {
  margin-top: 50px;
  background-color: red;
  height: 200px;
  width: 200px;
  display: inline-block;
}
<button id='toggle'>Toggle</button>
<div class='container'>
  <div class='inner-container'></div>
</div>

Another solution would be to only have one event handler on document and check if the target or any of its ancestors have the container class (similar to jquery's closest method):

另一种解决方案是在文档上只有一个事件处理程序,并检查目标或其任何祖先是否具有容器类(类似于jquery最接近的方法):

document.addEventListener('DOMContentLoaded', function() {

  document.addEventListener('click', closeContainer);

  function closeContainer(obj) {
    if (closest(obj.target, '.container')) return;

    var containerVar = document.querySelector('.container');
    if (containerVar.style.display === 'flex') {
      containerVar.style.display = 'none';
    } else if (obj.target.id == 'toggle') {
      containerVar.style.display = 'flex';
    }
  }

  function closest(el, selector) {
    const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

    while (el) {
      if (matchesSelector.call(el, selector)) {
        return el;
      } else {
        el = el.parentElement;
      }
    }
    return null;
  }

});
.container {
  background-color: orange;
  height: 350px;
  width: 350px;
  margin-left: auto;
  margin-right: auto;
  display: none;
  justify-content: center;
}

.inner-container {
  margin-top: 50px;
  background-color: red;
  height: 200px;
  width: 200px;
  display: inline-block;
}
<button id='toggle'>Toggle</button>
<div class='container'>
  <div class='inner-container'></div>
</div>