0

I have several images like this:

    <img id="geqfader" frequency="100" src="img/fader.png" />
    <img id="geqfader" frequency="400" src="img/fader.png" />
    <img id="geqfader" frequency="1600" src="img/fader.png" />
    <img id="geqfader" frequency="6300" src="img/fader.png" />

When the user clicks on an image, I want to invoke a function and pass on the value of frequency:

  document.getElementById('geqfader').addEventListener('click', function() {
    showResult(hereIWantTheFrequencyValue, toneFrequency)
  });

How can I pass the image frequency value into showResult (where hereIWantTheFrequencyValue is)?

Max
  • 386
  • 3
  • 16
  • 1
    Ids have to be _unique_. Use a class instead. `frequency` should be `data-frequency` to produce valid markup. Then use `querySelectorAll()` or `getElementsByClassName()` to get the elements and `this` and `dataset` in the event handler to get the value. – Andreas Sep 08 '18 at 11:52
  • @Andreas thanks, I'll consider using another attribute then :) – Max Sep 08 '18 at 12:00

4 Answers4

1

replace all ids with class and set onclick="showValue(this)" to all img tags like code below...

        <img class="geqfader" onclick="showValue(this)" frequency="100" src="img/fader.png" />
        <img class="geqfader" onclick="showValue(this)" frequency="400" src="img/fader.png" />
        <img class="geqfader" onclick="showValue(this)" frequency="1600" src="img/fader.png" />
        <img class="geqfader" onclick="showValue(this)" frequency="6300" src="img/fader.png" />


<script>

function showValue(img){
  alert(img.getAttribute('frequency'));
}

</script>
Akbar Soft
  • 1,028
  • 10
  • 19
  • This was by far the easiest working solution, but I accepted the other answer to have better separation between HTML & JavaScript. If I could accept multiple answers, I would also accept this one! – Max Sep 09 '18 at 10:25
1

In HTML the id value should be unique value for each element. In situation like yours, you can use a custom attribute on your elements. To get the element using your custom attribute you can use querySelectorAll function in JavaScript as shown in the following example:

let elms = document.querySelectorAll('[my_id="geqfader"]');

for(let elm of elms){
elm.addEventListener('click', function(e) {
    console.log(e.target.getAttribute('frequency'))
  });
}
<img my_id="geqfader" frequency="100" src="img/fader.png" />
<img my_id="geqfader" frequency="400" src="img/fader.png" />
<img my_id="geqfader" frequency="1600" src="img/fader.png" />
<img my_id="geqfader" frequency="6300" src="img/fader.png" />

EDIT As an alternative I suggest you to use the class attribute instead of a custom attribute which allows you to use the getElementsByClassName function instead of querySelectorAll. Also, the data- prefix gives us the ability to use custom data attributes.

let elms = document.getElementsByClassName('geqfader');

for(let elm of elms){
elm.addEventListener('click', function(e) {
    console.log(e.target.getAttribute('frequency'))
  });
}
<img class="geqfader" data-frequency="100" src="img/fader.png" />
<img class="geqfader" data-frequency="400" src="img/fader.png" />
<img class="geqfader" data-frequency="1600" src="img/fader.png" />
<img class="geqfader" data-frequency="6300" src="img/fader.png" />
Max
  • 386
  • 3
  • 16
pouyan
  • 3,445
  • 4
  • 26
  • 44
  • @Andreas just in case that maybe in some situation new attributes would be needed( i tried to answer question in more general form. but you are right and i personally prefer to use class instead, so i will edit my answer and will mention this approach). – pouyan Sep 08 '18 at 12:12
  • Thanks for helping out. What is the reason for using a `for` loop? Can't I just use `.addEventListener` on `document.getElementsByClassName()`? – Max Sep 08 '18 at 12:20
  • your welcome, `getElementsByClassName()` will return array of elements so you have to loop throughout all of your elements and attach event listener to them. – pouyan Sep 08 '18 at 12:24
  • Thanks. Your answer is certainly correct, but I find the other answer that uses `onclick` in the img tag easier to use as a beginner. I wish I could accept more than one answer ... – Max Sep 08 '18 at 12:39
  • `.getElementsByClassName()` returns a `HTMLCollection` which is an array-like structure but not an actual array. – Andreas Sep 08 '18 at 12:39
  • @Max I would go with this one (or even better use event delegation if there's a common parent element) - [javascript - Why Should I Avoid Inline Scripting? - Software Engineering Stack Exchange](https://softwareengineering.stackexchange.com/questions/86589/why-should-i-avoid-inline-scripting) – Andreas Sep 08 '18 at 12:42
  • _"it will needed you to use `getElementsByClassName` function instead of `querySelectorAll` in order to retrieview elements"_ - No id doesn't. `querySelector()` and `querySelectorAll()` work with css selectors -> `document.querySelectorAll(".geqfader")` – Andreas Sep 08 '18 at 12:44
  • @Andreas which one would be preferred - `document.getElementsByClassName()` or `document.querySelectorAll()`? In case it influences the decision, I might add `

    x Hz

    ` later on, depending on how the lay-out will turn out.
    – Max Sep 08 '18 at 12:51
  • @Max The `.querySelector` methods work with css selectors, hence you can get anything you want with them - as long as there's a valid selector for it. With the "older" `.getElements...` methods you will have to decide first if you're looking for a tagname, a class or a name. And the methods have different return values ([NodeList vs. HTMLCollection](https://stackoverflow.com/questions/15763358/difference-between-htmlcollection-nodelists-and-arrays-of-objects)), which can make your life easier or more complicated. Check their documentation on [MDN](https://developer.mozilla.org/en-US/). – Andreas Sep 08 '18 at 12:58
  • @Andreas yes you are right but for `class` selector, `getElementsByClassName` is faster than `querySelectorAll` (At least in chrome browser). – pouyan Sep 08 '18 at 13:00
  • Care to explain why you think it is "faster"? And even if this would be the case, that's unnecessary micro-optimisation. Use whatever makes your life easier. – Andreas Sep 08 '18 at 13:03
  • @Andreas [Here is the reason](https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25) – pouyan Sep 08 '18 at 13:06
0

You should learn more JavaScript and understand how the DOM and EventListener works. First of all IDs are unique, even if you can define duplicates its invalid markup. document.getElementById returns only the first matched element so your click handler is only attached to the first img.
This should work:

Array.slice.call(document.querySelectorAll("img[frequency]")).forEach(function(img) {
  img.addEventListener("click", function(e) {
    var frequency = e.target.getAttribute("frequency");
  });
});

Array.slice.call is used because querySelectorAll returns a NodeList and not an Array

Code Spirit
  • 3,992
  • 4
  • 23
  • 34
-1

event.target.getAttribute('frequency')

Where event is the argument that the event handler function takes as argument.

Ertan Kara
  • 308
  • 3
  • 12
  • `event.target === this` but this won't work either as the event handler only would be added to the first image. – Andreas Sep 08 '18 at 12:00