Archive for the ‘JavaScript’ Category

Note to jQuery developer team: Please use curly brackets!

Posted on July 3rd, 2008 in JavaScript, jQuery | No Comments »

If you haven’t gathered so far, I think the jQuery JavaScript library is the dog’s bollocks. Its small, efficient, and has improved my life as a developer almost as much as Firebug. jQuery gets flack occasionally for containing complex or cryptic code full of ternary operators and multiple variable declarations in a single statement (eg. a=b=1), which I mostly see as concise and efficient coding however, there’s one thing about the jQuery library that I can’t stand. It’s something every developer should do and if you’re not doing it then you’re a jerk and that, ladies and gentlemen, is omitting your curly brackets.

Look at this code snippet from the jQuery library to see what I mean:

for ( ; i < length; i++ )
	// Only deal with non-null/undefined values
	if ( (options = arguments[ i ]) != null )
		// Extend the base object
		for ( var name in options ) {
			var src = target[ name ], copy = options[ name ];
 
			// Prevent never-ending loop
			if ( target === copy )
				continue;
 
			// Recurse if we're merging object values
			if ( deep && copy && typeof copy == "object" && !copy.nodeType )
				target[ name ] = jQuery.extend( deep,
					// Never move original objects, clone them
					src || ( copy.length != null ? [ ] : { } )
				, copy );
 
			// Don't bring in undefined values
			else if ( copy !== undefined )
				target[ name ] = copy;
 
		}
 
// Return the modified object
return target;

Coding in this way leads is extremely error-prone especially for open-souce projects where many others are modifying your code. Please stop it.

Love,

A dedicated user

Creating a usable JavaScript Library

Posted on July 2nd, 2008 in JavaScript, Usability | No Comments »

I’m working on small JavaScript library for cross-(sub)domain communication through iframes for users of our platform and my target audience will have little to no JavaScript experience. While I’m going to have extensive documentation, my goal really is to make this library like HTML - easy to understand and pickup, without necessary having to consult a reference. Generally, I want one site creator (we call them affiliates) to look at another person’s site, say “How did he do that?”, view the source code, copy it, and implement it on her own site by altering the code.

My initial setup code (to configure/initialize) the library looked like this:

document.domain='mydomain.com';
Library.init('sub.domain.com',5166);

After looking back at it I thought about converting it to this:

document.domain='mydomain.com';
Library.setCommunity('sub.domain.com');
Library.setAffiliateSiteId(5166);
Library.init();

This is really clean and easy to understand but a little much if I need to add a ton more settings in the future.
My latest iteration looks like this:

document.domain='mydomain.com';
Library.configure({community:'sub.domain.com', affiliateSiteId: 5166, showErrors: true});

Although passing (JSON) objects around isn’t the most easy to understand for people with little or no JavaScript knowledge, it isn’t that unreadable and I really feel the pros outweighed the cons. In some of my methods there will be so many arguments that passing an object would be necessary and the user implementing the library is going to have to learn the syntax regardless. Plus passing data in a regular argument (x,y,z) format isn’t really good for optional parameters of which they’ll be a ton of in this library.
I’ve also decided to remove the initialize method and just auto-initialize once you’ve configured your settings. The more I can take away from the process the better.

Lastly, I added an optional error mode that will trigger an alert if you’re doing something wrong. The idea would be to disable it (remove or set  it to false) when you’re ready for production. This may add substantial bloat to the codebase so it may not stay in - or I could keep this feature in the dev version of the code and recommend affiliates use the production version after the initial creation process.

Note: The library isn’t actually called “Library”. I’m hiding it’s name until it’s ready. ;)

Mozilla’s “home” JavaScript function

Posted on June 30th, 2008 in JavaScript | 4 Comments »

I came across an interesting bug in someone’s code today. They had an iframe that was dynamically created and it’s url was different depending on whether the variable home was true or not. They had declared home a few lines earlier but the condition was always returning true no matter what. Turns out, there is already a variable of the same name in Mozilla-based browsers. It’s a function that when called, takes you to your home page set in your browser preferences.

I don’t have time to hack around with it at the moment, but I’d imagine that this is a slight security risk. Similar to Jeremiah Grossman’s CSS History Hack that can potentially tell all the sites you’ve visited recently, this one would tell what user’s home pages were set to. Initial thoughts are that this would be hard to do since the only way to call this function without leaving the page is to call it in an iframe (tried it and it works) but iframe sandboxing restrictions prevent code from the parent frame from seeing or accessing the contents of this iframe (or it’s window.location object) since it’s from a different domain. A quick check shows that this function doesn’t exist in Safari or Internet Explorer.

Dynamically creating an iframe in Internet Explorer for remote form submissions

Posted on May 13th, 2008 in General Web Dev, Internet Explorer, JavaScript | 3 Comments »

I’ve been doing a lot of remote iframe work as of late and while creating some functionality that submits a form to a dynamically generated iframe I quickly found that in IE6/7 you cannot target an iframe created with document.createElement('iframe');. You must instead use innerHTML to write out the iframe inside another element.

Oh IE, we will never understand you!

Update: Max commented that you can indeed use document.createEelement and still target iframes in IE, you just need to create them in this way document.createElement('<iframe name="iframeName">');. Still über quirky but slightly better than the innerHTML approach. Kudos Max!

Issue with Omniture’s Site Catalyst Form Analysis Plug-in

Posted on March 11th, 2008 in JavaScript, Omniture | No Comments »

Update: To further illustrate my discussion below I have created an example page with nothing but a basic form and Omniture code with the Form Analysis plugin. Clicking the submit button with Omniture enabled should alert the Form Object but notice in Firefox, Safari, and Opera the Window Object is instead alerted. Internet Explorer alerts the Form Object in both cases as it should.
How to fix the issue: Omniture has to fix this issue. Somewhere in their code they need to change a direct function call to use that function’s apply method instead so that they can keep the this reference targeting the same object.

I wanted to write about an issue I’ve been debugging with a particular sport’s team site and the issue ended up stemming from a conflict in Omniture’s Site Catalyst Form Analysis Plug-in with existing form validation code on the site. The form in question had a hard-coded event listener that (simplified) looks like this:

<form id="addForm" onsubmit="return validateForm(this)" method="post">
     // form contents here
 
</form>

The function validateForm is being passed one argument, this, which is a reference to the form it’s attached to. This function validates the form and returns true or false (with false halting form submission.) When the Omniture code runs, it removes any listeners on the form and ques them up to run after Omniture’s listener. Since the Omniture code is running in the global namespace (window object) the this keyword of our form validation function is now referencing the global window object instead of the form it was originally attached to. Unfortunately, because of it’s obscured nature - I couldn’t find the specific mechanism directly causing the issue in their code during my Firebug debug session. I have tracked it down to the Form Analysis 2.0 plugin, which tracks form success/abandonment rates. I can see that when the Omniture code is in the page all references to this change to the window object, which is pretty horrific since this is the basis of writing object-oriented code.

Since I can’t see Omniture’s code to fix it, the only end solutions are:

  • Removing all references to the this keyword in the site-specific code
  • Remove the Omniture plugin.

I’m pushing for the latter as developers shouldn’t have to code around an analytics tool, and the Omniture guys really need to fix this. I’ve looked around and found a related Omiture conflict with this in the jQuery JavaScript framework:

“Conflict with Omniture javascript”
http://dev.jquery.com/ticket/1295

As well as Dean Edward’s addEvent2 script:

“Anyone know why this code would conflict with Omniture’s SiteCatalyst javascript files?”
http://dean.edwards.name/weblog/2005/10/add-event2/#comment196705

For the above two scenarios, you may be able to move the omniture include above the other js includes so that it loads first, in my situation, I don’t have access to certain parts of the site so my options are limited. Hopefully this page will serve as a resource to others though, who also run across it.