Jossie Calderon
Jossie Calderon

Reputation: 1425

Image reading as "undefined" by JavaScript

I tested the below code for one image and it worked:

  let imageName1 = document.getElementById("the-edge");

  imageName1.onclick = function(element) {

    // Create the link to be copied
    hyperlink = imageName1.alt
    imgOpen = "[img]"
    imgClose = "[/img]"
    link = imgOpen.concat(hyperlink, imgClose)

    // Create a dummy TextArea to copy text 
    var dummy = document.createElement("textarea")
    document.body.appendChild(dummy)
    dummy.value = link
    dummy.select()

    document.execCommand("copy")
    document.body.removeChild(dummy)
  };  

Now I tried to do this onclick for three images.

  let images = document.getElementsByTagName("img");
  console.log(images)

  for(var i = 0; i < images.length; i++) {
      images[i].onclick = function(element) {

      // Create the link to be copied
      hyperlink = images[i].alt // THROWS THE ERROR HERE
      imgOpen = "[img]"
      imgClose = "[/img]"
      link = imgOpen.concat(hyperlink, imgClose)

      // Create a dummy TextArea to copy text 
      var dummy = document.createElement("textarea")
      document.body.appendChild(dummy)
      dummy.value = link
      dummy.select()

      document.execCommand("copy")
      document.body.removeChild(dummy)

      }
  }

Finally I got the error that Uncaught TypeError: Cannot read property 'alt' of undefined at the line hyperlink = images[i].alt.

But how can it be undefined? console.log(images) outputs

HTMLCollection(3) 0: img#the-edge 1: img#the-rock 2: img#emma-stone length: 3 emma-stone: img#emma-stone the-edge: img#the-edge the-rock: img#the-rock __proto__: HTMLCollection

I created a separate loop to store the alt before going onto the onclick section and it really is undefined, but why? doesn't the image have an alt? I've defined it so. And the first code worked!

Upvotes: 1

Views: 96

Answers (1)

Juliano Bez
Juliano Bez

Reputation: 24

This problem occurs due to the context of counter i.

The value of i at the time the onclick is called is 3 and therefore the mentioned error occurs.

Another error is that the function onclick argument is not element, but event.

To access the element within the onclick function, you must use event.target.

The correct function is as follows:

let images = document.getElementsByTagName("img");
console.log(images)
for (var i = 0; i < images.length; i++) {
    images[i].onclick = function (event) {
        // Create the link to be copied
        hyperlink = event.target.alt //EVENT.TARGET = ELEMENT

        imgOpen = "[img]"
        imgClose = "[/img]"
        link = imgOpen.concat(hyperlink, imgClose)
        console.log(link)


        // Create a dummy TextArea to copy text 
        var dummy = document.createElement("textarea")
        document.body.appendChild(dummy)
        dummy.value = link
        dummy.select()

        document.execCommand("copy")
        document.body.removeChild(dummy)

    }
}

EDIT

Another way to do the same thing is as follows:

<html>

<head></head>

<body>
    <img alt='teste 0' id="the-edge">
    <img alt='teste 1' id="the-rock">
    <img alt='teste 2' id="emma-stone">

</body>
<script>
    let images = document.getElementsByTagName("img");
    console.log(images)
    // image is one item of images
    for (let image of images) {
        //image is used by reference here. on updating image, you are updating too images[x]
        image.onclick = function (event) {
            // Create the link to be copied
            hyperlink = event.target.alt // THROWS THE ERROR HERE

            imgOpen = "[img]"
            imgClose = "[/img]"
            link = imgOpen.concat(hyperlink, imgClose)
            console.log(link)


            // Create a dummy TextArea to copy text 
            var dummy = document.createElement("textarea")
            document.body.appendChild(dummy)
            dummy.value = link
            dummy.select()

            document.execCommand("copy")
            document.body.removeChild(dummy)

        }
    }
</script>

</html>

Hope this helps!

Upvotes: 1

Related Questions