Event.target替代品

时间:2016-08-09 13:20:27

标签: javascript html

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

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

5 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我想这样的事情可能有用。

旁注: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后,我们检查点击目标是否属于导航(位于数组中)。

答案 2 :(得分:0)

尝试从目标元素进入DOM树。

&#13;
&#13;
//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;
&#13;
&#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)