0

This seems like it should be an easy fix. The code lets the user click on either a header, paragraph, or image and identifies what type the element is. It works but then gets stuck in an infinite loop. It appears to be continuing to try and run the same code. I read A LOT of similar questions but the suggestions to use .one or other methods haven't worked.

$(document).ready(function() {
  
  const elementsToMatch = ['h1', 'p' , 'img']
  const elementsMessage = ['This is a heading', 'This is a paragraph' , 'This is an image']

  $('*').click(function(e) {
    const target = $(e.target)
    elementsToMatch.forEach(function(element, index) {
      
    if (target.is(element, index)) {
      alert(elementsMessage[index]);
    };
  });
});
Dharman
  • 30,962
  • 25
  • 85
  • 135
reduxredux
  • 23
  • 1
  • 4
  • Did you check [this](https://stackoverflow.com/questions/14969960/jquery-click-events-firing-multiple-times) post ? – Swati Jun 08 '21 at 04:46
  • Per @swati's link, I tried `.off()`, `.one()`, and `.unbind()`, and nothing worked until I got to `.stopPropagation()` and `event.stopImmediatePropagation()` – Kinglish Jun 08 '21 at 06:07
  • I don't get why propagation caused the click event to repeat 3 times despite how many elements were on the page (though clicking on the background only ever produced a single event). – Kinglish Jun 08 '21 at 06:08
  • @Kinglish Using ``` $('*').click(function(e) { event.stopPropagation()``` did indeed work. Thank you so much – reduxredux Jun 08 '21 at 14:13
  • Does this answer your question? [jQuery click events firing multiple times](https://stackoverflow.com/questions/14969960/jquery-click-events-firing-multiple-times) – Dharman Jun 29 '21 at 18:04

1 Answers1

1

This is not another explanation of what went wrong with your code but rather an alternative way of doing what - I assume - was your intention:

$(document).ready(function() {
  const msgs = {H1:'This is a heading',P: 'This is a paragraph', IMG:'This is an image'};
  $('body').on("click","H1,P,IMG",function(e) {
  console.log(msgs[this.tagName]);
  });
});
<script src=" https://code.jquery.com/jquery-3.6.0.min.js"></script>
<h1>This is a heading</h1>
<p>a paragraph and below, an image:</p>
<img src="hello.jpg">

The click element was not attached to * as this would cause three events to be fired each time a click is observed in any of the target elements (for the target element itself and also for the body and the html element). Instead I am using a "delegated" event handling on the parent body element, Limited to the elements "H1,P,IMG".

Having returned to this question years later I noticed that there is of course also a simple a non-jQuery answer for it:

window.onload=()=>{
  const msgs = {H1:'This is a heading',P: 'This is a paragraph', IMG:'This is an image'};
  document.body.onclick=e=>
    Object.keys(msgs).includes(e.target.tagName) && console.log(msgs[e.target.tagName]);
};
<h1>This is a heading</h1>
<p>a paragraph and below, an image:</p>
<img src="hello.jpg">
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43