www.webdeveloper.com
Results 1 to 4 of 4

Thread: 'this' seems to refer to last created object

  1. #1
    Join Date
    Mar 2010
    Posts
    5

    'this' seems to refer to last created object

    In the attached script (part of a framework), custom objects of type scratchBlock are created. They should have a function 'render' assigned, and they do. But aScratchBlock.render() always seems to trigger the render function on the last created object of type scratchBlock.

    Any ideas?

    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    
    <head>
    <title>WebScratch Sandbox</title>
    <link href="style.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="editor.js"></script>
    </head>
    
    <body onLoad="app_init()" onMouseMove="app_mouseMove(event)">
    
    <div id="scriptEditor">
    </div>
    
    </body>
    </html>
    Code:
    function app_init() {
    	scratchBlocks = new Array();
    	scratchBlockId = 0;
    	scratchBlocks[0] = new scratchBlock();
    	scratchBlocks[1] = new scratchBlock();
    	scratchBlocks[2] = new scratchBlock();
    	scratchBlock_dragging = -1;
    	testvar = 0
    }
    
    function app_mouseMove(event) {
    	mousex = event.clientX;
    	mousey = event.clientY;
    	
    	testvar ++;
    	window.status = typeof scratchBlock_dragging;
    	
    	if (scratchBlock_dragging != -1) {
    		/*xpos = scratchBlock_dragging.style.left;
    		xpos = xpos.substr(0, xpos.length-2);
    		ypos = scratchBlock_dragging.style.top;
    		ypos = ypos.substr(0, ypos.length-2);*/
    		xpos = scratchBlock_dragging.x
    		ypos = scratchBlock_dragging.y
    		
    		//alert(typeof scratchBlock_dragging + ' ' + xpos + ' ' + ypos);
    		
    		if (scratchBlock_dragStarted == false) {
    			//avoid drag on regular click or very slight mouse moves
    			scratchBlock_dragStarted = (Math.abs(xpos-xdiff-mousex)>2 || (Math.abs(ypos-ydiff-mousey)>2))
    		} else {
    			//document.getElementById(scratchBlock_dragging).style.top = (mousey + ydiff) + 'px';
    			//document.getElementById(scratchBlock_dragging).style.left = (mousex + xdiff) + 'px';
    			scratchBlock_dragging.x = mousex + xdiff;
    			scratchBlock_dragging.y = mousey + ydiff;
    			scratchBlock_dragging.render();
    		}
    	}
    }
    
    //scratchBlock Object Definition
    
    //actual object definition
    
    function scratchBlock() {
    	//Object Properties
    	this.bid = scratchBlockId;
    	this.x = 100
    	this.y = this.bid*50+50;
    	this.blockType = 'command';
    	this.color = 'blue';
    	this.label = 'go to x: [' + Math.round(Math.random()*100) + '] y: [' + Math.round(Math.random()*100) + ']';
    	
    	//Object Methods
    	//this.render = scratchBlock_render;
    	this.render = scratchBlock_render;
    	
    	this.render();
    	
    	scratchBlockId ++;
    }
    
    //methods
    function scratchBlock_render() {
    	oldHTML = this.HTML
    	
    	this.HTML = '<div class="block ' + this.color + '" id="b'+scratchBlockId+'">' + this.label + '</div>';
    	
    	if (this.DOMobj == undefined) {
    		document.getElementById('scriptEditor').innerHTML += this.HTML;
    		this.DOMobj = document.getElementById('b'+this.bid);
    		//event handling
    		this.DOMobj.setAttribute('onMouseDown','scratchBlock_initDrag('+this.bid+')');
    		this.DOMobj.setAttribute('onMouseUp','scratchBlock_dragging = -1 ');
    		this.DOMobj.setAttribute('onSelectStart','return false'); //avoid text selection on browser other then Mozilla
    	}
    	
    	if ((this.HTML != undefined)&&(this.HTML != oldHTML)) {
    		document.getElementById('scriptEditor').innerHTML.replace(oldHTML, this.HTML);
    	}
    		
    	this.DOMobj.style.top = this.y + 'px';
    	this.DOMobj.style.left = this.x + 'px';
    }
    
    
    function scratchBlock_initDrag(blockId) {
    	//scratchBlock_dragging contains object scratchBlock
    	scratchBlock_dragging = scratchBlocks[blockId];
    	//alert(blockId + ' ' + typeof scratchBlock_dragging)
    	scratchBlock_dragStarted = false;
    	
    	xdiff = scratchBlock_dragging.x - mousex;
    	ydiff = scratchBlock_dragging.y - mousey;
    }

  2. #2
    Join Date
    Aug 2007
    Posts
    3,767
    Code:
    this.render = scratchBlock_render;
    That doesn't work, because there only is one version of scratchBlock_render, while with the way you have it coded, you need a new one for each object. You are looking for prototype object.
    Great wit and madness are near allied, and fine a line their bounds divide.

  3. #3
    Join Date
    Mar 2010
    Posts
    5
    :/ This is the way it is done in every tutorial I found on the net, sorry for my noob-ish behavior.

    Code:
    this.render = scratchBlock_render;
    should assign the function scratchBlock_render as a method to the definition of the scratchBlock object.

    I edited the code, and completely removed the scratchBlock_render. This is the result:
    Code:
    function app_init() {
    	scratchBlocks = new Array();
    	scratchBlockId = 0;
    	scratchBlocks[0] = new scratchBlock();
    	scratchBlocks[1] = new scratchBlock();
    	scratchBlocks[2] = new scratchBlock();
    	scratchBlocks[3] = new scratchBlock();
    	scratchBlocks[4] = new scratchBlock();
    	scratchBlocks[5] = new scratchBlock();
    	scratchBlock_dragging = -1;
    	testvar = 0
    }
    
    function app_mouseMove(event) {
    	mousex = event.clientX;
    	mousey = event.clientY;
    	
    	if (scratchBlock_dragging != -1) {
    		xpos = scratchBlocks[scratchBlock_dragging].x
    		ypos = scratchBlocks[scratchBlock_dragging].y
    
    		//alert(typeof scratchBlock_dragging + ' ' + xpos + ' ' + ypos);
    		if (scratchBlock_dragStarted == false) {
    			//avoid drag on regular click or very slight mouse moves
    			scratchBlock_dragStarted = (Math.abs(xpos-xdiff-mousex)>2 || (Math.abs(ypos-ydiff-mousey)>2))
    		} else {
    			//document.getElementById(scratchBlock_dragging).style.top = (mousey + ydiff) + 'px';
    			//document.getElementById(scratchBlock_dragging).style.left = (mousex + xdiff) + 'px';
    			scratchBlocks[scratchBlock_dragging].x = mousex + xdiff;
    			scratchBlocks[scratchBlock_dragging].y = mousey + ydiff;
    			scratchBlocks[scratchBlock_dragging].render();
    		}
    	}
    }
    
    //scratchBlock Object Definition
    
    //actual object definition
    
    function scratchBlock() {
    	//Object Properties
    	this.bid = scratchBlockId;
    	this.x = 100
    	this.y = this.bid*50+50;
    	this.blockType = 'command';
    	this.color = 'blue';
    	this.label = 'go to x: [' + Math.round(Math.random()*100) + '] y: [' + Math.round(Math.random()*100) + ']';
    	
    	this.HTML = '<div class="block ' + this.color + '" id="b'+this.bid+'">' + this.label + '</div>';
    	
    	document.getElementById('scriptEditor').innerHTML += this.HTML;
    	this.DOMobj = document.getElementById('b'+this.bid);
    	
    	//event handling
    	this.DOMobj.setAttribute('onMouseDown','scratchBlock_initDrag('+this.bid+')');
    	this.DOMobj.setAttribute('onMouseUp','scratchBlock_dragging = -1 ');
    	this.DOMobj.setAttribute('onSelectStart','return false'); //avoid text selection on browser other then Mozilla
    	
    	//Object Methods
    	//this.render = scratchBlock_render;
    	this.render = scratchBlock_render;
    	
    	this.render();
    	
    	scratchBlockId ++;
    }
    
    //methods
    function scratchBlock_render() {	
    	this.DOMobj.style.top = this.y + 'px';
    	this.DOMobj.style.left = this.x + 'px';
    }
    
    
    function scratchBlock_initDrag(blockId) {
    	//scratchBlock_dragging contains object scratchBlock
    	//scratchBlock_dragging = scratchBlocks[blockId];
    	scratchBlock_dragging = blockId;
    	//alert(blockId + ' ' + typeof scratchBlock_dragging)
    	scratchBlock_dragStarted = false;
    	
    	//test
    	scratchBlocks[blockId].label = 'go to x: [' + Math.round(Math.random()*100) + '] y: [' + Math.round(Math.random()*100) + ']';
    	//</test> lol
    	
    	xdiff = scratchBlocks[blockId].x - mousex;
    	ydiff = scratchBlocks[blockId].y - mousey;
    }
    It does exactly the same.

    This makes me think there is a problem with the this.DOMobj = document.getElementById(...);

    Is it possible that outside of the scratchBlock() object definition, aScratchBlock.DOMobj is handled as a copy of the HTML DOM object instead of a reference to the actual element on the page?

    This is what it seems to be - all properties of each scratchBlock object seem to have the desired values when running the script - the positions on the screen are just not updating...
    Last edited by Declan1991; 03-29-2010 at 06:07 PM.

  4. #4
    Join Date
    Mar 2010
    Posts
    5
    It seems I am not allowed to edit my own post, so I have to post a new one It says 'you may edit your posts' at the bottom of the page though...
    The title is also not describing my problem anymore - this happens when you think you've found problem but you're proven wrong afterwards. I should have done more testing before posting, sorry. I also noticed my last post got edited?

    I accidently posted a slightly wrong version of my code above, this is the version in which the scratchBlock render method does not exist. (simply shrunk it down until there were only two lines of code remaining, then replaced the two references to aScratchObject.render() with the actual code.)

    I did not mention it yet, but I really appreciate your help. Hopefully I'll be able to help others on this forum too, on surfaces I am slightly better at I know JavaScript just enough for creating dynamic forms and pages, but once it comes to this...

    And I see I did not describe my script too well, here it goes:
    When a new scratchBlock object is created, a piece of HTML is added to the div element scriptEditor.
    This new div should be draggable, but it's important to store the css properties as properties of the object for further reference in my project.
    aScratchBlock.DOMobj should contain a reference to document.getElementById('theScratchBlock'). To me it seems aScratchBlock.DOMobj does not contain a reference to the HTML element, but somehow a copy of it - I can edit it style properties, it stores them, the div's just don't move...
    The last created scratchBlock always works perfectly...
    Code:
    function app_init() {
    	scratchBlocks = new Array();
    	scratchBlockId = 0;
    	scratchBlocks[0] = new scratchBlock();
    	scratchBlocks[1] = new scratchBlock();
    	scratchBlocks[2] = new scratchBlock();
    	scratchBlocks[3] = new scratchBlock();
    	scratchBlocks[4] = new scratchBlock();
    	scratchBlocks[5] = new scratchBlock();
    	scratchBlock_dragging = -1;
    	testvar = 0
    }
    
    function app_mouseMove(event) {
    	mousex = event.clientX;
    	mousey = event.clientY;
    	
    	if (scratchBlock_dragging != -1) {
    		xpos = scratchBlocks[scratchBlock_dragging].x
    		ypos = scratchBlocks[scratchBlock_dragging].y
    
    		//alert(typeof scratchBlock_dragging + ' ' + xpos + ' ' + ypos);
    		if (scratchBlock_dragStarted == false) {
    			//avoid drag on regular click or very slight mouse moves
    			scratchBlock_dragStarted = (Math.abs(xpos-xdiff-mousex)>2 || (Math.abs(ypos-ydiff-mousey)>2))
    		} else {
    			//document.getElementById(scratchBlock_dragging).style.top = (mousey + ydiff) + 'px';
    			//document.getElementById(scratchBlock_dragging).style.left = (mousex + xdiff) + 'px';
    			scratchBlocks[scratchBlock_dragging].x = mousex + xdiff;
    			scratchBlocks[scratchBlock_dragging].y = mousey + ydiff;
    			scratchBlocks[scratchBlock_dragging].render();
    			scratchBlocks[scratchBlock_dragging].DOMobj.style.top = this.y + 'px';
    			scratchBlocks[scratchBlock_dragging].DOMobj.style.left = this.x + 'px';
    		}
    	}
    }
    
    //scratchBlock Object Definition
    
    //actual object definition
    
    function scratchBlock() {
    	//Object Properties
    	this.bid = scratchBlockId;
    	this.x = 100
    	this.y = this.bid*50+50;
    	this.blockType = 'command';
    	this.color = 'blue';
    	this.label = 'go to x: [' + Math.round(Math.random()*100) + '] y: [' + Math.round(Math.random()*100) + ']';
    	
    	this.HTML = '<div class="block ' + this.color + '" id="b'+this.bid+'">' + this.label + '</div>';
    	
    	document.getElementById('scriptEditor').innerHTML += this.HTML;
    	this.DOMobj = document.getElementById('b'+this.bid);
    	
    	//event handling
    	this.DOMobj.setAttribute('onMouseDown','scratchBlock_initDrag('+this.bid+')');
    	this.DOMobj.setAttribute('onMouseUp','scratchBlock_dragging = -1 ');
    	this.DOMobj.setAttribute('onSelectStart','return false'); //avoid text selection on browser other then Mozilla
    	
    	this.DOMobj.style.top = this.y + 'px';
    	this.DOMobj.style.left = this.x + 'px';
    	
    	scratchBlockId ++;
    }
    
    function scratchBlock_initDrag(blockId) {
    	//scratchBlock_dragging an id
    	scratchBlock_dragging = blockId;
    	scratchBlock_dragStarted = false;
    	
    	xdiff = scratchBlocks[blockId].x - mousex;
    	ydiff = scratchBlocks[blockId].y - mousey;
    }

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles