Go Back   CodingForums.com > :: Client side development > JavaScript programming > JavaScript frameworks

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 07-06-2010, 05:37 PM   PM User | #1
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
"this" confusion

I'm confused on how "this" works visavi jQuery bindings.

function Foo()
{
this.stuff = 0;
this.callback = function()
{
$(this).attr('src', '...'+this.stuff);
};
$('#image_id').load( this.callback );
}

For $("#image_id")... will the callback method be called?
For the callback method, will using "$(this)" act as if it was "$("#image_id")"? If so, how does the method know the difference between the image's "this" and the object's "this"? (to be exact, will it be able to access "this.stuff")
Apothem is offline   Reply With Quote
Old 07-06-2010, 06:15 PM   PM User | #2
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
This is resolved at runtime. It refers to the running context. If you attach your callback function to 25 objects and then call each of them from those objects, this will resolve 25 times to 25 difference referents.
Beagle is offline   Reply With Quote
Old 07-06-2010, 06:23 PM   PM User | #3
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
So basically, this.stuff would in fact output its setted value (0) and $(this) would also work? What if I called another method within the callback method? Could I still use $(this) to refer back to the $("#image_id")?
Apothem is offline   Reply With Quote
Old 07-06-2010, 07:55 PM   PM User | #4
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
You'll have to do some basic experimentation. I'm not going to be able to answer that confidently without writing some test code first. Make a hypothesis, code an experiment, check the results. If you can't figure out why something works or doesn't work, post the code and ask your questions then.

But try it first.
Beagle is offline   Reply With Quote
Old 07-06-2010, 09:13 PM   PM User | #5
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
First:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
	<head> 
		<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
		<title>TEst</title> 
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
		<script>
(function ($) {

$.event.special.load = {
	setup: function(data, namespaces, hollaback) {
		var retVal = false;
		
		if (this.tagName.toLowerCase() === 'img' && this.src !== "") {
			// Image is already complete, fire the hollaback (fixes browser issues were cached
			// images isn't triggering the load event)
			if (this.complete || this.readyState === 4) {
				$(this).bind('load', data || {}, hollaback).trigger('load');
				retVal = true;
			}
			
			// Check if data URI images is supported, fire 'error' event if not
			else if (this.readyState === 'uninitialized' && this.src.indexOf('data:') >= 0) {
				$(this).trigger('error');
				retVal = true;
			}
		}
		
		return retVal;
	}
}

}(jQuery));

		$(document).ready(function()
		{
			function Foo()
			{
				this.stuff = 0;
				this.callback = function()
				{
					//$(this).attr('title', '...'+this.stuff);
				};
				alert('foo');
				$('#image_id').bind( 'load', function(){alert('bar');} );
			}
			
			var f = new Foo();
		});
		</script>
	</head> 
	<body> 
		<img src="http://codingforums.com/image.php?u=60583&dateline=1260771715" id="image_id" />
	</body> 
</html>
For some reason in FF 3.6.x, only the first alert pops up and nothing else.

Last edited by Apothem; 07-06-2010 at 09:17 PM..
Apothem is offline   Reply With Quote
Old 07-06-2010, 09:21 PM   PM User | #6
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
FF is throwing a "too much recursion" error inside the jQuery library. I'm reviewing the code locally now.
Beagle is offline   Reply With Quote
Old 07-06-2010, 09:30 PM   PM User | #7
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
change the alert('bar') event from 'load' to 'click' to get this working for testing purposes. I'm not interested in figuring out why the 'load' event is causing problems.
Beagle is offline   Reply With Quote
Old 07-06-2010, 10:44 PM   PM User | #8
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
Well, for my personal project I actually do need an image to complete loading to activate a function. But I will do it for testing purposes.

Regardless, I still need to know what is wrong.

Edit: So I tested it, and this.stuff doesn't work. How can I make it work?

Last edited by Apothem; 07-06-2010 at 10:52 PM..
Apothem is offline   Reply With Quote
Old 07-06-2010, 10:54 PM   PM User | #9
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
Paste the code that doesn't work please.
Beagle is offline   Reply With Quote
Old 07-06-2010, 10:58 PM   PM User | #10
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
	<head> 
		<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
		<title>TEst</title> 
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
		<script>
(function ($) {

$.event.special.load = {
	setup: function(data, namespaces, hollaback) {
		var retVal = false;
		
		if (this.tagName.toLowerCase() === 'img' && this.src !== "") {
			// Image is already complete, fire the hollaback (fixes browser issues were cached
			// images isn't triggering the load event)
			if (this.complete || this.readyState === 4) {
				$(this).bind('load', data || {}, hollaback).trigger('load');
				retVal = true;
			}
			
			// Check if data URI images is supported, fire 'error' event if not
			else if (this.readyState === 'uninitialized' && this.src.indexOf('data:') >= 0) {
				$(this).trigger('error');
				retVal = true;
			}
		}
		
		return retVal;
	}
}

}(jQuery));

		$(document).ready(function()
		{
			function Foo()
			{
				this.stuff = 0;
				this.callback = function()
				{
					$(this).attr('title', '...'+this.stuff);
				};
				//alert('foo');
				$('#image_id').click( this.callback );
			}
			
			var f = new Foo();
		});
		</script>
	</head> 
	<body> 
		<img src="http://codingforums.com/image.php?u=60583&dateline=1260771715" id="image_id" />
	</body> 
</html>
$(this).attr('title', '...'+this.stuff); results in the title "...undefined". I expected it to become "...0"
Apothem is offline   Reply With Quote
Old 07-06-2010, 11:14 PM   PM User | #11
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
Right. So, as I said, this is resolved at runtime, let's try to figure out what the means.
Code:
function Foo() {
    this.stuff = 0;
    this.callback = function() {
        $(this).attr('title', '...'+this.stuff);
    };
    $('#image_id').click( this.callback );
}
			
var f = new Foo();
So, Foo() is executing. It defines stuff and callback in the current scope. Then it assigns callback to the click handler.

Now, you have an issue. When callback is called, the running scope is different, so this is not the same as the defining context, hence stuff does not exist in it. How do we fix that? Well, one way is to make sure we always have a reference to the defining scope:
Code:
function Foo() {
    this.stuff = 0;
    var parent = this;
    this.callback = function() {
        $(this).attr('title', '...'+parent.stuff);
    };
    $('#image_id').click( this.callback );
}
			
var f = new Foo();
or, by not using the this keyword when defining the variables:
Code:
function Foo() {
    stuff = 0;
    this.callback = function() {
        $(this).attr('title', '...'+stuff);
    };
    $('#image_id').click( this.callback );
}
			
var f = new Foo();
Both of these techniques work. You can even drop the this regarding callback since callback isn't directly referred to by name outside of it's defining scope.

Hope that helps!
Beagle is offline   Reply With Quote
Old 07-06-2010, 11:19 PM   PM User | #12
Apothem
Regular Coder

 
Apothem's Avatar
 
Join Date: Mar 2008
Posts: 380
Thanks: 36
Thanked 25 Times in 25 Posts
Apothem is an unknown quantity at this point
Wait I thought that if you don't do this.var that means it is a global variable. I don't want a global variable; I want an object element so that multiple constructions can be made.
Apothem is offline   Reply With Quote
Old 07-06-2010, 11:28 PM   PM User | #13
Beagle
Senior Coder

 
Join Date: Jul 2005
Location: New York, NY
Posts: 1,084
Thanks: 4
Thanked 19 Times in 19 Posts
Beagle is an unknown quantity at this point
Quote:
Originally Posted by Apothem View Post
Wait I thought that if you don't do this.var that means it is a global variable. I don't want a global variable; I want an object element so that multiple constructions can be made.
No. If you define a var inside a function, it's local.
Code:
function a_x() {
  var x = 'x';
  alert(x);
}

a_x(); // 'x'

alert(x); // undef
Beagle is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:33 PM.


Advertisement
Log in to turn off these ads.