14

http://jsfiddle.net/walkerneo/QqkkA/Delega evento Javascript, gestione genitori di elementi cliccati?

Ho visto molte domande qui sia chiedendo o di essere risposto con delega evento in javascript, ma devo ancora vedere, però, come utilizzare la delega evento per elementi che non stanno per essere gli obiettivi dell'evento click.

Ad esempio:

HTML:

<ul> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
</ul>​ 

CSS:

ul{ 
    padding:20px; 
} 
li{ 
    margin-left:30px; 
    margin-bottom:10px; 
    border:1px solid black; 

} 
.d{ 
    padding:10px; 
    background:gray; 
} 
​ 

Cosa succede se voglio aggiungere un evento click per gestire gli elementi li quando sono cliccato? Se allego un gestore di eventi all'elemento ul, gli div s saranno sempre gli elementi di destinazione. Oltre a controllare ogni genitore dell'elemento di destinazione in una funzione di clic, come posso realizzare questo?

edit:

voglio utilizzare la delega evento invece di:

var lis = document.getElementsByTagName('li'); 
for(var i=0;i<lis.length;i++){ 
    lis[i].onclick = function(){}; 
} 

Ma se faccio:

document.getElementsByTagName('ul')[0].addEventListener('click',function(e){ 

    // e.target is going to be the div, not the li 
    if(e.target.tagName=='LI'){ 

    } 
},false); 

EDIT: io non sono interessato a come utilizzare Librerie Javascript per questo, sono interessato a come lo fanno e come può essere fatto con pure js.

+0

In realtà confuso sulla tua domanda, non ho capito cosa vuoi raggiungere. –

+0

Mi inculo sempre su questo ... questo link può aiutare: http://www.quirksmode.org/js/events_order.html –

+1

@Michal, sembrava inefficiente, mi chiedevo se fosse l'unico modo. – mowwwalker

risposta

15

Ecco un modo per risolverlo:

var list = document.getElementsByTagName('ul')[0] 

list.addEventListener('click', function(e){ 
    var el = e.target 
    // walk up the tree until we find a LI item 
    while (el && el.tagName !== 'LI') { 
    el = el.parentNode 
    } 
    console.log('item clicked', el) 
}, false) 

Questa è eccessivamente semplificata, il ciclo continuerà l'albero, anche oltre l'elemento UL. Vedere l'implementazione in rye/events per un esempio più completo.

I metodi Element.matches, Node.contains e Node.compareDocumentPosition consentono di implementare questo tipo di funzionalità.

+0

Ho fatto qualche ricerca in jQuery, e questo è quello che ho trovato. – mowwwalker

+0

Grazie :) È quello che mi serve. –

0

Non sono un geek javascript ma per rispondere alla tua domanda (solo per curiosità) Ho trascorso un po 'di tempo online e dopo un paio di minuti ho capito che è possibile attivare un evento sull'elemento genitore come questo (come idea alternativa, può essere che non sono adeguate) per gestire i genitori di elementi cliccato

var el=document.getElementsByTagName('ul')[0]; 
el.addEventListener('click',function(e){ 
    var elm=e.target.parentNode; 
    if(document.createEvent) 
    { 
     evt = document.createEvent('MouseEvents'); 
     evt.initMouseEvent("click", false, true, window, 
0, 0, 0, 0, 0, false, false, false, false, 0, null); 
     elm.dispatchEvent(evt); 
     liEventhandler(evt);   
    } 

}); 

function liEventhandler(e) 
{ 
    console.log(e); 
    console.log(e.target); 
    console.log(e.which); 
    alert(e.target.innerHTML); 
} 

un esempio è here.

Sopra esempio non funzionerà in IE utilizza createEventObject e fireEvent

if(document.createEventObject) 
{ 
    var evt = document.createEventObject(); 
    el.fireEvent('onclick', evt); 
    liEventhandler(evt); 
} 

e anche e.target è window.event.srcElement e addEventListener dovrebbero essere

el.attachEvent('onclick', function(){...}) 

Quando generato l'evento su ul e l'obiettivo è div Ho appena attivato un evento su li

Alcune referenze:1.comp.lang.javascript2.MOZILLA DEVELOPER NETWORK e 3.this.

0

C'è ora un metodo sugli elementi chiamati closest, che fa esattamente questo. Prende un selettore CSS come parametro e trova l'antenato di corrispondenza più vicino, che può essere l'elemento stesso. Tutte le versioni correnti dei browser desktop support, ma in generale non è pronta per l'uso di produzione. La pagina MDN collegata sopra contiene un polyfill.