1

from a querySelectorAll I retrieve every objects from a specific class
(list - all the same but with specific value inside...) :
- I create buttons (event) for each objects
- Each object have a specific value
- When clicking on one object. I need to show this specific value contained inside this object.

I'm currently doing it with pure javascript

I use tree HMTL node to move inside and take the data. But whenever, these objects are clicked it's only the last object value come up...

----- EDIT : html added-----

function hello(d)
{
alert("" + d);
}

var Images = document.querySelectorAll('.block-image_carousel-single > figcaption');

for (var i = 0; i < Images.length; i++) {

var Image = Images[i];

Image.addEventListener('click', function (event) {  

    event.preventDefault();

    hello(Image.textContent);
}, false);
}
<div class="block-image_carousel">
<div>
   <div class="block-main-image_carousel-display">
      <img src="img.png" class="block-image_carousel-display">
      <figcaption> Image 1 </figcaption>
   </div>
   <div class="block-image_carousel-single">
      <img src="img.png">
      <figcaption> Image 1 </figcaption>
   </div>
   <div class="block-image_carousel-single">
      <img src="img.png">
      <figcaption> Image 2 </figcaption>
   </div>
   <div class="block-image_carousel-single">
      <img src="img.png">
      <figcaption> Image 3 </figcaption>
   </div>
   <div class="block-image_carousel-single">
      <img src="img.png">
      <figcaption> Image 4 </figcaption>
   </div>
</div>
</div>
  • When clicking on one object. I need to show this specific value contained inside this object.
  • But whenever, these objects are clicked it's only the last object value come up...

ANSWER : use let instead of var for image.

CharlieWhite
  • 133
  • 1
  • 12
  • replace the `var` keyword inside your loop (`var i = 0`) to `let`.. it should do the trick :) – ymz Jan 16 '19 at 18:07
  • 2
    ^.. + you're overriding the collection in the loop, use a different variable name. See [this post](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) to better understand ymz'es comment. – Teemu Jan 16 '19 at 18:08
  • Please post your HTML too. – AndrewL64 Jan 16 '19 at 18:10
  • 2
    `var Image = Images[i];` should be `let Image = Images[i];`.. when using **var** you are overriding the **same** variable. **let** will allow you to allocate **different** space in memory, hence preserve the original image reference for each event – ymz Jan 16 '19 at 18:14
  • 1
    @ymz pretty nice trick to change var by let ;) I'm going to learn more about this – CharlieWhite Jan 16 '19 at 18:30
  • Read this https://stackoverflow.com/q/19586137/4650675 – Niraj Kaushal Jan 16 '19 at 18:38

4 Answers4

1

Remove the for loop and use the forEach() method instead to add a click listener to each element and extract the textContent from each figcaption inside the element.


Check and run the following Code Snippet for a practical example of what I described above:

function hello(d) { alert("" + d) }

var images = document.querySelectorAll('.block-image_carousel-single > figcaption');

images.forEach(image => {
  image.addEventListener('click', function(e) {
    e.preventDefault();
    hello(image.textContent);
  }, false);
});
<div class="block-image_carousel">
  <div>
    <div class="block-main-image_carousel-display">
      <img src="https://picsum.photos/1000/200" class="block-image_carousel-display">
      <figcaption> Image 1 </figcaption>
    </div>
    <div class="block-image_carousel-single">
      <img src="https://picsum.photos/100/100">
      <figcaption> Image 1 </figcaption>
    </div>
    <div class="block-image_carousel-single">
      <img src="https://picsum.photos/100/100">
      <figcaption> Image 2 </figcaption>
    </div>
    <div class="block-image_carousel-single">
      <img src="https://picsum.photos/100/100">
      <figcaption> Image 3 </figcaption>
    </div>
    <div class="block-image_carousel-single">
      <img src="https://picsum.photos/100/100">
      <figcaption> Image 4 </figcaption>
    </div>
  </div>
</div>
AndrewL64
  • 15,794
  • 8
  • 47
  • 79
0

Try this

function hello(f,d)
{
    alert(f,d);
}

var Images = document.querySelectorAll('.block-image_carousel-single > figcaption');

for (var i = 0; i < Images.length; i++) {

    var Image = Images[i];

    Image.addEventListener('click', function (event) {  

        event.preventDefault();

        hello(this, Image.textContent);
    }, false);
}
Niraj Kaushal
  • 1,452
  • 2
  • 13
  • 20
0

Your code is overwriting the "Images" var in the for loop, and only the last instance in the loop is being saved to Images. Also you defined Images twice?

Try modifying your code to this:

   function hello(f,d)
{
alert(f,d);
}

var Images = document.querySelectorAll('.block-image_carousel-single > figcaption');
for (var i = 0; i < Images.length; i++) {

Images[i].addEventListener('click', function (event) { 
event.preventDefault();

hello(this, Images.textContent);
},false);
}
Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
0

Your issue is variable scoping, when the for loop ends the variable contains the last value.

You may use this.textContent in the event handler instead of Image.textContent. Or you may use let instead of var in the for loop. Another way to solve it is with IIFE

function hello(d) {
    alert("" + d);
}

var Images = document.querySelectorAll('.block-image_carousel-single > figcaption');
for (var i = 0; i < Images.length; i++) {
    var Image = Images[i];
    Image.addEventListener('click', function (event) {
        event.preventDefault();
        hello(this.textContent);
    }, false);
}

//
// ...loop using let
//
for (let i = 0; i < Images.length; i++) {
    var Image = Images[i];
    Image.addEventListener('click', function (event) {
        event.preventDefault();
        hello(Images[i].textContent);
    }, false);
}
<div class="block-image_carousel">
    <div>
        <div class="block-image_carousel-single">
            <img src="/media/images/irbOgrandOparis-17-png_956449_1505405590__B-.max-940x640.png" class="block-image_carousel-display">
            <figcaption> Image 0 </figcaption>
        </div>
        <div class="block-image_carousel-single">
            <img src="/media/images/irbOgrandOparis-17-png_956449_1505405590__B-.max-940x640.png">
            <figcaption> Image 1 </figcaption>
        </div>
        <div class="block-image_carousel-single">
            <img src="/media/images/irbOgrandOparis-17-png_956449_1505405590__B-.max-940x640.png">
            <figcaption> Image 2 </figcaption>
        </div>
        <div class="block-image_carousel-single">
            <img src="/media/images/irbOgrandOparis-17-png_956449_1505405590__B-.max-940x640.png">
            <figcaption> Image 3 </figcaption>
        </div>
        <div class="block-image_carousel-single">
            <img src="/media/images/irbOgrandOparis-17-png_956449_1505405590__B-.max-940x640.png">
            <figcaption> Image 4 </figcaption>
        </div>
    </div>
</div>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61