Suggest an editImprove this articleRefine the answer for “The event.stopPropagation() method”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`event.stopPropagation()` stops the event from travelling any further through the DOM tree: handlers on the current element still run, but the ancestors never receive the event.** The method only controls the event's route: it does not cancel the browser's default action (that is `preventDefault()`) and it does not silence other handlers on the same element (that is `stopImmediatePropagation()`). ```javascript child.addEventListener('click', (e) => { e.stopPropagation(); // parent handlers will no longer fire }); ``` **Key point:** `stopPropagation()` switches off propagation, not the default action.Shown above the full answer for quick recall.Answer (EN)Image**`event.stopPropagation()` stops the event from travelling any further through the DOM tree: the event still fires on the element where it happened, but it never rises to that element's ancestors.** The method only affects the event's route. It does not cancel the browser's default action and it does not block other handlers attached to the same element. ## Theory ### TL;DR - `stopPropagation()` cuts off further propagation through the tree: both bubbling upward and any remaining capturing downward. - Handlers attached to the same element still run: the method stops neighbours in the tree, not neighbours on the element. - It does not cancel the browser's default action (following a link, submitting a form), that is what `preventDefault()` is for. - `stopImmediatePropagation()` is stricter: it stops propagation and the remaining handlers on this very element. - Overusing it silently breaks event delegation: the parent handler simply stops receiving clicks. ### Quick example ```javascript document.querySelector('.child').addEventListener('click', (event) => { console.log('child'); event.stopPropagation(); // stop bubbling, the parent will see nothing }); ``` ### Event bubbling by default Most DOM events bubble: after being handled on the target element they travel up the chain of ancestors. ```html <div class="parent"> <button class="child">Click</button> </div> ``` ```javascript document.querySelector('.parent').addEventListener('click', () => { console.log('Parent'); }); document.querySelector('.child').addEventListener('click', () => { console.log('Child'); }); ``` Clicking the `.child` button logs: ```text Child Parent ``` The handler on the button ran first, then the event bubbled up and triggered the parent's handler. ### What stopPropagation() actually does It is enough to call the method inside the child's handler: ```javascript document.querySelector('.child').addEventListener('click', (event) => { console.log('Child'); event.stopPropagation(); // stop the bubbling }); ``` Now a click on the button logs only: ```text Child ``` The event never reaches the parent, it gets stuck on the button. The same holds for deeper nesting: ```html <div id="outer"> <div id="inner"> <button id="btn">Click me</button> </div> </div> ``` ```javascript outer.addEventListener('click', () => console.log('outer')); inner.addEventListener('click', () => console.log('inner')); btn.addEventListener('click', (e) => { e.stopPropagation(); console.log('button'); }); ``` A click on the button prints only `button`, while `inner` and `outer` never receive the event. ### Delegation: when bubbling gets in the way If a single shared handler sits on the parent (classic delegation), a click on a nested button sometimes must not reach it: ```html <ul id="list"> <li>Item 1 <button>Delete</button></li> <li>Item 2 <button>Delete</button></li> </ul> ``` ```javascript list.addEventListener('click', (e) => { if (e.target.tagName === 'LI') { console.log('Item clicked'); } }); document.querySelectorAll('button').forEach(btn => btn.addEventListener('click', (e) => { e.stopPropagation(); // so the parent does not receive the event console.log('Deleting the item'); }) ); ``` The result: - a click on `<li>` logs "Item clicked"; - a click on the button logs "Deleting the item", and the event does not bubble to the list. ### What stopPropagation() does not do - **It does not cancel the browser's default action.** The form will still submit, the link will still open. You need `event.preventDefault()` for that. - **It does not block other handlers on the same element.** If a button has three `click` listeners, all three run, in the order they were added. ### stopImmediatePropagation() and the summary table There is a stricter option: ```javascript event.stopImmediatePropagation(); ``` It stops everything: propagation through the tree and the remaining handlers on this very element, so further processing is blocked completely. | Method | What it does | Stops bubbling? | Stops other handlers on the element? | | --- | --- | --- | --- | | `event.stopPropagation()` | Interrupts propagation further through the tree | Yes | No | | `event.stopImmediatePropagation()` | Blocks any further processing of the event | Yes | Yes | | `event.preventDefault()` | Cancels the browser's default action | No | No | > A short mnemonic: > `stopPropagation()` means "do not go any higher", > `preventDefault()` means "do not do the default thing", > `stopImmediatePropagation()` means "stop everything, even the neighbours". ### Common mistakes - **Confusing it with `preventDefault()`.** The first controls the event's route, the second controls the browser's default action. To both keep a form event from bubbling and keep it from submitting you need both calls. - **Adding `stopPropagation()` just in case in every handler.** That silently breaks event delegation and global listeners on `document`, for example closing a dropdown on an outside click. - **Expecting it to disable the other handlers on the same element.** It will not, that is what `stopImmediatePropagation()` is for. - **Forgetting the capture phase.** If the listener was added with `{ capture: true }`, the call cuts the event off before it even reaches the target element. - **Writing `return false` instead of the call.** In a plain DOM handler that does nothing: this behaviour exists only in jQuery, where `return false` calls both methods at once.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.