How to detect variable change? object.watch?

I’ve been looking at Eli’s object.watch (https://gist.github.com/384583) script and I understand the idea of it and what it does but I’m so confused about how I actually use it in my script! Even if this seems quite obvious to most, I’m just not seeing it :S

I might even be trying the wrong approach to it entirely and object.watch isn’t what I actually need to be using!

I’ve got my script here:


<script type="text/javascript">

    jQuery.fn.elementlocation = function() {

        var curleft = 0;
        var curtop = 0;

        var obj = this;

        do {

        curleft += obj.attr('offsetLeft');
        curtop += obj.attr('offsetTop');

        obj = obj.offsetParent();

        } while ( obj.attr('tagName') != 'BODY' );


            return ( {x:curleft, y:curtop} );

    };


    $(document).ready( function() {
		
			$("#gdimage").mousemove( function( eventObj ) {

				var location = $("#gdimage").elementlocation();
				var x = eventObj.pageX - location.x;
				var y = eventObj.pageY - location.y;
	
				x = x / 5;
				y = y / 5;
	
				x = (Math.floor( x ) + 1);
				y = (Math.floor( y ) + 1);
	
				if (y > 1) {
	
					block = (y * 200) - 200;
					block = block + x;
	
				} else {
	
					block = x;
	
				}
				
				x = ((x * 2) + (x*3)) - 4;
				y = ((y * 2) + (y*3)) - 4;
				
				x = (Math.floor( x ));
				y = (Math.floor( y ));
	
				$("#block").text( block );
				$("#x_coords").text( x );
				$("#y_coords").text( y );
				
					$.ajax({
						type: "GET",
						url: "fetch.php",
						data: "x=" + x + "&y=" + y + "",
						dataType: "json",
						async: false,
						success: function(data) {
							$("#user_name_area").html(data.username);
						}
					});	
			
			$("#gdimage").click( function( eventObj ) {
				window.location = "/redirect/?x=" + x + "&y=" + y + "";
			});

        });

    });

</script>

Now as you can tell, the server load will be pretty high with the mouse move constantly calling data from the fetch.php page through AJAX. SO, what I’m trying to do is only call upon the AJAX when the variable “block” changes it’s value.

So I assume, I have to somewhere store a value, and then when the value changes check it with the stored value, but of course, the stored value will always change to the new value too since it’s all determined by constantly changing variables?

So how would I get it to only call the AJAX section when the block number changes?

You could store the block number in a jQuery data section, so that you can take action when a comparison finds that the existing block number is different from the stored one.

Sorry to sound stupid, but where and how would I add that into the script though?

Did you write that script, or did someone else do it for you?

I took parts of it from tutorials since my Javascript/jQuery is pretty limited!

I had help from SgtLegend and furicane (on these forums) with the AJAX/JSON too and the x/y/block rounding etc I did the maths for that myself. So a bit of everything really…

I’ve literally sat for hours trying to understand the whole object.watch thing and its just frustrating me cause I don’t see how it works! :frowning: I’m still reading the jQuery.data you posted, but I have trouble changing it from their examples to work with my scripts…

After this code, you will have a variable called block.


if (y > 1) {
    block = (y * 200) - 200;
    block = block + x;
} else {
    block = x;
}

Which could be simplified as follows:


block = x;
if (y > 1) {
    block += (y * 200) - 200;
}

Regardless of that though, it is after that code is where you would store the value of block. Not immediately after, but somewhere after there.

Here is the order of the steps that you want the code to perform:

[list=1][]calculate a value for block
[
]compare the calculated value with a previously stored value
[]if they’re different, perform the ajax code
[
]finally, store the calculated block value for next time[/list]

Steps 2 and 3 are where you wrap the code that performs the ajax call, with the following condition:


if ($('#gdimage').data('block') === block) {
    // do ajax stuff here
}

After that if statement is where you perform step 4, to store the block value as data, so that you can retrieve it next time around.


$('#gdimage').data('block', block);

And I just realised that y is always going to be 1 or greater, so the following code:

block = x;
if (y > 1) {
    block += (y * 200) - 200;
}

could be simplified even further to just:


block = x + (y * 200) - 200;

But this is what I don’t understand… this is how I’m seeing it:

The block value is created by the equation from the x/y co-ords, right? Which are constantly changing through every mouse movement over the image, but they are rounded to a sequence of 1, 6, 11, 16, 21 etc since my blocks are 5*5.

So I’m hovering over, lets say block 5 (x:21, y 1). If I store that number, one I’m not sure where I actually store it too (again, sorry if this is obvious - I’d normally store data on a server/cookie/session etc but for this it’s seems unnecessary).

Say if I did know how to store, it’s then stored - then I check that block value with the old block one (and I take it I make it so if an old value doesn’t exist, then to still execute the AJAX).

But when the AJAX is called and the block number is stored again, the block number still hasn’t actually changed, so both values of the block will forever be the same. Since the mouse hasn’t moved yet and they are taken from the same x/y co-ords?

And if I do move the mouse and the original block value changes, so will the new one, once again, making them both them same surely!?

So both block value and stored block value will constantly be updating as the mouse moves around, completely making the loop pointless?

I’m not trying to be awkward, and trust me, I am trying so hard to understand this but nothing is clicking :confused:

EDIT: Thank you for simplifying the block equation too :slight_smile:

In this case, we are associating the block value with the #gdimage element.

The data documentation page says:

If nothing was set on that element, null is returned.

This is why it’s useful to have that set of steps, so that we can use them to walk through different scenarios to determine just what should happen.

[list=1][]calculate a value for block
[
]compare the calculated value with a previously stored value
[]if they’re different, perform the ajax code
[
]finally, store the calculated block value for next time[/list]

So, step 1, the block value is calculated to be 5.
With step 2, 5 is compared to the stored data, which is null (as no stored value exists)
That allows step 3 to occur, the ajax call
With step 4, the value of 5 is stored as data

The next time around, the calculated 5 will be compared with the stored 5, and no ajax task is performed.

Here’s that list again.

[list=1][]calculate a value for block
[
]compare the calculated value with a previously stored value
[]if they’re different, perform the ajax code
[
]finally, store the calculated block value for next time[/list]

Step one calculates the block value to be 4, instead of 5 from last time
Step two compares the calculated 4 with the previously stored 5
Step three performs the ajax update
Step four stores the value 4 as data, to be used for next time

The next time around, 4 will be retrieved from the data store

Does that help in some way to understand what is happening?

It helped in the understanding a lot!! Here’s what I’ve got now, with an alert just to test it out too.


if (block != $('#gdimage').data('storedBlock')) {
				
	$.ajax({
		type: "GET",
		url: "fetch.php",
		data: "x=" + x + "&y=" + y + "",
		dataType: "json",
		async: false,
		success: function(data) {
			$("#user_name_area").html(data.username);
		}
	});
					
	alert('ajax called');
					
}
				
$('#gdimage').data('storedBlock', block);

I think what was confusing me was I didn’t understand where it was being stored, in my head the only placed I could see it being stored was within the mousemove function. I didn’t realise it was stored in the #gdimage.

I really, REALLY appreciate your help with that. You don’t know how many things I’ve tried and people I’ve asked and still couldn’t get it working!

EDIT: Does it make much of a difference with the way I called my if statement to yours using === ?

You’re welcome.

As you said before, the key is in understanding when the value is stored.

Here’s how you can get to that technique again, without having to think too hard about things.

There are two main sections involved in the code. The calculating of the new variable, and where that new variable is compared. That leaves three different places for the storing to occur.

[indent]- Store here?

  1. Calculate variable
  • Store here?
  1. Compare with stored variable
  • Store here?[/indent]

Storing the calculated variable cannot occur before it has been calculated.

[indent]- Store here? No. Nothing yet to store

  1. Calculate variable
  • Store here?
  1. Compare with stored variable
  • Store here?[/indent]

And if you store it before the comparison, you’re clobbering the previously stored one.

[indent]- Store here? No. Nothing yet to store

  1. Calculate variable
  • Store here? No. Clobbering old variable, so comparison will always be the same
  1. Compare with stored variable
  • Store here?[/indent]

Having ruled out those two possible locations, that only leaves the place after the comparison as the only viable place for the storing to occur.

[indent]- Store here? No. Nothing yet to store

  1. Calculate variable
  • Store here? No. Clobbering old variable, so comparison will always be the same
  1. Compare with stored variable
  • Store here? Yes. The stored variable is then used the next time through[/indent]

It does make a lot of sense, yes!

And I wasn’t even aware of the data function of storing to an ID, that’s all new to me! As I said Javascript/jQuery is all still pretty limited for me. All I’ve ever really used it for is client side form validation, and the jQuery side of things for tabs, modal boxes, moving tool tips, show/hide text etc.

Thank you for the thorough explanation and your time! I can’t explain how appreciated it is!! :slight_smile: