Search code examples
javascripthtmlcssprogressive-web-appsaddeventlistener

When i click on specific tag i want it to show its unique value but it keeps showing only the first value


The output will always be goodbye even when clicked on hello

How to identify and get unique values from the specific tags?

addEventListener('click', function(e) {
  if (e.target && e.target.id == 'democlass') {
    var x = document.getElementsByTagName("H1")[0].getAttribute("value");
    document.getElementById("demo").innerHTML = x;
  }
});
#democlass {
  color: red;
}
<h1 id="democlass" value="Goodbye">Goodbye </h1>
<h1 id="democlass" value="Hello ">Hello </h1>

<p>Click the button to display the value of the id of the h1 element.</p>


<p id="demo">Here lies new text</p>


Solution

    1. IDs must be unique. No two elements can share the same ID. If you want to group elements I suggest switching to classes instead.

    2. In addition I don't think the value attribute on an H1 element is valid HTML, so select the text content instead.

    This example adds an event listener to the document but doesn't use classes. It checks the nodeName instead.

    const demo = document.querySelector('#demo');
    
    document.addEventListener('click', function(e) {
      const { target: { nodeName } } = e;
      if (nodeName === 'H1') {
        const value = e.target.textContent;
        demo.textContent = value;
      }
    });
    #democlass {
      color: red;
    }
    <h1>Goodbye</h1>
    <h1>Hello</h1>
    
    <p>Click the button to display the value of the class attribute of the h1 element.</p>
    
    <p id="demo">Here lies new text</p>

    Instead of setting an event listener at document level you might want to just target the headings. In this example I've used classes:

    const demo = document.querySelector('#demo');
    const h1s = document.querySelectorAll('.democlass');
    
    h1s.forEach(h1 => h1.addEventListener('click', handleClick, false));
    
    function handleClick(e) {
      const value = e.target.textContent;
      demo.textContent = value;
    }
    #democlass {
      color: red;
    }
    <h1 class="democlass">Goodbye</h1>
    <h1 class="democlass">Hello</h1>
    
    <p>Click the button to display the value of the class attribute of the h1 element.</p>
    
    <p id="demo">Here lies new text</p>

    But you might not want to add an event listener to each heading. What if, instead of two headings, you had 100. Well, you can take advantage of the fact that events "bubble up" the DOM. Event delegation allows you to add an event listener to a parent element to "catch" events as they bubble up.

    const demo = document.querySelector('#demo');
    const container = document.querySelector('.container');
    
    container.addEventListener('click', handleClick, false);
    
    function handleClick(e) {
      const { target: { textContent } } = e;
      demo.textContent = textContent;
    }
    #democlass {
      color: red;
    }
    <div class="container">
      <h1 class="democlass">Goodbye</h1>
      <h1 class="democlass">Hello</h1>
    </div>
    
    <p>Click the button to display the value of the class attribute of the h1 element.</p>
    
    <p id="demo">Here lies new text</p>