Steven Dropper Steven Dropper - 6 months ago 22
Javascript Question

undefined variable from (this) jquery

Basically, I can't figure out why it isn't working...
The function is NOT wrapped inside the document.ready,

my function:

function expandImg(){
var imgsrc = $(this).attr("src");
$("#expander").css("display","block");
$("#expander").html("<div class='close' id='close'>X</div><br /><img src='"+imgsrc+"' />");
}


and html:

<img src='/pgal/".$galeryresult."' / onClick='expandImg()'>


Note: $galeryresult is a working src variable that outputs the actual image, but when I click on it, I get undefined in
src
.. why?

Note 2:
$(this)
is a must here as I'm outputting more different imgs from one
while fetch
code

Answer

The way you're calling expandImg, this will be the global object, because you're just calling it directly: expandImg(). In JavaScript, when you call a normal function like that, in loose mode this during the call will be the global object (window on browsers); in strict mode, this during the call will be undefined. I don't think you can ever enable strict mode in onXyz attributes, so I think it would always be the global object.

You'd have to either use call, change your function, or (probably best) use modern event handling.

1. Using call:

onclick='expandImg.call(this)'

2. Changing your function:

onclick='expandImg(this)'

...then use the argument you're passing in instead of this:

function expandImg(img){
            var imgsrc = img.src; // Or $(img).attr("src"), but there's no need
            $("#expander").css("display","block");
            $("#expander").html("<div class='close' id='close'>X</div><br /><img src='"+imgsrc+"' />");
}

3. Using modern event handling:

Don't use onXyz attribuets at all, instead hook up the function with jQuery:

<img src='...' id="gallery-result">

then

$("#gallery-result").on("click", expandImg);

(You don't have to use an id, you can use any CSS selector.) Ensure that the code runs once the element exists (or look into event delegation).

Here's an event delegation example:

$(document.body).on("click", ".foo", function() {
  alert("src: " + this.src);
});
First image:
<div><img class="foo" src="https://www.gravatar.com/avatar/b51b0bf2dc8fb2091865cba7264b89d4?s=32&d=identicon&r=PG&f=1"></div>
Second image:
<div><img class="foo" src="https://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG"></div>
Click each of the above.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

That's using document.body, but there's usually a container nearer to the group of elements that you can use to be more targeted.

Comments