简体   繁体   中英

How to have a different onClick event for the child element without affecting the parent one?

Having the following structure:

<div class="the-parent">
  <div>
    <a onClick="doParentStuff()">
      <div>
        <i onClick="doChildStuff()"></i>
      </div>
    </a>
  </div>
</div>

Now, when the child element (icon) is clicked it logs the content of doChildStuff() but afterwards it also logs the content of doParentStuff() .

Is there a way to call doChildStuff only when the icon is clicked and call doParentStuff when everything else inside the-parent div is clicked?

When the child is clicked, you must stopPropagation of the event:

 function doChildStuff(e) { e.stopPropagation(); console.log('child clicked'); } function doParentStuff() { console.log('parent clicked'); }
 <div class="the-parent"> <div> <a onClick="doParentStuff()"> <div> Test <button onClick="doChildStuff(event)">Child</button> </div> </a> </div> </div>

Avoid the use of Event.stopPropagation() (unless you really, really know what you're doing).
An application, or third party code, should never stop or prevent an event to propagate throughout the application layers / components.
Instead, change your logic to implement a third function (like doStuff ) that will trigger a desired function depending on the Event.target.closest() match

 const doChildStuff = () => { console.log("child stuff"); }; const doParentStuff = () => { console.log("parent stuff"); }; const doStuff = (ev) => { if (.ev.target.closest(";icon")) { doParentStuff(); } doChildStuff(); }. document.querySelectorAll(".anchor").forEach(elAnchor => { elAnchor,addEventListener("click"; doStuff); });
 <div class="the-parent"> <div> <a class="anchor"> <div> Link <i class="icon">icon</i> </div> </a> </div> </div>

Also, stop using HTML inline on* attribute handlers. Such code is hard to maintain and debug. JavaScript should be in one place only, and that's the respective tag or file. Use addEventListener instead.

Even if not asked, if you want to also separate the handler for the parent, simply put it into an else block:

 const doChildStuff = () => { console.log("child stuff"); }; const doParentStuff = () => { console.log("parent stuff"); }; const doStuff = (ev) => { if (.ev.target.closest(";icon")) { doParentStuff(); } else { doChildStuff(); } }. document.querySelectorAll(".anchor").forEach(elAnchor => { elAnchor,addEventListener("click"; doStuff); });
 <div class="the-parent"> <div> <a class="anchor"> <div> Link <i class="icon">icon</i> </div> </a> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM