Showing posts with label insights. Show all posts

5 notes on JavaScript Arrays

In this post, we will go through some of the features of JavaScript's Arrays. I thought this would be a good place to come back time to time and refresh my memory about special cases and notes I've collected on Arrays in Javascript. Without futher ado, 5 notes on JavaScript Arrays.

1. Arrays are Objects in JavaScript

Arrays are Objects in JavaScript. Let me repeat it one more time: "Arrays are Objects". Understanding this helped me simplify my conceptual understanding of the language. Instead of rembembering different special cases and syntax for Arrays and Objects, now, we just need to remember rules to work with Objects alone.

Now, let me elaborate on it more. Array index keys are just property names of an object. Since, a property name can not start with a number, we have to use alternative [''] property access notation just like we would with any other object. So, there is nothing special about Array keys. They are just object property names that are integers.

var array = [1, 2, 'three', 4, 5]; // or 'new Array()' array.0 // SyntaxError: Unexpected number array[0] // 1 array[2] // 'three'

2. Arrays keys are String

Internaly javascript engine keeps array keys as String values, because naming rules do not allow properties starting with a numeral. When you access array values with an integer, javascript engine casts it into string. So this means that JavaScript Arrays are not breaking any of the naming rules defined by the language. Property names are not starting with an integer and they are stored as strings. Let's see some examples.

var array = [1, 2, 'three', 4, 5]; array[1] // 2 array['1'] // 2 - Accessing with a string works just fine array['3'] == array[3] // 'true' array['03'] == array[3] // 'false' - because array['03'] != array['3'] array['03'] == array[03] // 'false'

In the example above: array['03'] is not equal to array[03], because numerical value 03 furst turned into 3 and only then casted into string. So the end equation would become array['03'] == array[3] and that equals to false.

3. Arrays keys must be positive integers

Just like in any other programming language, JavaScript imposes a rule that array keys can only be positive integers. You can still treat them as if they were objects and set values to any keys. Javascript engine would simply ignore them.

var array = [1, 2, 'three', 4, 5]; array['06'] = 7; array['str'] = 'some value'; array.prop = 'another value'; console.log( array ); // [1, 2, 'three', 4, 5] array['6'] = 7; console.log( array ); // [1, 2, 'three', 4, 5, undefined, 7]

4. Use the literals notation [] instead of new Array()

The new Array() is ambiguous in how it deals with its parameters, so it is better to always use alternative [] notation to define arrays. The literals are more readable and shorter as well.

You can read more about this behaviour here.

// Prefered method var array = [1, 2, 'three', 4, 5]; // Not so prefered var array2 = new Array(5);

5. Loop through arrays with for() loop

As we said previously, arrays are objects. So you can loop through them using for in loop. But it is not recommended. Because, for in loops through all the properties that are in the prototype chain and you will have to use .hasOwnProperty() check. This means only 2 things:

  1. bloated and hard to read code;
  2. performance penalty.
var array = []; a[1000] = 'some value'; for (key in array) { if (a.hasOwnProperty(key)) { array[key]; // 'some value' } } // Recommended for(var index = 0, l = array.length; index < l; index++) { array[index]; // 'some value' } // OR if you have ECMAScript5 support array.forEach(function(value) { value; 'some value' });

6. Bonus notes

Since arrays are objects of an Array class. We can check if an object is an array.

function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is('Array', [1, 2, 3]); // true

If you have jQuery included on your page, use either $.type() or $.isArray().

var array = [1, 2, 3]; $.type(array); // 'array' - string $.isArray(array); // true - boolean

JavaScript: typeof & when should you use it?

In this post, we will talk about JavaScript’s typeof operator. We will start with its’ purpose. Then discuss its’ flaws and finally see when should you use it.

typeof's usage doesn’t happen to match its’ initial purpose.

What is typeof?

The typeof operator is used to identify the type of an object. It always returns a String value, so you should always compare return value to a string.

// Examples typeof 37; // "number"; typeof true; // "boolean" typeof undefined; // "undefined" typeof {}; // "object" // Call with parentheses typeof(37); // "number";

As you can see above, there are 2 ways to call the method. typeof is an operand and not a function, that is why, the second method is actually not a function call. Operation in parentheses are evaluated and then passed to typeof.

So far, so good, we know its’ purpose. Now let’s see its’ flaws.

Flaws and caveats

I’ll just say it: typeof is one of the biggest flaws in JavaScript. It had only one job, to return the type of an object. But let’s see the table below (source):

Value Class Type ------------------------------------- "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object (function in Nitro/V8) new RegExp("meow") RegExp object (function in Nitro/V8) {} Object object new Object() Object object alert Function function (object in IE 6, 7, 8) null null object (in future ECMAScript versions)

"Type" column lists the typeof‘s return values and "Class" column shows the actual class of the operand.

As you can see, in most of the case you end up with object string instead of the actual class name. A workaround for getting the class of an object is to use Object.prototype.toString method. Here is how:

Object.prototype.toString.call("foo") // [object string] Object.prototype.toString.call(new String) // [object string]

As you can see, this is not the ideal return value. Here is a JavaScript function that would help make your code more readable (source):

function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is('String', 'test'); // true is('String', new String('test')); // true

If you want to check the type of an object, use Object.prototype.toString method instead of typeof operator. This would make your code behave as expected.

NOTE:
ECMAScript 5 changes the Object.prototype.toString method’s return values for null and undefined from object to null and undefined.

When should you use typeof?

typeof is good for checking if variables are undefined. If you make use of an undefined variable in your code, you will get a ReferenceError. Using typeof will not cause your code to throw an error.

if( typeof foo !== "undefined") { // defined }else { // undefined }

To conclude, unless you are checking whether a variable is defined or not, you should avoid using typeof.

8+ methods that will not work in jQuery 1.9

There have been many method additions and deprecations in the last jQuery releases, but never so many changes that remove previous deprecations and make backward incompatible changes in a single release. Final release of jQuery 1.9 will be announced today. This article will help you get an overview of what’s changing and how to get prepared. So lets review these changes.

1) $.browser is no longer available

$.browser added in v1.0, deprecated since v1.3 and now it's gone. If possible use browser feature detection ($.support) instead of browser sniffing ($.browser). The documentation says that it may be moved to a plugin, but it's not yet (well, not considering jQuery Migrate of course). If you haven't used $.support before, we will cover it in our next post.

For those who really need just the browser sniffing feature back, you can copy-paste the highlighted code from jQuery 1.8.3's core here.

2) .andSelf() is renamed to .addBack()

.andSelf() added in v1.2, deprecated in v1.8. It's used for adding previous selection set to the current set in the chain.

For example: $('.first-set').children().andSelf() - would return a set with all children of the .first-set, plus .first-set's themselves. It took no arguments and now it has been replaced by .addBack() method that does the exact same thing, but accepts optional selector argument to filter out the set. So with the example above you could say: $('.first-set').children().addBack('div') - return all children of .first-set, plus .first-set's that are <div>s.

3) Removed deprecated .sub()

.sub() added in v1.5, deprecated in v1.7. Lets you create a copy of jQuery object, so that methods' default behaviours could be overwritten.

For example you could overwrite jQuery's .data() methods so that it would try to fetch required data from your server if it's not found on the element.

(function() { var copy = jQuery.sub(); copy.data = function(element, key, value) { // Make sure user is trying to get, not set data if(!!value) return jQuery.data.apply(this, arguments); // Get data using default jQuery.data() method var data = jQuery.data.apply(this, arguments); if(!data) { // if no data, get it from the server data = $.ajax({ AJAX_INFO }); } // Once we have the data, cache it using // original $.data() and return to the callee return jQuery.data.apply(this, arguments, data); }; copy(document).ready(function($) { alert($(".test-elem").data(); }); })();

If you want to study how it was accomplished, here is the related code from 1.8.3 code base.

4) Can't toggle through click events, only visibility

.toggle() added in v1.0, deprecated in v1.8. There were 2 .toggle() methods: one that animates show/hide, the other toggles click events. The one that toggles through click handlers is removed. So .toggle(function(){}, function(){}) will not work. Here is the related code in jQuery Migrate plugin.

5) No more $('img').error()

.error() added in v1.0, deprecated in v1.8. Not to be confused with $.error() method, that throws new Error(msg);

6) .attr() for working with attributes only

.attr('value', newValue) used to set property instead of attribute. To set current value use .prop('value', newValue) and .val(newValue) for form elements.

Learn the difference between property and attribute.

7) Removed "hover" pseudo-event

"hover" – there is no more event called hover. Instead use "mouseenter mouseleave". Please note, that only pseudo-event name is no longer available. You can still use .hover() method.

8) Global AJAX events triggered on document

ajaxStart, ajaxSend, ajaxSuccess, ajaxError, ajaxComplete, ajaxStop now must be bound to 'document'.

9) Internal undocumented changes

There are also some other internal methods that were either changed or removed (like .data('events') and $.clean()), but since they are not documented I guess you are not using them.

How to deal with all the changes?

As you can see jQuery 1.9 throws away many deprecated methods, but the team understands that there is a lot of code in production that relies on these features. So jQuery team provided us with jQuery Migrate plugin that makes code written prior to 1.9 work with it.

If you use unminified version of the plugin, it will log warning messages in console if your code uses any of the deprecated methods. The minified file is for production and it does not throw any warnings.

How to prepare your jQuery plugin for the new plugins.jquery.com site

It’s been over a year since the unfortunate event that whipped out the plugins.jquery.com site’s database. But sometimes unfortunate events lead to better things and that’s the case with the Plugins site. Instead of trying to reinvent the wheel and create a website equally useful for plugin users and plugin developers (while fighting spam, maintaining the servers, etc.), the team decided to embrace the power of existing tools. Now plugin developers will maintain their code on GitHub taking full advantage of all its’ features, while jQuery Foundation concentrates on building a better user experience for “plugin users”.

This means that plugin development and maintenance lifecycles are moving over to more confortable and more suitable for this kind of work GitHub platform.

There seems to be a lot of confusion among “plugin users”, that they’ll need to deal with GitHub and such. “NO” – plugin users will see all necessary information about the plugin on a user friendly plugins.jquery.com website.

HTML: The difference between attribute and property

In this short post I will explain the difference between attributes and properties in HTML. The .prop() function introduced in jQuery 1.6 raised a lot of questions about the difference and I hope this post will help you to understand it.

What is an attribute?

Attributes carry additional information about an HTML element and come in name=”value” pairs. Example: <div class=”my-class”></div>. Here we have a div tag and it has a class attribute with a value of my-class.

What is a property?

Property is a representation of an attribute in the HTML DOM tree. So the attribute in the example above would have a property named className with a value of my-class.

Our DIV node |- nodeName = "DIV" |- className = "my-class" |- style |- ... |- ...

What is the difference between attribute and property?

Attributes are in your HTML text document/file, whereas properties are in HTML DOM tree. This means that attributes do not change and always carry initial (default) values. However, HTML properties can change, for example when user checks a checkbox, inputs text to textarea or uses JavaScript to change the property value.

Here is a visual representation:
HTML DOM <input value="default" /> value = default ---------------- Current values: Attribute: "default" Property: "default"

Assume user inputs his name "Joe" into the inputbox. Here are what attribute and property values of an element will be.

HTML DOM <input value="default" /> value = Joe ---------------- Current values: Attribute: "default" Property: "Joe"

As you can see, only element’s property is changed, because it is in the DOM and dynamic. But element’s attribute is in HTML text and can not be changed!

I hope this helps to understand the difference between attributes and properties. If you have any questions please leave them on jQueryHowto Facebook page.

Also, stay tuned for the next post about the difference between jQuery.attr() and jQuery.prop() and when to use one over another.

jQuery Globalization plugin — jquery.glob.js

This is the first post of a series that are dedicated to jQuery’s new Microsoft contributed Globalization plugin or shortly jquery.glob.js. In this first post I will try to cover the very basics like library licensing, “the good & the bad” and some thoughts on how it could be improved (IMO).

I will be post some jQuery globalization plugin tutorials in coming days, so bare with me.

Before we jump into licensing and support issues, first things are first. What’s up with the name? It’s confusing! When did we start calling localization (l10n) a globalization?! I haven’t seen any g12n abbreviations lately, have you? When I first came across it, I thought it was some wicked jQuery solution to "global variables are evil" idea or solution to some other problem that I am not even familiar with :) Don’t you agree, it’s confusing a bit.

So, there you go. One little improvement: "Don’t confuse, rename it!"

Before we talk about the jQuery globalization plugin license, let me mention that this plugin is now officially supported by jQuery Project. Which means that it will be under continues improvement by jQuery core team and will be compatible with the future jQuery and jQuery UI releases. Also globalization plugin will become a part of the jQuery UI project.

jQuery Project officially supports jQuery Globalization plugin.

Now, the legal stuff – the license. Because jQuery project accepted the globalization plugin as officially supported (and of course because Microsoft agreed to its terms) jQuery Globalization plugin is distributed under the same license as core jQuery.js. So you are safe to do pretty much anything.

jQuery Globalization plugin is licensed under the same non-restrictive terms as the core jQuery.js

After playing with the plugin for a while I realized that it does not do any DOM manipulations and you certainly don’t expect any animations. So what’s the point of having it as jQuery plugin and not a general JavaScript globalization/localization library? This way a larger community could benefit from it. I guess it was more of marketing decision rather than technical.

JavaScript library alternative to globalization plugin would be nice.

To be honest, JavaScript and jQuery community had a lack of localization libraries and jQuery Globalization plugin with over 350 localizations is a great solution. Surely, plugin’s exposed function names and namespacing could be improved, and most probably will be, but we’ll talk about it in our next “jQuery Globalization plugin tutorial” post. Stay tuned…

jQuery mobile source code

If you want to download jQuery Mobile source code and look into it just like everybody else, we are all out of luck :(  As I mentioned in my previous post jQuery mobile facts, the source code will be available in October this year.

The jQuery Mobile source will not be in a separate jquery.mobile.js file. It will be right in the jQuery core. This means that jQuery team is fixing and improving jQuery core so that it works nicely in all major mobile phones and devices.

By the way, if you want to keep track of the jQuery mobile source code and be the first one to download it, when it is available, you should watch jQuery on GitHub.

The big part of the upcoming jQuery mobile is new UI components that work and render nicely in all mobile devices and degrade gracefully. So, keep an eye on jQuery UI as well. Here is the jQuery UI GitHub page.

Meanwhile you can read all jQuery mobile facts here.

jQuery code / syntax guidelines

We all write our own jQuery code and since creating custom jQuery plugins is so easy, we all create our own jQuery plugins. And all of us have our own code syntax preferences. For example:

function myFunction() { ... } // some prefere it like this function myFunction() { ... }

If you want to publish your jQuery plugins following jQuery core code writing guidelines is a good idea. This would make your code more easier to read to other jQuery developers. Follow the link above and go through the guidelines (it will only take a few minutes). The guidelines page shows gives you general guidelines, but I went through the jQuery core code and found several additional ones. I lay they out at the end of this post.

In short, the official guidelines are as follows: (Taken from official docs)

  1. Use tabs to indent your code
  2. Use liberal spacing":
    function myFunction ( myVar, myVar2 ) { // Pay attention to spaces around // the brackets and curly brackets }
  3. Use strict equality checks whenever possible (===)
  4. Braces should always be used on blocks and statements should not be on the same line as a conditionals:
    // NO: if ( true ) blah(); // YES: if ( true ) { blah(); }
  5. When checking an object type:
    String: typeof object === "string" Number: typeof object === "number" Function: jQuery.isFunction(object) Array: jQuery.isArray(object) Element: object.nodeType See full list on official docs page (link above)
  6. Don't use "string".match() for RegExp, instead use .test() or .exec()
  7. Node related rules:
    • .nodeName should always be used in favor of .tagName.
    • .nodeType should be used to determine the classification of a node (not .nodeName).
    • Only attach data using .data().

Now let’s see other additional rules that I could spot reading the jQuery core code.

Additional jQuery code / syntax guidelines:

  1. The first thing that I noticed was multiline comments did not use common /* comment */ syntax. In jQuery core all multiline comments use line comment syntax // comment.
    // This is an example of multiline // comment syntax used in jQuery core.
  2. Local variables are declared and initialized on one line just below the function declaration with no extra line:
    function someFunction () { var target = arguments[0] || {}, i = 1, name; // Empty line and then the rest of the code }
  3. When declaring objects, there is no space between property name and colon:
    { myName: "", myFunc: function( ) {} }
  4. All strings are in double quotes " ", not single quotes ' ':
    var myMarkup = "<a href='/a'>a</a>";
  5. The last but not least, variable naming uses camelCase.

Create callback functions for your jQuery plugins & extensions

Most of the time custom jQuery plugins and extensions that we create do not use a callback functions. They usually simply work on DOM elements or do some calculations. But there are cases when we need to define our own custom callback functions for our plugins. And this is especially true when our plugins utilize AJAX querying.

Let’s say our custom jQuery extension gets data by making some AJAX request.

$.extend({ myFunc : function(someArg){ var url = "http://site.com?q=" + someArg; $.getJSON(url, function(data){ // our function definition hardcoded }); } });

What is bad in this jQuery code is that the callback function is defined and hardcoded right in the plugin itself. The plugin is not really flexible and its user will have to change the plugin code, which is bad!

So the solution is to define your own custom callback function argument. Here is how it is done:

$.extend({ myFunc : function(someArg, callbackFnk){ var url = "http://site.com?q=" + someArg; $.getJSON(url, function(data){ // now we are calling our own callback function if(typeof callbackFnk == 'function'){ callbackFnk.call(this, data); } }); } }); $.myFunc(args, function(){ // now my function is not hardcoded // in the plugin itself });

The above code shows you how to create a callback function for AJAX load, but if you want to create a simple callback function for your jQuery plugin, for example the one that executes on your own custom events. To achive this you can do the following:

$.extend({ myFunc : function(someArg, callbackFnk){ // do something here var data = 'test'; // now call a callback function if(typeof callbackFnk == 'function'){ callbackFnk.call(this, data); } } }); $.myFunc(someArg, function(arg){ // now my function is not hardcoded // in the plugin itself // and arg = 'test' });

jQuery.noConflict – Resolving conflicts with other javascript libraries that use $() function

One of the reasons that make a software popular is its extensions and plugins. jQuery has plenty of plugins that do almost anything you want, from simple button hide to full blown galleries. Plugins let non developers easily add functionality they need to their websites and there are times when one might include more than one javascript library such as prototype.js, YUI or mootools with jQuery. They all use $ as their main function name. Including second library might brake the behavior of the first one. To resolve such cases jQuery introduces .noConflict() method.

When you call .noConflict() jQuery will return $() to it’s previous owner and you will need to use jQuery() instead of shorthand $() function.

.noConflict() usage example (From jQuery Docs site)

<html> <head> <script src="prototype.js"></script> <script src="jquery.js"></script> <script> jQuery.noConflict(); // Use jQuery via jQuery(...) jQuery(document).ready(function(){ jQuery("div").hide(); }); // Use Prototype with $(...), etc. $('someid').hide(); </script> </head> <body></body> </html>

You can also use the following code snippets to still use $() in your code, but with one drawback, you will not have access to your other library’s $() method.

// Method 1 jQuery(document).ready(function($){ $("div").hide(); }); // Method 2 (function($) { /* some code that uses $ */ })(jQuery);

TIP:
Don’t forget that you can always assign jQuery to any other variable name to use it as your shorthand: var $_ = jQuery;

jQuery custom selectors with parameters

My last tutorial on how to create a custom jQuery selector showed you the basics of creating custom filters in jQuery. Now, it is time to get more serious with selectors and create more advanced jQuery selectors – custom jQuery selectors with parameters. To get an idea of what I am talking about think of :contains(someText) selector.

Anyway, let’s create our own jQuery selector that takes arguments. The basic syntax is the same:

$.expr[':'].test = function(obj, index, meta, stack){ /* obj - is a current DOM element index - the current loop index in stack meta - meta data about your selector !!! stack - stack of all elements to loop Return true to include current element Return false to explude current element */ };

meta is a parameter we are interested in. meta is an array that carries an information about our selector. Here is what it looks like:

$('a:test(argument)'); //meta would carry the following info: [ ':test(argument)', // full selector 'test', // only selector '', // quotes used 'argument' // parameters ] $('a:test("arg1, arg2")'); //meta would carry the following info: [ ':test('arg1, arg2')', // full selector 'test', // only selector '"', // quotes used 'arg1, arg2' // parameters ]

Here as you can see, we can make use of the arrays fourth (meta[3]) value to get a hang of our parameters.

Creating custom jQuery selector with parameters

Now, let’s improve our selector from previous post that selects all links with non empty rel attribute and make it select any element with specified non empty attribute. Here is the code to do just that:

$.expr[':'].withAttr = function(obj, index, meta, stack){ return ($(obj).attr(meta[3]) != ''); };

See it in action here.

Custom jQuery selectors

jQuery makes it easy to select elements you need using CSS selectors. It is undoubtedly one of the jQuery features that makes it a great javascript library. On top of standard CSS selectors jQuery introduces some custom selectors that makes your code even more simpler and easier to read.

Examples of custom jQuery selectors are: :header, :even, :odd, :animated, :contains(text), etc.

And the best part is that jQuery lets you create and define your own custom selectors using custom selector creation template below.

jQuery Custom Selector Creation Template:

$.expr[':'].test = function(obj, index, meta, stack){ // obj - is a current DOM element // index - the current loop index in stack // meta - meta data about your selector // stack - stack of all elements to loop // Return true to include current element // Return false to explude current element }; // Usage: $('.someClasses:test').doSomething();

Let’s now create a very simple custom selector using the template above. Let’s say we want a custom jQuery selector that will return elements with nonempty rel attribute.

$.expr[':'].withRel = function(obj){ var $this = $(obj); return ($this.attr('rel') != ''); }; // Usage: $('a:withRel').css('background-color', 'yellow');

The code above creates a custom selector that will select only elements with not empty rel attributes. Here is the above code’s demo page.

You might also be interested in reading about jQuery custom functions.

UPDATE: Read about creating custom jQuery selectors with parameters.

Mozilla Jetpack & jQuery

Jetpack is a new product of Mozilla Labs. It is basically a new way to create Firefox plugins using web programming languages like HTML, CSS and JavaScript. The idea behind is the same as for Adobe AIR. If you know HTML, CSS and JavaScript you can build a Firefox plugin in no time.

The bad news is that Jetpack is still in early developer testing stage, so it is not available in Firefox yet. The good news is that Jetpack is using jQuery and you can use it to do all kinds of stuff like responding to user click events, manipulate any website DOM elements and use cross-site XMLHttpRequest object, etc. Besides, Jetpack can be setted up to use other javascript libraries such as prototype.js, dojo.js etc. and third party API libraries such as Twitter, Google, etc. API libraries.

Where to go from here?

If you want to learn more about Jetpack and how to use jQuery with it refer to this links:

  1. Watch this Jetpack video
    Good starting point to get an idea of what Jetpack is and how jQuery is used within it. Also good starting point to understand what kind of things can be don with Jetpack.
  2. Read Jetpack tutorial
    Official Jetpack introduction tutorial from Jetpack team. Probably the first article you must read about developing for Jetpack.
  3. Jetpack API documentation
    A list of global variables that are available in your Jetpacks. Currently it has a very limited global variables and functions.
  4. Jetpack plugin for your Firefox
    If you want to develop Jetpacks you need to install this Firefox plugin.
  5. Available Jetpack to investigate the code here and here.
    Most developers prefer understanding the logic and learning by investigating someone else’s code easier.

I am planning to post more Jetpack tutorials on this blog and try to show what kind of things can be done using Jetpack and jQuery. Keep tuned by following me on Twitter (@jQueryHowto) or subscribe to blog’s RSS.

Javascript for() loop vs jQuery .each() performance comparison

This post is an outcome of 15 minutes of free time and a question that I had yesterday. This question were:

  1. How fast jQuery’s .each() method is?
  2. How does it compare to javascript’s native for loop?

It is clear without any performance tests that native javascript for loop is faster, but I always used jQuery’s .each() utility with caution. It always felt like I will get a performance penalty for using it. So I tried to never use it.

So today, I wrote up a little javascript performance test and got my answers. Basically, I created an array and iterated through it using native for loop and jQuery’s .each() iterator. All I did was just an iteration and no array amendments or any other logic. I know it is very basic, but that’s exactly what I want to know. How fast they iterate!

Performance test code:

console.time('TestNative'); length = myArray.length; for( i=0; i < length; i++){ myArray[i]; } console.timeEnd('TestNative'); console.time('TestjQuery'); jQuery.each(myArray, function(i, val) { val; }); console.timeEnd('TestjQuery');

Performance test results:

JavaScript Native FOR loop Array size Time ========== ====== 10,000 7ms 100,000 62ms 1,000,000 613ms jQuery .each() loop Array size Time ========== ====== 10,000 10ms 100,000 177ms 1,000,000 1100ms

As you can see native for loop is never over 1ms. That’s probably because we are not doing anything with our array and browser simply optimizes the code or maybe its that fast :)

Usually we don’t have more than 1000 items in our arrays and objects, that is why I guess it can be concluded that using .each() loop in our code will not cause any performance penalties.

Tip for jQuery & handheld device developers

This week’s usual “Friday short post” about using jQuery in handheld devices. If you are a developer who is using jQuery in applications that were developed for use in environments with small processing power such as handheld devices, mobile phones, PDA’s, etc. you will find this post useful.

Anyway, back to the topic. For whatever reasons you chose to use jQuery in your application (I would suggest using plain javascript for better performance) jQuery effects such as animation, hide and show, etc. most likely were probably one of the reasons. Unfortunately, jQuery effects are process intensive and in “slow” environments it is recommended to turn them off. Fortunately, jQuery provides you with such a method. It lets you disable all animations and effects by changing jQuery.fx.off setting to true.

// Dissable all effects jQuery.fx.off = true; // Shorthand $.fx.off = true;

Now all your effects such as fadeIn(), fadeOut(), slideDown(), slideUp(), etc. will not be animated. They will simply be hidden and shown immediately (by changing CSS rules display:none; display:block;) to save CPU processing time.

NOTE:
By setting the jQuery.fx.off back to false you enable all animations and effects.

jQuery AJAX functions (load(), $.get(), etc.) are not loading new page versions problem

Today I would like to share with you a quick solution to the common problem when your AJAX calls to some page that changes over time is not being loaded to your page. In other words, jQuery or your browser is not loading new version of the page.

This problem is common in Mozilla Firefox (FF). Internet Explorer (IE) users I believe, do not experience this problem. Usually it occurs when you use jQuery AJAX functions in javascript setInterval() method. Basically, what happens is that Firefox can not see the changes been made to the page and thinks it’s the same with the old one. So Firefox loads it from cache and you don’t see the new version of your page. To resolve this issue, you should simply add a random string to the request like below.

The solution:

// Reload mypage.html every 5 seconds var refresh = setInterval(function() { // Minimized code, suggested by Kovacs $('#mydiv').load("mypage.htm?" + 1*new Date() ); }, 5000);

Check if jQuery plugin is loaded

The previous post checked if jQuery is loaded, now it is time to check if particular jQuery plugin is loaded. Checking if plugin exists or if plugin has been already loaded is useful if you are writing your jQuery code that depends on that plugin.

Here is how to check if some jQuery plugin is loaded or not:

if(jQuery().pluginMethod) { //jQuery plugin exists } else { //jQuery plugin DOES NOT exist }

As you know from previous post on namespacing javascript plugins are created as an additional namespace within jQuery namespace. All you have to do to check if plugin exists is to check if it’s namespace / function is defined.

For example, let’s assume that my plugin depends on jQuery Validation plugin. To check if validation plugin is loaded I would do the following:

if(jQuery().validate) { // Validation plugin exists // Now I can use $('#someId').validate() } else { // Validation plugin DOES NOT exist }

Only the last element is bound/inserted/etc. in your javascript code’s “for” loop

There is a common problem when you use javascript for loop to bind an event function or add a class that comes from looping selection’s attributes.

To make clear what I mean consider this example:

var lis = $('ul li'); for (var i = 0; i<lis.length; i++) { var id = lis[i].id; lis[i].onclick = function () { alert(id); }; } // All li's get and alert the last li's id

There is no obvious code syntax nor logical problem in this code. But you still will get last li’s id in alert window whichever li you click.

The solution to this problem is to rewrite your code similar to this one:

var lis = $('ul li'); for (var i = 0; i<lis.length; i++) { var id = lis[i].id; lis[i].onclick = function (the_id) { return function () { alert(the_id); }; }(id); }

Here, we are introducing another anonymous function which will be called immediately after it has been declared, because of the trailing () (in our case (id)) with the current id.

This solves the problem of all items in the loop getting the last arrays/elements/etc. attribute value (id/class/etc.).

jQuery For Firebug

We all use Firebug and sometimes need jQuery in pages that don’t already have it. In such cases you can use the following javascript code or the bookmarklet that would insert jQuery into the page’s DOM on the fly. Thus making jQuery available for use in Firebug.

Load jQuery to Firebug

Here are two options to jQuerify any page. The code is taken from a jQuerify javascript code snippet by John Resig.

Method 1: You can run this code to make jQuery available in Firebug:

var s = document.createElement('script'); s.setAttribute('src', 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js'); document.body.appendChild(s); s.onload=function(){ /*Your Code Here*/ }; void(s);

Method 2: Or you can drag this bookmarklet to your browser’s bookmarks toolbar:

  • Load jQuery – When you click on this link it will load jQuery from Google’s server and make it available in Mozilla add-on Firebug.

How to use YUICompressor to compress your javascript code?

Since writing on this blog I posted two jQuery plugins and I needed to compress my js files. So as jQuery documentation suggests I used YUICompressor. YUICompressor is javascript and CSS file/code compressor written in Java language. So to run one yourself you will need JRE installed on your machine.

Then call this command:

java -jar /path/to/yuicompressor.jar path/to/file.js -o path/to/minimized.file.js

Your file will be compressed and saved to path you specified as the last parameter (in our case minimized.file.js).

Links:

  1. Download YUICompressor
  2. Download JRE (required to run java applications)
  3. Online version of YUICompressor