Object losing data when onmouseup is defined in code?

Bit of a weird error, and I'm pulling my hair out on it because I don't think it should be happenening.

I have an object with functions inside it.   I have another object with other functions on it.     I have code where I can move a window(div) around.    

If I define the onmouseup without the () at the end, it keeps the object data.  But, then it registers the onmouseup immediately, ends the movement and nothing happens.   It just sticks in the same place.

If I however do not put the () at the end, then I can move the object around, but then when it tries to call a stop, it says the object is null.

As it's moving a window, I of course have to track the mousemovements and such "onmousemove".     So there are 2 objects going back and forth.

 The 2 objects we will call "form" and "desktop".

desktop contains the "mouse_track(event)" function.   It also contains a variable called "being_dragged" which lets it know to move the window on the mouse movement.   The actual movement code itself is defined in the "form" object.    There is only 1 desktop object, and there can be multiple form objects.

Also, a reference to the desktop object is kept in the form object.   So when I call the other object, I use the reference, this.desktop.blah

So the flow goes as such.

Call to form.object -> start moving.    
start moving sets "being_dragged" to true, and sets the onmouseup.
desktop.mouse_track(event) registers the "being_dragged" = true and starts moving the window around.
Then on mouseup, it's supposed to call the function, and the function then sets being_dragged back to false, and thus the movement stops.

This code worked before without the () no problem, but I wasn't keeping the object reference inside the other object.   The object reference is valid and works, I've used it for other code. In order to start the tracking at the start it has to use the object reference to set the value to true.

I realize I can just define a global and that will likely fix it, but I'm trying to get the global variables down to basically 0.  And if all else fails, I can probably just define the onmouseup in the actual div, but I'd really like to figure out what is going on with the current code.


//relevant code
 
function form (id, desktop) {
	this.id = id;
	this.desktop = desktop;
	this.move_window = function() {
		if (this.state == "normal") {
			this.desktop.element = this.new_win;
			var y_current = document.getElementById(this.new_win).offsetTop;
			var x_current = document.getElementById(this.new_win).offsetLeft;
			this.desktop.x_loc_off = this.desktop.x_loc - x_current;
			this.desktop.y_loc_off = this.desktop.y_loc - y_current;
			this.desktop.being_dragged = true; 
			document.onmouseup = this.move_window_stop;
//alternative     document.onmouseup = this.move_window_stop();
			document.getElementById(this.new_win).style.opacity = .7;
		}
	}
	this.move_window_stop = function() {
		this.desktop.being_dragged = false;
		document.getElementById(this.new_win).style.opacity = 1;
		document.getElementById(this.new_win).style.cursor = 'auto';
	} 
}
 
function desktop() {
	this.being_dragged = false;
	this.mouse_track = function(event) {
		//code that defines x_loc and y_loc by browser;
		if(this.being_dragged == true) {
			var x_now = this.x_loc - this.x_loc_off;
			var y_now = this.y_loc - this.y_loc_off;
			document.getElementById(this.element).style.top = y_now +'px'; //
			document.getElementById(this.element).style.left = x_now +'px'; //
		}
}

Open in new window

nameinuseAsked:
Who is Participating?
 
GregTSmithCommented:
I get the sense that the problem lies with scope.  JavaScript has functional scope, but for anonymous (lambda) functions they can still have access to objects available in their parent object/function.  The keyword "this" doesn't follow that rule the way you'd expect.  It refers to the calling object not where the code is written per se.

Working Example:
<html>
<head>
<script>
function example1() {
	this.id = 'function example1 ...';
	alert(this.id);
	document.body.onclick = function () {
		alert(this.id);
	};
}
function example2() {
	var me = this;
	me.id = 'function example2 ...';
	alert(me.id);
	document.body.onclick = function () {
		alert(me.id);
	};
}
</script>
</head>
<body id="theBody">
<button onclick="example1()">Example 1</button><br />
<button onclick="example2()">Example 2</button><br />
</body>
</html>

Open in new window

0
 
GregTSmithCommented:
I've made couple modifications, but without a full sample of the code it's difficult to tell whether this change is correct.  :(

I'll post a follow-up to describe my impression of the problem.
function form(id, desktop) {
  var me = this;
  me.id = id;
  me.desktop = desktop;
  me.move_window = function () {
    if (this.state == "normal") {
      me.desktop.element = me.new_win;
      var nw = document.getElementById(me.new_win),
        y_current = nw.offsetTop,
        x_current = nw.offsetLeft;
      me.desktop.x_loc_off = me.desktop.x_loc - x_current;
      me.desktop.y_loc_off = me.desktop.y_loc - y_current;
      me.desktop.being_dragged = true; 
      document.onmouseup = function () {
        me.desktop.being_dragged = false;
        nw.style.opacity = 1;
        nw.style.cursor = 'auto';
      };
      nw.style.opacity = 0.7;
    }
  };
}
function desktop() {
  var me = this;
  me.being_dragged = false;
  me.mouse_track = function (event) { //code that defines x_loc and y_loc by browser;
    if (me.being_dragged) {
      var e = document.getElementById(me.element),
        x_now = me.x_loc - me.x_loc_off,
        y_now = me.y_loc - me.y_loc_off;
      e.style.top = y_now + 'px';
      e.style.left = x_now + 'px';
    }
  };
}

Open in new window

0
 
nameinuseAuthor Commented:
Thanks, full code is much too big.   I'm writing a window manager of sorts for allowing the user to customize things a bit, so there is alot of code for all the functions.

I went ahead and put the mouse out on the form itself and got it to work, but I am having another issue with trying to remove the objects from the window list and I think what you mention could solve that issue.  

If I understand correctly, If I have function 1 call function 2, then "this." will be referring to function 1 rather than function 2.    So if I have a "this.id" in each of them, and call "this.id" I will get function1.id, rather than function2.id.   Makes sense, and I'm sure will fix some oddities that have been giving me trouble.

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.