2016-08-09 26 views
0

Ich versuche, die Seitennavigation auf Klick irgendwo zu schließen, aber Navigationsblock selbst und seine Umschalttaste. Ich versuche, einen solchen Code:Event.target Alternativen

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) 

Das Problem ist, dass e.target auf eine genaue Ziel Klick entspricht, nicht ganze Block. Für Beispiel Klicken Sie auf <div class="icon-menu"></div> ist nicht gleich auf seinen Elternteil klicken <div class="header__menu-toggle">. Oder klicken Sie auf Kind li Elemente tief im Navigationsblock ist nicht gleich auf <section id="main-nav"> klicken. Wie löst man dieses Problem? Wie überprüfe ich, ob ich gemeinsam auf Navigationsblock oder navToggle-Block klicke?

+0

Sie besser wickeln die ganze Sache in einem eigenen Container und wenden Sie den Ereignis-Listener es:

js Code mit ersetzen. Anwenden auf den Körper ist keine gute Idee. Es kann Ihr ursprüngliches Problem auch lösen. – haim770

Antwort

0

Versuch: $ (event.currentTarget) ich denke, dass die Lösung, wenn nicht das Ereignisobjekt versuchen und einige Unter Eigenschaft Fall, dass Sie helfen diesen Link können helfen event.currentTarget

+0

Es ist eine gute Antwort, wenn OP jQuery verwendet, aber ich denke, die Frage gilt hauptsächlich für native js. – spoq

+0

ja aber event.currentTarget ist eine native js, die ich gerade von meinem js Code kopiert habe –

+0

Allerdings ist $ (event.currentTarget) jquery. – pabrams

0

finden anzuzeigen Ich denke, so etwas kann funktionieren.

Seitennotiz: querySelector und querySelectorAll sind toll, verwenden Sie sie stattdessen.

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>

Warum es funktioniert?

nav.childNodes speichert Informationen über alle untergeordneten Elemente des nav-Elements. Wir konvertieren es für Bequemlichkeit in Array. Nachdem click erkannt wurde, prüfen wir, ob das Klickziel zum Nav gehört (ist im Array).

0

Versuchen Sie, in DOM-Baum von Zielelement zu gehen.

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

Erklärung - i mit e.target Knoten starten und steigen, gibt es zu Endungen - ein, wenn wir Eltern finden das Suchelement ist passend - dies bedeutet, dass wir innerhalb oder wir sind dieses Element, oder zweitens gehen wir zum Ende des Baumes - wir sind draußen.

Diese Methode kann verbessert werden, indem zum Beispiel hinzugefügt wird, um wie viel Ebenen wir gehen sollten.

In dieser aktuellen Problem Nutzung von isInside Funktion würde wie folgt sein:

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

Sie jquery-Methode "am nächsten"

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

event.path Rückkehr Array von Baum verwenden können Struktur, die verwendet werden kann, um Eltern des Zielelements zu finden.

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)