2 votes

Arrêt du déclenchement de l'événement parent sur le clic de l'élément enfant

J'ai un événement de clic sur li puis dans cette balise li J'ai un autre lien imbriqué.

Lorsque l'on clique sur le parent li tout fonctionne bien. Mais onclick nested ou child li le parent li est déclenché.

J'ai utilisé event.stopPropagation() mais cela ne fonctionne pas dans mon cas.

$("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>

2voto

naxsi Points 591
$('#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>

Vous utilisez un mauvais sélecteur pour la propagation de l'arrêt

Lorsque vous utilisez #testUl > li vous appelez le premier li mais vous avez li à l'intérieur de votre li sur #testUl Appelez donc #testUl li o #testUl .innerUl li

1voto

ciekals11 Points 742

Vous pouvez comparer e.target qui est un élément qui a click et e.currentTarget c'est l'élément sur lequel vous avez réellement cliqué. S'ils ne correspondent pas, vous retournez sans exécuter le reste de la fonction.

$('#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>

1voto

KooiInc Points 38845

Sans jQuery, vous pouvez utiliser délégation d'événements et décider d'agir en utilisant 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>

Même idée avec 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>

0voto

Dragos Points 11

Vous pouvez essayer avec stopImmediatePropagation()

Voir ici : https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X