Properties

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Properties

Post by superdezign »

Let's say I'm making a slider, and I want it to be able to recognize whether or not the mouse is down, regardless off where the "mouseup" event occurs. Therefore, I'm using it's ownerDocument (or just "document" for browsers that don't support it) and giving it event listeners for both mousedown and mouseup events. I created a custom property with the ownerDocument so that it could be updated through mouse events on the ownerDocument, and accessed through a reference to my slider's ownerDocument.

It works beautifully in Firefox. Not so much In IE. I'm not blaming IE for anything, I'm just certain that I'm probably doing something that just shouldn't be done... maybe.

Code: Select all

function Slider()
{
	this.document = this.ownerDocument ? this.ownerDocument : document;
	this.document.__mousestate = 'up';
	
	AddEvent(this.document, 'mousedown', function(){this.__mousestate = 'down';}, true);
	AddEvent(this.document, 'mouseup', function(){this.__mousestate = 'up';}, true);
}

Slider.prototype.Slide = function()
{
	if(this.document.__mousestate == 'up')
		return;
	// Otherwise, slide the bar
}
AddEvent is a function I wrote for cross-browser compatibility. (addEventListener, attachEvent)

Is it not legal to create document.__mousestate?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I don't recall IE having ownerDocument.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Right. Which is why I use

Code: Select all

this.document = this.ownerDocument ? this.ownerDocument : document;
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Oops, missed that bit. ;)
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

when I create "flags" like that I usually attach it to window (window.__mousestate)

ppk's event compatibility tables would likely come in handy as well: http://www.quirksmode.org/js/events_compinfo.html#mouse
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Well, I've been playing around with it and Internet Explorer can, in fact, attach the flag to document. So, that portions is fine and has been fine the entire time. JS should be easier to debug. Anyway, the problem now lies deeper than that.

Code: Select all

function AddEvent(object, evt, func, capture)
{
	if(typeof func != 'function')
	{
		return false;
	}
	
	if(object.addEventListener)
	{
		object.addEventListener(evt, func, capture);
		return true;
	}
	else if(object.attachEvent)
	{
		object.attachEvent('on' + evt, func);
		return true;
	}
	
	return false;
}
The code looks to me like it should work fine, but somehow, it's not. In the event that I'm adding using this function, I've added an alert().

I run the script in Firefox and on the event, alert(this) gives me [object HTMLDivElement].
I do the same in Internet Explorer, and alert(this) gives me [object].

The problem is that, somehow, Internet Explorer is attaching the event to something other than object in AddEvent(). And, since I don't know what it is, I'm having hell trying to figure out what it is.


I hate saying this, but Microsoft needs to get with the standards rather than make up their own. Any idea why attachEvent isn't affecting the correct object? I've been debugging like mad, and still no luck.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Kieran Huggins wrote:when I create "flags" like that I usually attach it to window (window.__mousestate)

ppk's event compatibility tables would likely come in handy as well: http://www.quirksmode.org/js/events_compinfo.html#mouse
QuirksMode is the JS Bible. Of course I've read it all. :-p
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

have you seen the "dragable" and "slider" jQuery (interface) demos @ http://interface.eyecon.ro/demos
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Just for reference:

Code: Select all

this.document = this.ownerDocument ? this.ownerDocument : document; 
Can be written like this in JS (and only JS as far as I know):

Code: Select all

this.document = this.ownerDocument || document;
For null and undefined the expression just returns the value to the right of the || .
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

d11wtq wrote:Can be written like this in JS (and only JS as far as I know):
Looks like a good reason never to do it.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Kieran: No, I haven't. I've avoided jQuery. It makes too much sense. :-p

d11wtq: I'm aware, but if I were to attempt to access any of their properties in the statement, it'd throw errors. So, I avoid it altogether.
Example:

Code: Select all

// This would throw an error in FF since it has no srcElement
eventHandler(e){ var id = e.srcElement.id || e.target.id; }
I've been debugging like a madman and have finally pinpointed the problem. The problem is in Internet Explorer's attachEvent. Apparently, it doesn't work the same as addEventListener.

Take this test class that I wrote to find the problem:

Code: Select all

function Foo(id)
{
	this.__foo					= document.getElementById(id);
	this.__child				= document.createElement('div');
	this.__child.reference		= this;
	
	this.__child.style.width	= 
	this.__child.style.height	= '50%';
	this.__child.style.margin	= 'auto';
	this.__child.style.border	= '1px solid #000';
	
	this.__foo.appendChild(this.__child);
	
	if(!AddEvent(this.__child, 'click', this.Bar, true))
	{
		this.__child.onclick = this.Bar;
	}
}

Foo.prototype.Bar = function(e)
{
	if(!e)
	{
		e		= window.event;
	}
	
	alert('this.reference: ' + this.reference + '\ne.target.reference: ' + (e.srcElement ? e.srcElement.reference : e.target.reference));
}
Here is the AddEvent() function:

Code: Select all

function AddEvent(object, evt, func, capture)
{
	if(typeof func != 'function')
	{
		return false;
	}
	
	if(object.addEventListener)
	{
		object.addEventListener(evt, func, capture);
		return true;
	}
	else if(object.attachEvent)
	{
		object.attachEvent('on' + evt, func);
		return true;
	}
	
	return false;
}

So, when I create a "Foo" object, and click on the __child, here's what Bar alerts:
Firefox wrote:this.reference: [object Object]
e.target.reference: [object Object]
Internet Explorer wrote:this.reference: undefined
e.target.reference: [object Object]
So, when attachEvent occurs, the "this" keyword no longer refers to the element on which the event has occurred.

If I comment out the lines in AddEvent referring to attachEvent, thus making AddEvent return false in Internet Explorer, the event will be created use the age-old onmouseevent = doSomething.

Now, here's what Bar alerts:
Firefox wrote:this.reference: [object Object]
e.target.reference: [object Object]
Internet Explorer wrote:this.reference: [object Object]
e.target.reference: [object Object]
So, I've stopped using attachEvent, and now it works perfectly.


I don't like it though. I've been trying to play around with e.target and e.srcElement, and created a small GetEvent function that creates a pseudo srcElement in non-Microsoft browsers as e.target's value. I got that method to work up to an extent. Firstly, the sliders move much slower, and if I click on any of the elements inside of the slider (i.e., the bar div in the middle, the moving handle), it no longer responds as an action on the containing element, only the ACTUAL target/srcElement.

So, for now, IE will have to settle for me just.. not using attachEvent.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

@d11: that's why I love javascript - it's just so damned flexible!
Post Reply