1

The problem:

I have 134 elements which must have an onclick event attached. I am doing this by now, on eeeeeeevery single one of them (and they have an ondbclick event attached too!):

<div id="id1" class="name" onclick="functionName(this.id)"></div>
<div id="id2" class="name" onclick="functionName(this.id)"></div>
<div id="id3" class="name" onclick="functionName(this.id)"></div>

but read in Eloquent Javascript (chapter 14) that this is considered bad practice, since it mixes html and javascript.

So I thought I could find a way to attach the onclick event to all of them together. I searched a few hours and tried a few things, like this: (from 'How do you set a JavaScript onclick event to a class with css' here on stackoverflow)

window.onload = function() {
    var elements = document.getElementsByClassName('nameOfTheClass');
    for(var i = 0; i < elements.length; i++) {
        var OneElement = elements[i];
        OneElement.onclick = function() {
           //do something
        }
    }
}

Which got the click to work on the elements, but not my function.

My original function was receiving two values, the id and the innerHTML of the element that got clicked, and now I cannot find a way to access that information.

I tried OneElement.id and OneElement.innerHTML just to find out that it gets the id and innerHTML of the last of the elements in the document.

Any clues? Any help very much appreciated! :)

  • 2
    You need to pass in the event object. That will give you access to the element's properties including id and innerhtml. – Govind Rai Nov 05 '17 at 19:18
  • Possible duplicate of [Getting the ID of the element that fired an event](https://stackoverflow.com/questions/48239/getting-the-id-of-the-element-that-fired-an-event) – PM 77-1 Nov 05 '17 at 19:20
  • @GovindRai, ok, I will read about it. Thanks! –  Nov 05 '17 at 19:20
  • inside event handler the target element (`OneElement` in OP) is available as **`this`** with all its properties like `this.id`, `this.innerHTML`, and so on. – Alex Kudryashev Nov 05 '17 at 19:25
  • @MrUnity you might take a look at this answer: https://stackoverflow.com/a/6348597/1156518 – Dmitry Druganov Nov 05 '17 at 19:54

3 Answers3

5

When an event is triggered in JavaScript, JavaScript passes an event object to the callback function. Pass that into the signature and you will gain access to element properties.

window.onload = function() {
    const elements = document.getElementsByClassName('nameOfTheClass');
    
    for (const element of elements) {
        element.addEventListener("click", e => {
            console.log("element was clicked", e.target.id, e.target.innerHTML);
        })
    }
}
Govind Rai
  • 14,406
  • 9
  • 72
  • 83
  • Another question: is it better to use this approach or the one using addEventListener?. I mean what is considered to be better practice? –  Nov 05 '17 at 19:31
  • 1
    It depends on your use case. Neither is wrong. If you need multiple events to be triggered on a click, for example, then you must use addEventListener. Otherwise you can stick to this approach. – Govind Rai Nov 05 '17 at 19:34
0
<div id="id1" class="name">first</div>
<div id="id2" class="name">second</div>
<div id="id3" class="name">third</div>
<script type="text/javascript">
  var nodes = document.querySelectorAll('.name');
  Array.from(nodes).forEach(function (node) {
    node.addEventListener('click', function (event) {
      alert('you clicked' + event.target.textContent + ' with id: ' + event.target.getAttribute('id'));
      // you might also use event.target.innerHTML here
    });
  });
</script>
Dmitry Druganov
  • 2,088
  • 3
  • 23
  • 32
  • Thank you Dmitry for your answer, since I am starting on this I will prefer the next answer, it seems a little easier for me to understand. –  Nov 05 '17 at 19:28
0

There are two DOM apis I would recommend you use:

  1. document.querySelector and document.querySelectorAll and
  2. element.addEventListener('click', event => {/* ... */});

Those are my gotos for "vanilla js" dom manipulation.

See the example below for what you wanted.

Array.from(document.querySelectorAll('.name')).forEach(element => {
  // for each element that matches the querySelector `.name`
  element.addEventListener('click', clickEvent => {
    // call your function when the element is clicked
    // see the properties of a Dom Element here:
    // https://developer.mozilla.org/en-US/docs/Web/API/Element
    yourFunction(element.id, element.innerHTML);
  });
})

function yourFunction(id, innerHtml) {
  // use the values!
  console.log({id, innerHtml});
}
<div id="id1" class="name">[click me] inner html 1</div>
<div id="id2" class="name">[click me] inner html 2</div>
<div id="id3" class="name">[click me] inner html 3</div>
Rico Kahler
  • 17,616
  • 11
  • 59
  • 85