[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now


Object losing data when onmouseup is defined in code?

Posted on 2009-04-21
Medium Priority
Last Modified: 2013-11-19
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

Question by:nameinuse
  • 2

Expert Comment

ID: 24212063
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


Accepted Solution

GregTSmith earned 1500 total points
ID: 24212068
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:
function example1() {
	this.id = 'function example1 ...';
	document.body.onclick = function () {
function example2() {
	var me = this;
	me.id = 'function example2 ...';
	document.body.onclick = function () {
<body id="theBody">
<button onclick="example1()">Example 1</button><br />
<button onclick="example2()">Example 2</button><br />

Open in new window


Author Comment

ID: 24221565
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.


Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question