IEs understanding 'this'
In this code, Firefox sees 'this' as the element that was clicked and passes the href attribute in the correct way.
IE seems to think of 'this' as [object window]. How can I get this to work the same in both browsers?
Note: jQuery will be fine, but not an option for this project
var printElem = getElementsByClassName('print', 'a');
for(i in printElem){
ObserveEvent(printElem[i], 'click', function(e){
window.open(this.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
cancelEvent(e);
});
}
I am adding my two cents here as I think you can use it.
4 years ago was to find out who can write the best implementation addEvent
. One of the main problems he was trying to solve was persistence this
inside an event handler.
Here is one contest entry written by the creator of jQuery:
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
(And of course be symmetrical):
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}
Rename it to "ObserveEvent" if you like.
There you have it, an 8-line implementation that you can throw into your codebase - no libraries, no frameworks. And your link this
inside your handler works just fine.
You can use event target like:
ObserveEvent(printElem[i], 'click', function(e){
var target = e.target || e.srcElement;
window.open(target.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
cancelEvent(e);
});
The problem is almost certainly with a function ObserveEvent
using IE's method attachEvent
, which (unlike addEventListener
in other browsers) does not set the this
object observable in the event handler.
Another option is to create an element scope closure for the handler for each element:
var printElem = getElementsByClassName('print', 'a');
for(var i in printElem){
(function(elem) { // elem === printElem[i] at time of execution later
ObserveEvent(elem, 'click', function(e){
window.open(elem.href, '', 'location=0,menubar=1,resizable=1,scrollbars=1,width='+810+',height='+700);
cancelEvent(e);
});
})(printElem[i]); // immediately call the temp function with our element
}