1

I'm trying to preview image in specific class that has the same index value of another class, from where the user selects an image. So far I have done this. When I give a specific value to the output class index the image shows up in that specific class

var input = document.getElementsByClassName("input");
var output = document.getElementsByClassName("output");

for (i = 0; i < input.length; i++) {
    input[i].onchange = function() {
            output[0].src = URL.createObjectURL(event.target.files[0]);
     }
}

However when I try to pass the 'i' variable to that class's index the code doesn't work.

var input = document.getElementsByClassName("input");
var output = document.getElementsByClassName("output");

for (i = 0; i < input.length; i++) {
    input[i].onchange = function() {
            output[i].src = URL.createObjectURL(event.target.files[0]);
     }
}

How can I solve this?

Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
Nooglers BIT
  • 71
  • 2
  • 11

1 Answers1

2

In this code you have used a closure function.When the function is invoked, it is created a single context.

Read more about, here.

One method is to use Immediately-invoked function expression, something like this:

for (i = 0; i < input.length; i++) {        
    (function(index){
        input[index].onchange = function() {
            output[index].src = URL.createObjectURL(event.target.files[0]);
        }
    }(i));
}

Here is an example where closures are used in wrong way.

var input=document.getElementsByClassName('abc');
for (i = 0; i < input.length; i++) {   
        input[i].onclick = function() {
            console.log(i);
        }
}
<button class="abc">Button1</button>
<button class="abc">Button2</button>
<button class="abc">Button3</button>

As you can see, anything button you clicked, console.log display 3.

Why it is this behavior ?

It is created a single context. When for loop is finished, the value of i remain 3 and whenever you clicked one button, this value is display in console.

How can we resolve this problem ?

One method is to use IIFE, as I mentioned above.

var input=document.getElementsByClassName('abc');
for (i = 0; i < input.length; i++) {   
      (function(index){
        input[index].onclick = function() {
            console.log(index);
        }
      }(i)); 

}
<button class="abc">Button1</button>
<button class="abc">Button2</button>
<button class="abc">Button3</button>
Community
  • 1
  • 1
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128