erichynds

Hi, I'm Eric Hynds, a front-end website developer living outside of Boston, Massachusetts. I'm passionate about developing functional, standard-compliant, and user-friendly websites.

Archive for the ‘JavaScript’ Category

A Recursive setTimeout Pattern

Monday, October 18th, 2010

Colin Snover wrote a good article about why he thinks setInterval is considered harmful:

  1. setInternval ignores errors. If an error occurs in part of your code, it’ll be thrown over and over again.
  2. setInterval does not care about network latency. When continuously polling a remote server for new data, the response could take longer than the interval amount, resulting in a bunch of queued up AJAX calls and an out-of-order DOM.

The solution is to recursively call a named function within setTimeout, which guarantees that your logic has completed before attempting to call it again. At such, this also doesn’t guarantee that your logic will occur on a regular interval. If you want new data every 10 seconds and it takes 15 for your response to come back, you’re now behind by 5 seconds. Colin notes that you can adjust your delay if need be, but you shouldn’t really care as JavaScript timers are not accurate to begin with.

So how to do this? Consider an AJAX poller as this is a common use case:

// old and busted - don't do this
setInterval(function(){
   $.ajax({
       url: 'foo.htm',
       success: function( response ){
          // do something with the response
       }
   });
}, 5000);
 
 
// new hotness
(function loopsiloop(){
   setTimeout(function(){
       $.ajax({
           url: 'foo.htm',
           success: function( response ){
               // do something with the response
 
               loopsiloop(); // recurse
           },
           error: function(){
               // do some error handling.  you
               // should probably adjust the timeout
               // here.
 
               loopsiloop(); // recurse, if you'd like.
           }
       });
   }, 5000);
})();

I’m doing three things here:

(more…)

Working With XML, jQuery, and JavaScript

Sunday, August 29th, 2010

A recent requirement of mine was to convert large CSV files to XML, and then build an accompanying interface to update & manage the data.  jQuery was most useful for traversing & manipulating the large DOM’s, but I did run across a few gotcha’s worthy of discussion.  There doesn’t seem to be much info on the interwebs about XML and jQuery outside of an XHR request, so here’s what I picked up along the way.

You cannot pass an XML string to jQuery’s constructor

Well technically you can, but it’s not supported and jQuery will not treat the string as XML. You’ll still be working with an HTML document object. jQuery has no idea/doesn’t care that the elements are not valid HTML elements though, so this might be just fine as long as your XML remains detached from the DOM. To feed XML to jQuery correctly, you must pass a parsed XML string (a la XML object) to jQuery’s constructor.

A new feature ticket exists to add cross-browser XML compatibility to jQuery, whose summary yields another good nugget of info:

As documented, the $(“<html string>”) method only supports parsing HTML strings, but users often try to parse XML strings with it. This doesn’t work since jQuery uses the .innerHTML property for parsing and implicitly enforces HTML rules on the string. IE in particular will throw errors or misparse XML strings passed to $() in this way.

Furthermore, the second you try to pass any sizable XML or HTML string to jQuery’s constructor, Firefox 3 is going to fail with a “script stack space quota is exhausted” error (see the bug report filed with Mozilla).

script stack space quota is exhausted

As Dave Methuin (core team member) explains:

Firefox seems to be dying on the constructor check for HTML, which uses a RegExp?:

match = quickExpr.exec( selector );

The string you’re passing in is long and html-ish, and I suspect Firefox is backtracking heavily trying to match the huge string. We can either assume a long (>1K chars) string must be HTML or come up with a RegExp? that doesn’t need to backtrack so much.

So how do you convert a string to an XML object? It depends on your browser. (more…)

jQuery and Performance: What is ‘this’?

Monday, January 4th, 2010

In my opinion, one of the best jQuery performance tips is to minimize your use of jQuery. That is, find a balance between using jQuery and plain ol’ JavaScript, and a good place to start is with ‘this‘. Many developers use $(this) exclusively as their hammer inside callbacks and forget about this, but the difference is distinct:

When inside a jQuery method’s anonymous callback function, this is a reference to the current DOM element. $(this) turns this into a jQuery object and exposes jQuery’s methods. A jQuery object is nothing more than a beefed-up array of DOM elements.

Digging a little deeper

As you begin to nest functions the context of this changes:

<a href="#"><span>Hello World</span></a>
 
$("a").click(function(event){
	var self = this;
 
	$(this).find("span").each(function(){
		console.log(self, this);
	});
 
	event.preventDefault();
});

In this example I save this to the variable “self” so it can be referenced inside the each() loop. Otherwise it’s impossible to reference this as the anchor element inside the loop, because this is now the “span” DOM element.

Depending on what you’re doing, using this is sometimes easier and always faster than $(this). I’m not talking about scraping jQuery altogether, but rather recognizing that a lot of DOM interaction (especially the simple stuff) can just as easily be done in vanilla JS using this; you are not required to use the jQuery API. Example:

(more…)