Tengo un evento de clic en la etiqueta li y luego en ese li tengo otro li anidado.
Cuando se hace clic en padre li todo funciona bien. Pero onclick anidado o child li se activa el evento de clic principal li .
He usado el método event.stopPropagation() pero no funciona en mi caso.
$("li").on("click",function() { console.log(this.firstChild.textContent) }) $('#testUl > li').on('click', function(e) { e.stopPropagation(); }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <ul id="testUl"> <li> <a href="#">Test A</a> <div class="innerUl"> <ul> <li>Inner A</li> <li>Inner B</li> <li>Inner C</li> </ul> </div> </li> </ul> $('#testUl .innerUl li').on('click', function(e) { e.stopPropagation(); }); // or $('#testUl li').on('click', function(e) { e.stopPropagation(); }); $('#testUl > li').on('click', function(e) { alert('test'); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- #testUl --> <ul id="testUl"> <!-- #testUl > li --> <li> <!-- #testUl > li > a or #testUl a --> <a href="#">Test A</a> <!-- #testUl > li > .innerUl or #testUl .innerUl --> <div class="innerUl"> <!-- #testUl > li > .innerUl > ul or #testUl ul --> <ul> <!-- #testUl > li > .innerUl > ul > li or #testUl li or #testUl .innerUl li or .innerUl li --> <li>Inner A</li> <li>Inner B</li> <li>Inner C</li> </ul> </div> </li> </ul>Está utilizando un selector incorrecto para detener la propagación
Cuando usa #testUl > li , llama al primer elemento secundario li , pero tiene elementos li dentro de su li en #testUl , así que llame a #testUl li o #testUl .innerUl li
Puede comparar e.target que es el elemento que tiene un evento de click , y e.currentTarget que es el elemento en el que realmente hizo clic. Si no coinciden, regresa sin realizar el resto de la función
$('#testUl > li').on('click', (e) => { if (e.target !== e.currentTarget) { return; } console.log('parent'); }); $('.innerUl li').on('click', (e) => { if (e.target !== e.currentTarget) { return; } console.log('child'); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul id="testUl"> <li> Test A <div class="innerUl"> <ul> <li>Inner A</li> <li>Inner B</li> <li>Inner C</li> </ul> </div> </li> </ul>Sin jQuery, puede usar la delegación de eventos y determinar actuar usando Element.closest()
document.addEventListener(`click`, handle); function handle(evt) { console.clear(); if (!evt.target.closest(`.innerUl`) && evt.target.closest(`#testUl`)) { console.log(`You clicked (something within) the first li of ul#testUl`); } } <ul id="testUl"> <li> <a href="#">Test A</a> <div class="innerUl"> <ul> <li>Inner A</li> <li>Inner B</li> <li>Inner C</li> </ul> </div> </li> </ul>La misma idea con jQuery
$("#testUl").on("click", evt => { console.clear(); if (!evt.target.closest(`.innerUl`) && evt.target.closest(`#testUl`)) { console.log(`You clicked ${evt.target.outerHTML}`); } }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"> </script> <ul id="testUl"> <li> <a href="#">Test A</a> <div class="innerUl"> <ul> <li>Inner A</li> <li>Inner B</li> <li>Inner C</li> </ul> </div> </li> </ul>