Jump to content

help with the keyword this


skaterdav85

Recommended Posts

I was having some fun today and trying to create a small JS library like jQuery in the code below. I have a constructor function called dQuery and I pass in one argument. If the argument is a string, it assumes the argument is an ID of an element and sets a property 'this.el' to the element with that ID using getElementById(). If the argument is not a string, it assumes it is an element. What I am having trouble with, is that when you run the code within window.onload in IE and FF or Chrome, this is interpretted differently. In IE, this points to window, whereas in Chrome and FF, this points to the anchor element with an ID of prinkLink. Any idea why?HTML

<a href="#" id="printLink">Print</a>

JavaScript

var dQuery = function (obj) {	if (this === window) {		return new dQuery(obj);	}	if (typeof obj === "string") { //assume the supplied argument is an ID		this.el = document.getElementById(obj);	}	else if (typeof obj === "object") { //assume the supplied argument is an element		this.el = obj;	}	this.bind = (function () {		if (document.attachEvent) {			return function (evt, cb) {				(this.el).attachEvent('on' + evt, cb);			};		}		else if (document.addEventListener) {			return function (evt, cb) {				(this.el).addEventListener(evt, cb, false);			};		}	} ());};   //end of constructor function//example using the dQuery objectwindow.onload = function () {		dQuery('printLink').bind('click', function () {			if (this === window) {				alert('this points to window');			}			else if (this.tagName === 'A') {				alert('this points to anchor tag');			}		});};

Link to comment
Share on other sites

oh ok. I didn't know IE handled scope differently. Do you know of any references that explain this in detail?I modified my bind() method to the following, using call and caching this.el and it worked, but it'd be nice to know what the scoping differences are between IE and modern browsers.

this.bind = (function () {		if (document.attachEvent) {			return function (evt, cb) {				var el = this.el;				el.attachEvent('on' + evt, function () {					cb.call(el);				});			};		}		else if (document.addEventListener) {			return function (evt, cb) {				var el = this.el;				el.addEventListener(evt, function () {					cb.call(el);				}, false);			};		}} ());

Link to comment
Share on other sites

I have always assigned handlers using the dot notation style:elem.onclick = function() { .... }and I have never had any problems with scoping this. Which way is more correct? (Dot notation or addEventListener/attachEvent) It seems to me that the dot notation style is more reliable.

Link to comment
Share on other sites

the traditional event model (element.onclick, element.onmouseover, etc) is more consistent across browsers. However there are drawbacks to this approach because it only allows you to assign one function to each event type of an element. If you have a link and you want to fire 2 functions when it is clicked, you would have to refactor your code so that you only assign one function to that event type, and that function would fire the 2 functions. With addEventListener and attachEvent, you can specify more than 1 event handler to an element. Read these 2 posts. They explain it much better.http://www.quirksmode.org/js/introevents.htmlhttp://www.quirksmode.org/js/events_advanced.html

Link to comment
Share on other sites

I usually don't use "this" in event handling functions. If you want to access the element to which the event is binded you can use currentTarget of the event object. Internet Explorer doesn't support that so you have to use srcElement. The only problem is that srcElement doesn't always point to the element that the event is binded to, it points to the element that fired the event, which sometimes may be different.A fix (that might not always work) is to assign a unique property to the element while binding the event. When the event fires, keep checking parentNodes until you find the one that has the property you were looking for.

Link to comment
Share on other sites

I usually don't use "this" in event handling functions. If you want to access the element to which the event is binded you can use currentTarget of the event object. Internet Explorer doesn't support that so you have to use srcElement. The only problem is that srcElement doesn't always point to the element that the event is binded to, it points to the element that fired the event, which sometimes may be different.A fix (that might not always work) is to assign a unique property to the element while binding the event. When the event fires, keep checking parentNodes until you find the one that has the property you were looking for.
Seems much easier to just use this. :)
Link to comment
Share on other sites

interesting approach Inglome. I haven't really studied the differences of the event object for IE and modern browsers since I rarely use them. Using this does sound easier though once you normalize its scope through feature detection.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...