我尝试单击某处的侧导航,但导航块本身及其切换按钮。我尝试这样的代码:
HTML
<div class="header__menu-toggle">
<div class="icon-menu"></div>
</div>
<section id="main-nav">
<ul class="main-nav__inner">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</section>
NATIVE JS
var body = document.getElementsByTagName("body")[0];
var nav = document.getElementById('main-nav');
var navToggle = document.getElementsByClassName('header__menu-toggle')[0];
function closeAll(e) {
if (e.target != nav && e.target != navToggle) {
nav.classList.remove("main-nav--open");
}
}
body.addEventListener('click', closeAll)
问题是e.target
等于确切的点击目标,而不是整个块。对于前者点击<div class="icon-menu"></div>
不等于点击其父<div class="header__menu-toggle">
。或者点击导航栏中深处的子li
元素并不等于点击<section id="main-nav">
。
如何解决这个问题呢?如何检查是否单击导航块或navToggle块?
答案 0 :(得分:0)
尝试:$(event.currentTarget) 我认为这是解决方案,如果不是尝试显示事件对象并找到一些帮助您的事件子属性 这个链接可以帮助 event.currentTarget
答案 1 :(得分:0)
我想这样的事情可能有用。
旁注:querySelector
和querySelectorAll
很棒,请改用它们。
var body = document.querySelector("body");
var nav = document.querySelector('#main-nav');
var navToggle = document.querySelector('.header__menu-toggle');
var nodeArr = [].slice.call(nav.childNodes);
function closeAll(e) {
if (nodeArr.indexOf(e.target) !== -1) {
console.log('closing the nav')
nav.classList.remove("main-nav--open");
} else {
console.log('clicked inside nav')
}
}
body.addEventListener('click', closeAll)
<div class="header__menu-toggle">
<div class="icon-menu"></div>
</div>
<section id="main-nav">
<ul class="main-nav__inner">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</section>
为什么会有效?
nav.childNodes
存储有关nav元素的所有子元素的信息。为方便起见,我们将其转换为数组。检测到click
后,我们检查点击目标是否属于导航(位于数组中)。
答案 2 :(得分:0)
尝试从目标元素进入DOM树。
//function search for "search" element for "current" element and all his parents
function isInside(search,current){
if (current!=search){
if (typeof current.parentNode != 'undefined' && current.parentNode!=null)
return isInside(search,current.parentNode);//go to parent
else
return false;//our tree is over - this is outside element
}else{
//yes this is element we looking for
return true;
}
};
var search=document.querySelector("#container");
//usage
document.querySelector("body").addEventListener("click",function(e){
if (isInside(search,e.target)){
console.log("click inside #container");
}else{
console.log("click outside #container");
}
});
&#13;
<html>
<body>
<div> This is wrong div</div>
<div id="container" width="100px" height="100px" style="display:block; background:red"><ul><li><span>Test node</span></li></ul>
</div>
<div> This is wrong div</div>
</body>
</html>
&#13;
解释 - 我从e.target节点开始向上,有结局 - 如果我们找到匹配搜索元素的父元素 - 这意味着我们在里面或者我们是这个元素,或者第二个我们去结束树 - 我们在外面。
这种方法可以通过添加例如我们应该达到多少级别来改进。
在目前的问题中,使用 isInside 功能会是这样的:
function closeAll(e) {
if (!isInside(nav,e.target) && !isInside(navToggle,e.target) ) {
nav.classList.remove("main-nav--open");
}
}
答案 3 :(得分:0)
你可以使用jquery方法&#34;最接近&#34;
$(document).click( function(event){
if( $(event.target).closest("#main-nav").length ||
$(event.target).closest(".header__menu-toggle").length) return;
$("#main-nav").removeClass("main-nav--open");
}
答案 4 :(得分:0)
event.path返回树结构的数组,可用于查找目标元素的父元素。
用以下代码替换js代码:
var body = document.getElementsByTagName("body")[0];
var nav = document.getElementById('main-nav');
var navToggle = document.getElementsByClassName('header__menu-toggle')[0];
function closeAll(event) {
if (event.path.indexOf(nav) > -1 && event.path.indexOf(navToggle) > -1) {
nav.classList.remove("main-nav--open");
}
}
body.addEventListener('click', closeAll)