繁体   English   中英

Event.target替代方案

[英]Event.target alternatives

我尝试使侧面导航在单击某处时关闭,但导航块本身及其切换按钮。 我尝试这样的代码:

的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>

原生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块?

尝试:$(event.currentTarget)我认为这是解决方案,如果不尝试显示事件对象并找到事件的一些子属性,可以帮助您,此链接可以帮助event.currentTarget

我想类似的事情可能会起作用。

旁注: querySelectorquerySelectorAll很棒,请改用它们。

 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后,我们检查点击目标是否属于导航(在阵列中)。

尝试从目标元素进入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"); } }); 
 <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> 

说明-我从e.target节点开始,然后到结尾-如果找到与搜索元素匹配的父对象,则是一个结局-这意味着我们在其中,或者是这个元素,或者第二个结局是在树的末端-我们在外面。

可以通过添加例如我们应该提高多少级别来改进此方法。

在当前问题中, isInside函数的用法如下:

function closeAll(e) {
   if (!isInside(nav,e.target) && !isInside(navToggle,e.target) ) {
      nav.classList.remove("main-nav--open");
   }
}

您可以使用jQuery方法“最近”

$(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");  
}

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM