3

This is part of a function that is creating a table with images and the name of the image inserted by the user.

var NameFile = [];//Where the names of the files are stored

Function handleFiles() {
var inputElement = document.getElementById("input");
var fileList = inputElement.files; 

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

NameFile.push(fileList[i].name);
var Img = document.createElement("tr");
Img.setAttribute("id", "ImgTr" +(i));
document.getElementById("galeria" +(i)).appendChild(Img);

/.../

var Img = document.createElement("tr");
Img.setAttribute("id", "ImgTr" +(i));
document.getElementById("galeria" +(i)).appendChild(Img);

var Imgz = document.createElement("td");
var image =document.createElement("img");
image.setAttribute("id", "imageID" +(i));
image.setAttribute("className", "bordered");
image.setAttribute("src","http://placehold.it/200/200/pink/black");
image.setAttribute("onclick","imgClick(this)");

image.src = window.URL.createObjectURL(fileList[i]);
  image.height = 50;
  image.with = 50;
  image.onload = function(){
    window.URL.revokeObjectURL(this.src);
  }

Now this is the function i want to call if the image is clicked on. This function is supposed to show a border around the image clicked by the user.

 function imgClick(img) {

 if (img.className.indexOf('bordered') > -1) {
 img.className = img.className.replace('bordered', '').trim();
 } else {
 img.className += ' bordered';
 }

It compares the img clicked id atributte with the others images ids, and when it equals it shows the name of the file stored in the array NameFile

 for( var i=0; i<NameFile.length;i++){
 if("imageID"+[i]===img.getAttribute("id")){ 
 alert(NameFile[i]);
 }
 }
 }
1
  • 1
    Set the property directly image.onclick = imgClick Commented May 11, 2018 at 9:27

6 Answers 6

5

The problem mostly lies with this line:

var imgTag=document.getElementsByTagName('img');

as document.getElementsByTagName('img'); returns a HTMLCollection and not a single element. So when you try setting the style prop, you are doing it on the HTMLCollection and not the actual node

Try this instead:

function imgClick(img){
  img.style.border = '5px solid pink';
}

var img = document.createElement('img');
img.setAttribute('src','http://placehold.it/200/200/pink/black');
img.setAttribute('onclick','imgClick(this)');

document.body.append(img);

EDIT:

If you want the second click to remove the border, there are several ways to do it. One way would be to add a class to the element when it is clicked once. We can then check for the class each time it is clicked to decide whether to add the border or remove it.

Sample:

function imgClick(img) {
  if (img.className.indexOf('bordered') > -1) {
    // Already has border
    img.style.border = 'none';
    img.className = img.className.replace('bordered', '').trim();
  } else {
    // Does not have border
    img.style.border = '5px solid pink';
    img.className += ' bordered';
  }

}

var img = document.createElement('img');
img.setAttribute('src', 'http://placehold.it/200/200/pink/black');
img.setAttribute('onclick', 'imgClick(this)');

document.body.append(img);

Note: If the styling of the border does not change, you can move the styling out to a CSS style and just toggle the class on the image like this:

function imgClick(img) {
  if (img.className.indexOf('bordered') > -1) {
    img.className = img.className.replace('bordered', '').trim();
  } else {
    img.className += ' bordered';
  }

}

var img = document.createElement('img');
img.setAttribute('src', 'http://placehold.it/200/200/pink/black');
img.setAttribute('onclick', 'imgClick(this)');

document.body.append(img);
img.bordered{
  border: 3px solid pink;
}

EDIT 2:

You can retrieve the file name as you set it and update your array

// Initialize empty array
var myImages = [];
function imgClick(img) {
  // Add image file name to array after getting it from data attribute
  myImages.push(img.dataset.name);
  console.log(myImages);
}

function appendImage() {
  var img = document.createElement('img');
  var file = document.getElementById('file_in').files[0];
  var url = window.URL.createObjectURL(file);
  img.setAttribute('src', url);
  img.setAttribute('onclick', 'imgClick(this)');
  // Set the file name as a data attribute for later use
  img.dataset.name = file.name;

  document.body.append(img);
}
img.bordered {
  border: 3px solid pink;
}
<input type=file id="file_in" />
<button onclick="appendImage()">Upload</button>

Sign up to request clarification or add additional context in comments.

7 Comments

it worked like a charm, now if i want to on the second click erase the border, how do i do this?
There are many ways to do that. I have updated the answer with one way of doing this.
Just one more little question, i have an array (var NameFile = [];) that stores the files names and i want to show the filename of the image clicked, how do i access it, i try with " ( function imgClick(img, NameFile) alert(img.NameFile); ) but it shows undefined, how can i do this. thanks in advanced
What do you mean by file name? You can access the URL used to access the image from the src. Is the filename a part of the URL? See this related question on SO and feel free to come back if that does not help
The user inserts an image through an input button, that image has name and that is the file name. I took a look at what u send and it shoes the url of the image, in this case the mac adress, cause im using a mac
|
1

Instead of adding an "onclick" attribute, I strongly advise you add an event listener to your img element.

image.addEventListener("click", imgClick);

There is also an issue in your imgClick function : you don't need to look for your img element in there. You can instead add an event variable to your function declaration. That way you can retrieve the events target and do whatever you want with it :

function imgClick(event) {
    event.target.style.border='2px solid #33cc33';
}

Comments

1

You can access to clicked item using event.target, like so:

function imgClick(e) {  
  e.target.style.border = '2px solid #33cc33';  
}        

And bind event like below (as you did in your code):

image.onclick = imgClick;

Or using addEventListener:

image.addEventListener("click", imgClick, false);

Notice that var imgTag = document.getElementsByTagName('img') returns array (like) of found item(s)/node(s), so imgTag.style... won't work.

Comments

1

If you want to set onclick, then you need to set the property directly

image.onclick = imgClick;

Better solution would be to add event listener instead

image.addEventListener( "click", imgClick ); 

And you imgClick method becomes

function imgClick(e){      
    var imgTag = e.currentTarget;
    imgTag.onload = function()
    {
        window.URL.revokeObjectURL( imgTag.src );
        imgTag.hasImageLoaded = true;
    }
    if ( imgTag.hasImageLoaded )
    {
        imgTag.style.border = '2px solid #33cc33';
    }
}

or

function imgClick(e){
    var imgTag = e.currentTarget;
    imgTag.addEventListener("load", function()
    {
        window.URL.revokeObjectURL( imgTag.src );
        imgTag.hasImageLoaded = true;
    });
    if ( imgTag.hasImageLoaded )
    {
        imgTag.style.border = '2px solid #33cc33';
    }
}

Comments

1

setting onclick as attribute will not set the event on image you have assign onclick to image

image.onclick = imgclick

Comments

1

Also you can create the image with the HTMLInstance:

<div id="gallery"></div>

<script>
function createImg(src, height, weight, onclick) {
    const img = new Image(height, weight)
    img.src = src
    img.onclick = onclick
    return img
}

function addNewImage(image) {
    gallery.appendChild(image)
}

function handleClick () {
    alert('Image catch click event!')
}

const src = 'https://loremflickr.com/320/240'
const img1 = createImg(src, 100, 100, handleClick)

addNewImage(img1)
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.