纯JavaScript - 点击外部隐藏Div

4
当我点击具有ID“Container_ID”的我的DIV之外的任何位置时,所有容器都会通过display: none;隐藏。 我在 JavaScript 中呈现的代码在某种程度上可以工作,因为当我单击Container_ID内的任何部分时,它返回相同的行为,我的DIV会隐藏。 但是,当我与Container_ID内部的Controls_CLASS + ul、li + Checkbox_CLASS元素交互时,它们不应该被排除在隐藏整个Container_ID时,因为它们位于其中。
如何改善这个问题? JavaScript(字体:https://codepen.io/marizawi/pen/YgaaMp

window.addEventListener('mouseup', function(event) {
  var cont = document.getElementById('Container_ID');
  if (event.target != cont && event.target.parentNode != cont) {
    cont.style.display = 'none';
  }
});
div.Container_CLASS {
  width: 50%;
  height: 350px;
  margin-top: 4px;
  margin-left: 4px;
  display: block;
  position: absolute;
  overflow-y: scroll;
}
<div class="Container_CLASS" id="Container_ID">
  <div class="Controls_CLASS"><a href="#">Select All</a>|<a href="#">Reset</a></div>
  <ul>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="BMW" />BMW</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Mercedes" />Mercedes</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Volvo" />Volvo</li>
  </ul>
</div>


我为您创建了一个代码片段,请在 [mcve] 中将其可见。 - mplungjan
同样也是重复问题 - mplungjan
我不明白哪里出了问题。在示例中我没有看到任何列表。 - html_programmer
@mplungjan 是的,这是一个重复问题,但我检查了前三个搜索结果,没有一个真正好的答案。 - connexo
3个回答

4

使用closest方法来检查点击的区域是否在div之外。

closest

一个元素的祖先是指:它的直接父元素,父元素的父元素,依此类推。这些祖先一起形成了从该元素到顶部的父级链。

elem.closest(css)方法会查找最近的匹配CSS选择器的祖先元素,包括elem本身。

In other words, the method closest goes up from the element and checks each of parents. If it matches the selector, then the search stops, and the ancestor is returned.
if div has id

 window.addEventListener('mouseup',function(event){
        var pol = document.getElementById('pol');
        if(!(event.target.closest("#pol"))){
            pol.style.display = 'none';
        }
  });  
h2{margin:0 0 10px}
#pol{
    width:400px;
    height:300px;
    background:#999;
    text-align:center;
    display:none;
    margin-top:0;
    margin:10px;
}
<h2>Click outside div will be hide. Click Button div will be display</h2>
<button onClick="document.getElementById('pol').style.display='block'">Show</button>
<div id="pol">
I am Tanmoy Biswas
  <p>ksjdhfksjdhfkjshdfkjsdfsf</p>
<div class="Controls_CLASS"><a href="#">Select All</a>|<a href="#">Reset</a></div>
  <ul>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="BMW" />BMW</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Mercedes" />Mercedes</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Volvo" />Volvo</li>
  </ul>
</div>

如果 div 具有 class

 

    window.addEventListener("mouseup", function (event) {
  let pol = document.querySelectorAll(".pol");
  pol.forEach((myDiv) => {
    if (!(event.target.closest(".pol"))) {
      myDiv.style.display = "none";
    }
  });
});
h2{margin:0 0 10px}
.pol{
    width:400px;
    height:300px;
    background:#999;
    text-align:center;
    display:none;
    margin-top:0;
    margin:10px;
}
<h2>Click outside div will be hide. Click Button div will be display</h2>
<button onClick="document.getElementById('a').style.display='block'">Show</button>
<div id="a" class="pol">
I am Tanmoy Biswas
  <p>ksjdhfksjdhfkjshdfkjsdfsf</p>
<div class="Controls_CLASS"><a href="#">Select All</a>|<a href="#">Reset</a></div>
  <ul>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="BMW" />BMW</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Mercedes" />Mercedes</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Volvo" />Volvo</li>
  </ul>
</div>


<h2>Click outside div will be hide. Click Button div will be display</h2>
<button onClick="document.getElementById('b').style.display='block'">Show</button>
<div id="b" class="pol">
I am Tanmoy Biswas
  <p>ksjdhfksjdhfkjshdfkjsdfsf</p>
<div class="Controls_CLASS"><a href="#">Select All</a>|<a href="#">Reset</a></div>
  <ul>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="BMW" />BMW</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Mercedes" />Mercedes</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Volvo" />Volvo</li>
  </ul>
</div>


1
event.target.closest("#pol") === null 可以被替换为 !(pol.contains(event.target)) - connexo
1
@Jaakko 我编辑了答案。这能帮到你吗? - Ahmad MRF
@M.RMRF,你说的 myDiv 是什么意思?我的示例中没有这个名称... - Edgaras
1
@Jaakko myDiv 是一个参数,它将任何具有 .pol 类的项目传递给 foreach 回退函数 - Ahmad MRF
1
https://chat.stackoverflow.com/rooms/241332/discussion-between-m-r-mrf-and-jaakko - Ahmad MRF
显示剩余6条评论

2
这是我会做的事情。
只需检查点击的元素(event.target)是否在容器中,或者点击的元素是否为显示容器的元素即可。

const theDiv = document.getElementById('theDiv');
const theButton = document.getElementById('theButton');

document.addEventListener('click', function(event) {
  if (theDiv.contains(event.target) || event.target.id === 'theButton') return;
  theDiv.hidden = true;
})
div {
  background-color: red;
  height: 400px;
  width: 400px;
}
<button type="button" onclick="this.nextElementSibling.hidden=false" id="theButton">Show</button>
<div hidden id="theDiv">
  <button>clicking here won't close</button>
</div>

针对您的例子:

const container = document.getElementById('Container_ID');

document.addEventListener('click', function(event) {
  if (container.contains(event.target)) return;
  container.hidden = true;
})
div.Container_CLASS {
  border: 1px solid red;
  width: 50%;
  height: 350px;
  margin-top: 4px;
  margin-left: 4px;
  position: absolute;
  overflow-y: scroll;
}
<div class="Container_CLASS" id="Container_ID">
  <div class="Controls_CLASS"><a href="javascript:void(0)">Select All</a>|<a href="javascript:void(0)">Reset</a></div>
  <ul>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="BMW" />BMW</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Mercedes" />Mercedes</li>
    <li><input type="checkbox" name="cars[]" class="Checkbox_CLASS" value="Volvo" />Volvo</li>
  </ul>
</div>


在代码片段上运行得非常好,但当我放到我的代码中时,什么都不发生:s - Edgaras
适应你的代码。可用。 - connexo
我可以在代码片段中看到它工作,但在我的实际代码中不起作用。 Container_ID 在表单和表格 TD 中,可能是问题吗?还是它不会干扰? - Edgaras
仍然无法工作,请直接检查我的代码,也许你会发现有什么问题:https://imgur.com/a/q2DVrKH - Edgaras
1
代码可以运行。你需要在CSS中不设置任何display属性,否则会破坏hidden功能。 - connexo
显示剩余3条评论

-1

这里有几个你可以使用的选项

我认为最好的是鼠标离开事件

鼠标离开事件

document.getElementById("Container_ID").addEventListener('mouseleave',function(event){
    document.getElementById("Container_ID").style.display = "none";
});

失去焦点事件

document.getElementById("Container_ID").addEventListener('focusout',function(event){
    document.getElementById("Container_ID").style.display = "none";
});

两者都不起作用。当我点击Container_ID之外的区域时,它仍然不会隐藏。 - Edgaras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接