32. Discuss the differences between event propagation and event bubbling in the DOM.
medium
In HTML, events are used to trigger specific actions when certain user interactions occur on a web page. When an event is triggered, it starts with the element that fired the event and then propagates to its ancestors or parent elements until it reaches the root of the DOM tree.

Event propagation refers to this process of moving an event upwards from its source element to its ancestor elements until it reaches its final destination. In contrast, event bubbling is the default behavior in which events propagate from their source element downwards to its descendants.

Here's an example to illustrate the difference between event propagation and bubbling:
<div id="parent">
  <button id="child1">Child 1</button>
  <button id="child2">Child 2</button>
</div>

Suppose we add an `onclick` event handler to the parent element that logs a message:
const parent = document.getElementById('parent');
parent.addEventListener('click', (event) => {
  console.log('Parent clicked!');
});
If we now click on one of the child buttons, we would expect both child buttons to log the message "Parent clicked!" since it is bubbling downwards from parent to children. However, if we add an `onclick` event handler to the first child button that also logs a message:
const child1 = document.getElementById('child1');
child1.addEventListener('click', (event) => {
  console.log('Child 1 clicked!');
});
Now, when we click on child button 1, the "Parent clicked!" message would be logged only once, since the event is propagating upwards from the child to its parent and stopping there. On the other hand, if we click on child button 2, both messages ("Child 1 clicked!") and ("Parent clicked!") would be logged since bubbling would continue downwards from the parent to its descendants.

In summary, event propagation refers to the upward movement of an event from its source element to its ancestor elements until it reaches its final destination, while event bubbling is the default behavior in which events propagate downwards from their source element to its descendants. We can use event propagation to control how events are handled and prevent unwanted events from propagating too far up the DOM tree.