Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Wednesday, June 09, 2010

viewport resize event in IE

There is no viewport resize event in internet explorer, there is a window resize event, but its not the same. A window resize can mean that the size of the document within the view port has changed, for example 10 pages were added to the document.

I needed to know when the actual window was resized, so i wrote this hack to make that easy:

Saturday, April 24, 2010

Migrating to syntaxhighlighter 2.1.x

Problem:
I recently decided to upgrade to syntaxhighlighter 2.1 from 2.0 on my blogger blog. I thought it was going to be as easy as dropping in a new version. I was wrong, the TEXTAREA in which i was putting my code is no longer supported. instead SCRIPT tags are used to enclose the code! AHHH! I have about 40 code snippets on my blog and conversion seems very not-fun.

Solution:
I started to hand convert some of the entries, to find that the new blogger post editor was also losing all of my tabs! This was going to be painful to do by hand..
Alas, i decided to try to do it with javascript, and it worked!

I pulled in the latest jquery into my template to ease the pain. Instead of the regular synataxhighlighter init i now have this:



Now, i dont need to hand convert all of my textareas to the new format, and the tabs are saved. Good deal!

Wednesday, April 21, 2010

jQuery plugins: default options

jQuery plugins should expose their default options as a global hash. This is useful if you want to always override the defaults in the exact same way across your entire site.

Most good plugins already do this, for example jQueryUI plugins do this. Here is the plugin code that will let you expose your defaults as a global variable:

Tuesday, March 16, 2010

jQuery: Detect Windows XP Theme


I started building a jquery dropdown widget, and i ran into a problem where i was not styling the dropdown arrow correctly because i developed the widget in the classic theme, but the xp theme styled widgets differently.

Clearly i needed to be able to assign different classes to my widget depending on the user's theme if i wanted the widget to look natural to that user.

The problem is that the user's theme setting is not something available through a javascript api call, nor is it in the user agent string. I used a javascript technique called feature detection to get this information. Here is how it works:

We create a button element and assign it background color called 'ButtonFace'. This is a special system color that is different depending on what theme you use. Next we need to get the computed color of the button element, and remove the element from the DOM. The idea is that a user in XP theme will have a slightly different colored button than a user in the classic theme.

I used some jQuery to make my life easier, but it would be easy to port this code to any other framework, or do it in plain javascript.


The code above plugin will create a new jquery.support object $.support.windowsTheme which contains a name member that will be set to 'xp' if user is using the XP windows theme, 'classic' if they are using the classic theme, and undefined if they are using a custom theme, or another operating system.

To see this code in action look at this demo page

For further updates to this code please visit the jquery plugin page

Caveats:
  • This code does not check if the user is actually using windows, you would need to add that check yourself.
  • I have tested this code in firefox 3.6 and IE6,7 on windows XP. This code should really be also tested on Vista and Windows 7.
See also:
It has come to my attention that someone has already done this before

Tuesday, February 17, 2009

Building fast jQuery plugins

There are 3 million articles out there about making jQuery plugins, but most of them seem to focus on the basics. That is all well and good, but none of those articles will help you if you want to write a fast, responsive plugin that wont peg the CPU.

I will outline some techniques that have worked for me in building good jQuery plugins.

  • Cache your selectors. Not caching can be a real performance killer, once you select an element, cache it, if you plan to use it again. Even ID selectors should be cached. it will always be faster to reuse a cached selector than to ask the DOM for it. When it comes to plugins, you can hide the cached selectors in the main closure, and reuse them in the methods of the plugin.
  • Cache your state. It will always be faster to check if a boolean is true, than to check if a DOM element is visible. Forget about the DOM. Cache everything you will need access to, cache your modifications. DOM access is slow. I will exchange a few bytes of memory for a few ms of execution any day.
  • Use closures. If you dont know how to use closures, you must learn now. You wont be able to write a good plugin if you dont know when and how to use these. You should use the closure to hide all your config data, your cached selectors etc.
  • Dont use $.fn. if it doesnt make sense. Sometimes it makes sense to return something other then the jQuery object from your plugin. You can always pass in the 'this' the old school way as an argument. Sometimes it may be better to return an object that makes some methods from the closure 'public' and exposes some members. This kind of an object can be useful when writing unit tests, or if you want to provide a rich API without bastardizing $.fn.
  • Use functional inheritance. Use this and you will be get private/public members. This is important if you would like to have a clean API. I am talking about the functional inheritance from 'javascript: the good parts' book. See example of what i mean here.
  • Break things up into responsibilties. Let each method inside your plugin handle one thing. Do we need to recalucate something on window resize? Do we need to reload some event handlers after AJAX calls? Dont make one giant 'reload' method when you can have more specific methods that will save time.
  • Time and profile. I wish i had started doing this earlier. Use firebug's timing and profiling to see which portions of your code are slow, and optimize them.
  • Unit test. QUnit is jQuery's testrunner. Use it.
  • Test on a Pentium 3, in IE 6. This is my golden standard. If its fast here, you have nothing to worry about.

Sunday, February 08, 2009

Using jQuery with NYT JSON API

New York Times recently made public a great API that lets you search all of their articles from 1981 to present, and get the data back in JSON format.
I decided to use this API to add some relevant news stories to a site i have been working on. I was going to use jQuery to pull the data using $.getJSON() and shove it into some divs on my site.

Problem:
I quickly ran into a problem. NYT is retuning plain JSON, not JSONP. JSONP is needed to do cross-domain JSON calls. jQuery will make a jsonp call if you add the following to the request url:
jsoncallback=?
In the background, what happens is that jQuery replaces the ? with a function is creates, for example jsonp1229009. jQuery is expecting a response of:

but new york times is returning:

When jQuery pulls that response into a script tag, and executes in, i get the following error in firefox: "Invalid Label".

Solution:
What i needed was a JSONP wrapper. Luckly, i have a friend who knows perl =) I asked him to write a service that will take 2 params: url and callback. Where URL is an encoded URL i am requesting, and callback is the param to wrap the response in. It worked out nicely, i can now use ANY JSON API and get JSONP back. This is the perl source:



Here is my crude and incomplete jQuery plugin that gets me a couple of articles with predefined fields and displays them on my site:



i call it like this:

Wednesday, December 17, 2008

jQuery: responsiveness plugin for fast UI

for demo go here

Problem:
I was working on a dropdown widget where the user could scroll down using the arrow keys, and while he was scrolling, two things needed to happen:
  1. UI need to be updated, showing his new selection, and removing his old selection.
  2. Some costly DOM operations had to happen in the background to set the selected item in the widget.
I noticed that the scrolling was slow in IE6 on a P3-1000. Mind you, scrolling 1 item was fast, but holding down the arrow key and scrolling 50 items was painfully slow, because the DOM operations had to happen for every item scrolled.
I also knew that i only really needed to do the DOM operations for the last item selected, that is the one the user really wanted.


Solution:
Javascript is single threaded, but there is a timer function that makes faking multi-threaded execution possible.
What i needed to do was to split up the scroll function into two components, first call the UI update every time the arrow was pressed, and second, queue up the expensive DOM operations to happen in the future, but dont execute them until no new DOM operations have been queued for some interval of time. This would give the user the visual feedback of "something is happening" while not executing the costly operation that would make everything feel slow and unresponsive.

The plugin i came up with lets you specify the interval that you will wait for further requests until you execute the last request, and the number of times you will wait that interval.


One thing to be aware of is that this plugin does not implement any queing internally, so if you should only use one instance of it per function. make a new instance if you want to improve the performance of a different function.

For more info such as:
  • A simple typing demo
  • A crappy implementation of hoverIntent plugin
  • API
go here

Friday, December 12, 2008

jQuery: Conflict free events

Problem:
I had to validate an input, both onBlur and when the user pressed enter. If there was an error, in both cases, an alert would pop up. The problem was that when the user clicked 'ok' on the alert, the field would lose focus and cause the blur event to fire, and thus cause another alert to pop up. I only wanted one alert per error, so i made this little plugin to solve this problem.

Solution:
To use this plugin, you can pass in a hash with 2 keys: {blur: function(){}, enter: function(){}}, or a single function that you want run both onBlur and onEnter.



Example usage:

Wednesday, October 01, 2008

jQuery: constrain input chars plugin

Problem:
you need to only allow the user to input certain characters into the input box, and you want a jquery plugin to do it!

Solution:




the following lets you specify which chars (regexes or'ed together) are allowed in the input.

i added a small demo for the plugin, check it out here

get the plugin here