• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

Javascript Problem:: Event Handler and "this" Reference

deFektive

n00b
Joined
Jun 14, 2005
Messages
39
Short:
Problem: Using the reference "this" in FireFox will refer to the object that the event is captured on (eg - the anchor tag). Therefore, in FireFox, the function works as intended, acquiring the href and rel tags and manipulating them accordingly. However, in Internet Explorer, it appears that "this" is referencing the window instead, causing the function to break and instead loading the linked page instead of producing the AJAX call.

---------------------------------------------------------------------------------------------------------------------------------------------

I'm currently working on a script that is combining the mootools animation library (http://www.mootools.net) with some custom AJAX scripting. The exact application is irrelevant, but I'll do my best to explain the scenario.

First, I have a call to a function that attaches onClick events to links on the current page:
Code:
/**************************************
********* COMMON ** SCRIPTS ***********
**************************************/

function init(){
	ajaxLinks(); // Attatch Additional Functionality to Links
}

addEvent(window,'load',init);

/*********************************
**** AJAX :: REMOTE SCRIPTING ****
*********************************/

// Attatch Ajax Event to Links
function ajaxLinks(i) {
	if(!i){
		var links = document.getElementsByTagName('a');
	}else{
		var links = document.getElementById(i).getElementsByTagName('a');
	}
	for(var i = 0; i < links.length; i++){
		var a = links[i];
		
		if(a.getAttribute('href') && a.getAttribute('rel')) {
			var rel = a.getAttribute('rel');
			
			var key = rel.substr(0,4);
			
			
			// Check for rel="ajax..."
			if(key == 'ajax') {
				var x = rel.split('[');
				var start = x[0];
				var action = start.substr(5);
				
				/*** Determine Appropriate Function ***/
				
				//Append OnClick
				if(action == 'load') {
					addEvent(a,'click',getPage);
				}
				
				if(action == 'check') {
					addEvent(a,'click',checkRecord);
				}
				
				if(action == 'test') {
					addEvent(a,'click',test);
				}
				
			}
		}
	}
}

(For reference here are the addEvent and stopEvent functions):
Code:
function addEvent(obj,type,fn){if(obj.addEventListener){obj.addEventListener(type,fn,false);}else if(obj.attachEvent){obj.attachEvent('on'+type,fn);}else{obj['on'+type]=fn;}}

function stopEvent(e){if(e.stopPropagation){e.stopPropagation();e.preventDefault();}else{e.returnValue=false;e.cancelBubble=true;}}

In the first section of code above, you'll notice that any anchor tag containing both an href attribute and a rel attribute (the rel attribute containing "ajax_load[...]") will have the function getPage attached to it's onClick event. Attaching the event seems to work fine in all browsers, but when the function getPage is called, the results vary by browser.

Code:
function getPage(event){
	event = event || window.event;
	
	var href = this.getAttribute('href');
	var rel = this.getAttribute('rel');
	
	var x = rel.indexOf('[');
	var y = rel.indexOf(']');
	var opt = rel.substr(x+1,y-x-1);
	
	ajax_fadeOutIn(opt,href,'content');
	
	stopEvent(event);
}

(the line "ajax_fadeOutIn(opt,href,'content');" continues to produce the animation and load the new page through a remote call, but the problem I am running into appears before then)

Problem: Using the reference "this" in FireFox will refer to the object that the event is captured on (eg - the anchor tag). Therefore, in FireFox, the function works as intended, acquiring the href and rel tags and manipulating them accordingly. However, in Internet Explorer, it appears that "this" is referencing the window instead, causing the function to break and instead loading the linked page instead of producing the AJAX call.

Does anyone happen to know of a way that I might be able to rewrite this so that the function called onClick will reference the appropriate object?

Thanks,
Defektive
 
Instead of using 'this', use event.target.

generic, non-specific example:
Code:
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <script>
            window.onload = function() {
                document.getElementsByTagName("button")[0].onclick = function(e) {
                    if (!e) {
                        e = window.event;
                    }
                    if (e.target == null) {
                        e.target = e.srcElement;
                    }
                    alert(e.target.nodeName);
                    alert(e.target.innerHTML);
                    if (e.preventDefault) {
                        e.preventDefault();
                    }
                    return false;
                };
            };
        </script>
    </head>
    <body>
        <button>click me</button>
    </body>
</html>
 
Thanks Shadow2531, that did the trick. Do you happen to know a good resource on event handlers? It's still fairly new to me and I was completely unaware that an event contained attributes such as target. Thanks again.
 
Quirksmode has a fairly substantial section dedicated to Javascript and Event handling here: http://www.quirksmode.org/js/introevents.html which I like a lot.

I would recommend using some sort of Javascript framework to abstact out some of the more annoying browser quirks, for example the Yahoo User Interface toolkit, Dojo, or Google Web Toolkit depending on what you need to do. I believe each of these frameworks have some sort of automatic scope correction that will make sure "this" references what you are expecting.

I would still recommend reading up on Javascript and event handling before you dive in to any framework because it helps to know what is going on behind the scenes if you run into trouble.
 
Back
Top