Showing posts with label reference. Show all posts

4 jQuery Cross-Domain AJAX Request methods

The web has changed and with it the way we develop websites. Today, the web is becoming a place where we develop web apps, rather than websites. We use third party API's to create our next mashups. So knowing how to make a cross-site AJAX request or requests that do not comply with the same origin policy is a must. In this article, you will learn 4 cross-site AJAX request methods (plus 4 bonus legacy methods and links to jQuery plugins).

This methods will be handy to overcome Same origin policy as well. Browsers will throw an error if you are making AJAX request to the same domain but with different protocol (to https from http), use different port (http://same-domain.com:81) or subdomain.

This article reviews the following 4 methods and discusses their advantages & disadvantages. Also, summarise cases when they are better used.

Here is the list of methods:

  1. CORS (Cross-Origin Resource Sharing)
  2. JSONP
  3. window.postMessage
  4. Setting up a local proxy
  5. + 4 bonus legacy methods (document.domain, window.name, iframe, flash)
  6. + list of JavaScript libraries and jQuery plugins for making XSS requests.

Before we dive into the method details, let's cover most common cases:

  • Firstly, if you are trying to read data that is available as RSS feed, you are better off with universal RSS to JSON converter powered by Google.
  • Secondly, if you are accessing data from some popular website API, it's more likely they support JSONP as well. See their documentation.

JSONP is a cross browser method that does not rely on any browser hacks. It is supported by all browsers and many javascript libraries provide methods that make JSONP request seamless.

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

jQuery Form Reset

This post shows you how to reset HTML form using jQuery. Also, in the notes section below, you will find a list of special cases and things to keep in mind while resetting form.

Please note that this post discusses 2 cases of resetting a form:

  1. Resetting form values to their default/initial values (similar to clicking on form "reset" button);
  2. Clearing form values (clearing form values, no matter what their default values were).

1. Reset form values

Probably, you already tried to use $("your-form").reset() method and got the following error:

TypeError: $(...).reset is not a function

That is because jQuery does not have .reset() method. However, DOM form elements have .reset() method. It resets form values to their initial values. In other words, if we had an input field with value="set on server" attribute set, and then, user typed in some other random text. On reset() that input fields value would be reset to "set on server" again and not to " ".

That out of the way, here is how you can reset a form using "pure" JavaScript.

// JavaScript only syntax getElementById("your-form-id").reset(); // Using jQuery selectors $('.my-form-class')[0].reset();

Here is a better way to reset your form with jQuery. Simply trigger a reset event on your form.

// jQuery syntax $('.my-form-class').trigger("reset");

Notes on method 1

Things to remember:

  • Form values are reset to their initial/default values. They are not cleared/emptied.
  • Hidden values are not reset. If you have changed hidden input field values, you will have to reset them manually. You can do it by subscribing to reset event.

2. Clear form

The difference between clearing and resetting a form is that in clearing form values we clear all form fields. In other words, we will not reset them to their default values, but will replace their content with "" (empty space).

In other to do that, we will have to go through each field in the form and set its' value to "".

UPDATE: Replaced the code with the one from learningjquery.com. It creates a clearForm jQuery plugin.

$.fn.clearForm = function() { return this.each(function() { var type = this.type, tag = this.tagName.toLowerCase(); if (tag == 'form') return $(':input',this).clearForm(); if (type == 'text' || type == 'password' || tag == 'textarea') this.value = ''; else if (type == 'checkbox' || type == 'radio') this.checked = false; else if (tag == 'select') this.selectedIndex = -1; }); };

Here is how to use clearForm jQuery plugin:

// Call it on your <form> $('form').clearForm();

Notes on method 2

Put the plugin definition code into jquery.clearform.js file and include it your project.

jQuery: $.type()

This post covers all about jQuery’s .type() method. You will learn what it does, see its’ usage examples and understand the difference between jQuery’s .type() and JavaScripts’ typeof operator.

Without further ado, let’s find an answer to the following question.

What does $.type() do?

jQuery.type() method returns internal JavaScript class name of the passed argument.

jQuery.type(1) // "number" jQuery.type("foo") // "string" $.type(true) // "boolean" $.type(undefined) // "undefined" $.type(function(){}) // "function" $.type(new Date()) // "date" $.type(/test/) // "regexp" $.type(null) // "null"

You might argue, why should I use jQuery .type() function when JavaScript already has native typeof operator that does just that. Well, you are in luck. In our previous post I explained why JavaScript’s typeof operator fails in what it’s supposed to do and excels in something else. Take the time and read the article.

When would you need it?

The method is very handy when writing a jQuery plugin or a function that can receive different type of arguments (e.g. $.css(Array or String)) or take optional parameters (e.g. $.click([eventData], function)).

In the case of $.click() method above:

/* You can either check: - eventData's type - fn === undefined */ click: function(eventData, fn){ if($.type(fn) === "undefined"){ fn = eventData; eventData = {default: "value"}; } }

Notes and Caveats

I would like to leave you with some notes on $.type() method:

  • as of jQuery 1.9 $.type(new Error()) will return "error"
  • if the argument type is not one of the list below, method will return "object":
    • Boolean
    • Number
    • String
    • Function
    • Array
    • Date
    • RegExp
    • Object
    • Error

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.

ReferenceError: $ is not defined

This post will explain the root cause of the Reference Error in your browser’s console log. Also, list most common cases with examples and solutions. Without any further ado, lets see what a reference error is.

This is a common JavaScript error that says: you are trying to access a variable or call a function that has not been defined yet.

Reproducing the error:

// VARIABLES foo; // ReferenceError: foo is not defined var foo; foo; // No more errors // FUNCTIONS bar(); // ReferenceError: bar is not defined bar = function(){}; bar() // No errors

By now, you might have guessed the reason behind the "ReferenceError: $ is not defined" error. It is exactly the same as the bar() example above, but the name of the function is $ instead of bar this time. So, what it means is that we are trying to access the method $ that has not been defined yet. When is it possible? Only when jquery.js file has not been loaded successfully before we tried to call $().

Some common cases when error may occur

  1. Problem: Path to your jquery.js file is broken and it can not be found (Error 404).

    <script src="/wrong/path-to/jquery.min.js"></script>

    Solution: fix your path to jquery.js file. If your project is a public website, you better use Google hosted jQuery file.

    <script src="/correct/path-to/jquery.min.js"></script>
  2. Problem: jQuery plugin is included before jQuery file.

    <script src="/path-to/jquery.plugin.js"></script> <script src="/path-to/jquery.min.js"></script>

    Solution: Include jquery.js file before any jQuery plugin files.

    <script src="/path-to/jquery.min.js"></script> <script src="/path-to/jquery.plugin.js"></script>
  3. Problem: You are including jQuery file without the protocol in the URL and accessing the page from your local file system.

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

    Solution: Temporarily add HTTP protocol (http:// instead of //) in the URL while you are developing.

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
  4. Problem: jQuery file is included from the web, but you don't have an internet connection. It is a silly mistake, but you would be surprised how ofter it happens.

    <script src="http://www.example.com/js/jquery.min.js"></script>

    Solution: Include local jquery.js file copy or connect to the internet :)

    <script src="/js/jquery.min.js"></script>

If the above cases do not solve your case, try to figure out why jQuery is not loaded before the line where this error is thrown.

jQuery: Test/check if checkbox is checked

Testing if certain checkbox is checked using jQuery is pretty simple task. But I, just like many other developers, keep forgetting the exact syntax. So I decided to carry on a little research on the subject and gather all related information including small caveats and write this article for the future reference.

This post covers 4 methods to check if checkbox is checked. All methods especially do the same thing: test if checkbox has checked property set. But depending on the version of jQuery you are using, the methods may vary. Lets consider we have the document setup below and see how to test checkbox checked using different versions of jQuery.

<input id="checkbox"  type="checkbox" name="one" value="1" checked="checked"> <input id="checkbox2" type="checkbox" name="two" value="2"> <input id="checkbox3" type="checkbox" name="thr" value="3">

Using jQuery version 1.6 or newer

As I mentioned above, we need to check the checked property of an element and correct way of doing it is to use .prop() method. So if other methods do not add any value to your code’s readability, please use the first method below.

// First method - Recommended $('#checkbox').prop('checked') // Boolean true // Second method - Makes code more readable (e.g. in if statements) $('#checkbox').is(':checked') // Boolean true // Third method - Selecting the checkbox & filtering by :checked selector $('#checkbox:checked').length // Integer >0 $('#checkbox:checked').size() // .size() can be used instead of .length // Fourth method - Getting DOM object reference $('#checkbox').get(0).checked // Boolean true $('#checkbox')[0].checked // Boolean true (same as above)

Earlier version of jQuery (up to v1.5)

jQuery version 1.6 introduced .prop() method to get HTML/DOM element’s property instead of an attribute. Prior to version 1.6 we had to use .attr() method instead. Read more about the difference between .prop() and .attr().

// First method - Recommended $('#checkbox').attr('checked') // Boolean true // Second, Third & Fourth methods – The same as for version 1.6. See above.

Caveats & problems

What if your jQuery selector has a set of more than one checkbox? This is how the methods above will behave?

Case 1: <input class="check" type="checkbox" name="one" checked="checked"> <input class="check" type="checkbox" name="two"> Case 2: <input class="check" type="checkbox" name="two"> <input class="check" type="checkbox" name="one" checked="checked">
// Case 1: $('#checkbox').prop('checked') // true $('#checkbox').is(':checked') // true $('#checkbox:checked').length // 1 $('#checkbox')[0].checked // true // Case 2: $('#checkbox').prop('checked') // false $('#checkbox').is(':checked') // true $('#checkbox:checked').length // 1 $('#checkbox')[0].checked // false

jQuery attribute selector $('elem[name]') does not return updated property value. So use other methods instead.

$('#checkbox[checked]').length; // Integer 1 $('#checkbox').prop('checked', false); // Uncheck the checkbox $('#checkbox[checked]').length; // Still returns 1, not 0

Select all checked checkboxes on the page or within a container.

$("input[type=checkbox][checked]"); // All checkboxes in the document that are checked

This is all I could find on the subject. Please bookmark or share the article so that it is easier to find it later.

jQuery .end() explanation & examples

jQuery's .end() method is one of the most rarely used methods that I know of. In this post I would like share remind you what it does and how we can use it to make our jQuery code more readable.

Firstly, what does it do?

Put simply .end() cancels the last filtering action and returns a set like it was before the filtering was applied. It's best explained with an example. Consider we have this HTML code:

<ul> <li>One</li> <li>Two</li> <li class="special">>Three</li> </ul>
$('li') // would have all 3 elements $('li').filter('.special') // would have 1 (third) element only $('li').filter('.special').end() // would have all 3 elements again

Now, the main question: Why on earth would you need it?! It is actually very useful when you have to apply different methods on several sub-selections in your DOM. The game development fits this case perfectly. I have seen beautiful and easy to understand game code that was made possible by a combination of custom jQuery selectors, extending jQuery and .end() method.

Couple of examples

To give you an idea of what a code of some hypothetical game might look like:

check_mines = function(from, to_coord){ // don't pay attention to this building block $("#game-canvas") .find("div:ships") .moveElements(from, to_coord) .end() .find("div:mines") .killIfClose(to_coord) .end() .find("div:healthPack") .addHealthIfClose(to_coord) .markHealthPackUsed(to_coord) .end(); }; SomeGame.register(check_mines); // don't pay attention to this building block

As you can see, .end() helps us group related actions and make the code more readable.

Let's consider more realistic case. Let's say we have an article with images, links etc. (eg. Wikipedia articles). We need to add .content-img class to all images, than add .external-link to all external links, and finally apply a tooltip plugin to all the links that have .tooltip class within the article.

<div class="article"> <p>Text ... </p> ... </div>
$(".article") .find("img") .addClass("content-image") .end() // back to .article set .find("a:external") .addClass("external-link") .end() // back to .article set .find("a.tooltip") .tooltip() .end(); // don't really need it here, but nice to have for symmetry 

The above case is better written in 3 separate lines of codes of course, but it here to help explain the purpose of the .end().

NOTE:
If you do several filtering, you must call .end() several times as well.

$(".article").find("a").filter(".tooltip").end().end();

Hope you will find useful cases for .end() in your projects.

Bind jQuery events to tab or window close

This post shows you how to bind JavaScript functions that will fire when user navigates away from your page, closes browser or a tab. Browsers have native JavaScript events on window object: unload and beforeunload. beforeunload is a proprietary event introduced by Microsoft and supported by other browsers, but not all.

Please note, these events will be fired when user navigates away from the current page. This includes when user:

  • closes the browser or a tab;
  • clicks on any link (does not matter if it's to other domain or the current domain);
  • types any URL to the browser bar and leaves the page;
  • clicks browser's page reload, back, forward buttons.

NOTE
You must test your code, because the behavior of how browsers handle unload event has changed even in different versions of the browsers.

Catching browser/tab close event with JavaScript

Since unload is a native JavaScript event, we can get away without using jQuery at all.

window.onunload = function(){ // do some clean up clearLocalStorage(); };

If you are using alert(), confirm() or making AJAX requests here, please see what browsers block them belove.

Subscribing to browser/tab close using jQuery

jQuery introduced $.unload() event shorthand in v1.0 and deprecated it in v1.8. $.unload() is a shorthand for .bind('unload', handler).

$(window).unload(function() { // Do some code clean up });

How browsers handle alert(), confirm() and AJAX requests on unload event?

The document unload event was originally designed to let JavaScript to do some clean up. For example, clear or set cookies, but most of the time it is used to fire alert/confirm box or make an AJAX request to the server. This led to bad user experience and browsers started to block these methods in unload event.

Here is what each browser does:

  • Chromer/Safari (WebKit)
    • alert(), confirm() - blocked (confirm() returns false), AJAX request - not sent.
  • Firefox
    • alert(), confirm() - blocked (throws an internal NS_ERROR_NOT_AVAILABLE exception), AJAX requests - sent on page reload, but not on tab close.
  • IE9
    • alert(), confirm() - not blocked, AJAX requests - not sent.
  • Opera
    • alert(), confirm() - blocked, AJAX requests - not sent.

Browsers that have pop-up window blockers will block all window.open() function calls in unload event handler.

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.

All about jQuery plugin manifest file

As it was described in our previous post “How to prepare your plugin for the new jQuery plugins site” you will need to add a manifest file if you want your plugin to appear on the new jQuery plugins site. In this post we will cover everything you need to know about the manifest file, how to format it and where to put it.

What is a jQuery plugin manifest file?

It is a JSON file (not JavaScript literal) that carries all necessary information about your plugin. Information like: plugin name, description, version, author, homepage, licenses, plugin dependencies, etc. The upcoming plugins.jquery.com site will use this data to populate its’ database and create an individual pages for each plugin.

Manifest file naming conventions

The manifest file’s name must be yourpluginname.jquery.json. For example, jTwitter plugins manifest file name would be named: jtwitter.jquery.json. Please be advised, at first the file name was planned to be package.json (following common.js conventions). However, after some discussions it was changed to *.jquery.json.

There is also a concept of suites. Suites are a way to namespace many plugins in a single repository (e.g. jQuery UI would name their fils: ui.tabs.jquery.json). Suites are created manually by jQuery team.

The difference between == and === in jQuery/JavaScript

In this post I would like to explain the difference between double (==) and triple (===) equals in JavaScript/jQuery. A quick and short explanation is that == does type coercion (conversion) before checking for equality; and === does strict equation which requires values to have the same type as well.

Here is what it means:

0 == false // true 0 === false // false, because they have different types (int, bool) 1 == "1" // true 1 === "1" // false, because they have different types (int, string) null == undefined // true null === undefined // false

Detailed (longer) explanation

When you use == the javascript interpreter will convert one side of the comparison according to these rules:

  • When comparing a number and a string, the string is converted to a number value.
  • When comparing a boolean, the boolean is converted to 1 if it is true and +0 if it is false.
  • When object is compared with a number or a string, the object is converted to its’ default value (.valueOf(), .toString()). If these methods are missing a runtime error is thrown.
  • When comparing an object and another object, no type conversion is made. They are equal only if they refer the same object.

When you use === the javascript interpreter will not convert values to primitive types and make sure that the operands have the same value as well as the same type.

"foo" === "foo" // true, both operands are of type String new String("foo") === new String("foo") // false, 2 Objects refer diff object instances

Detailed comparison information can be found on Mozilla Developer Network page. Here is the summary:

  • Two strings are strictly equal when they have the same sequence of characters, same length, and same characters in corresponding positions
  • Two numbers are strictly equal when they are numerically equal (have the same number value). NaN is not equal to anything, including NaN. Positive and negative zeros are equal to one another
  • Two Boolean operands are strictly equal if both are true or both are false
  • Two distinct objects are never equal for either strictly or abstract comparisons
  • An expression comparing Objects is only true if the operands reference the same Object
  • Null and Undefined Types are == (but not ===)

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.

Check if a language file is loaded for jQuery Globalization plugin

Recently, I wrote my first jQuery Globalization plugin introductory post. I mentioned that I will write a tutorial for Globalization plugin and I am. While writing the tutorial I thought I’ll write one of my short Friday jQuery tips.

In this post you will learn how to check if a specific jQuery Globalization plugin language file is loaded or not. Globalization plugin saves localization data and all information in jQuery.cultures object. By default English language is added. So if you add "Inuktitut" language (code iu) the jQuery.cultures object will be extended and will have jQuery.cultures.iu object in it.

So to check if particular language file is loaded all we need to do is to check if jQuery.cultures.langCode is defined. Here is an example:

if($.cultures.iu){ // Inuktitut jquery.glob.iu.js lang file is loaded }else { // Inuktitut language is not loaded, load it here }

Some cultures have different alphabet, so they will have that appended in their language and culture names. For example Inuktitut has Syllabics (iu-Cans) and Latin alphabets (iu-Latn), So you will not be able to check the file existence with the code above. Here is a syntax to do it:

if($.cultures.iu-Latin){ // Will not work } // Better way to check if the lang file is loaded if($.cultures["iu-Latn"]){ // Inuktitut jquery.glob.iu-Latn.js lang file is loaded }else { // Inuktitut language is not loaded, load it here }

JavaScript to detect iPad visitors

This post gives you a short JavaScript function to detect your iPad users. Without any further ado, a javascript code to detect iPad users:

function isiPad(){ return (navigator.platform.indexOf("iPad") != -1); }

You can also detect browser version and some other stuff by parsing user agent string. Here is an iPad Safari’s user agent string for your reference:

Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10

Recently a friend of mine got himself an iPad and I couldn’t not notice how his internet browsing device preferences are changing (PC & iPad). More and more people are using hand held devices namely iPad to browse the internet. So it’s about time to show your iPad visitors some love and display your website designed specifically for iPad.

Let’s see how to do this. There are two way:

  1. Redirect iPad visitors
  2. Apply different CSS file for iPad users

Most of the posts on the internet related to iPad user detection are suggesting and showing you how to redirect (including myself in my previous iPhone & iPod detection post). However, I would recommend the second option, applying different CSS file.

You can apply the same technique described in applying different styling for javascript enabled browser with CSS post and apply different CSS rules for iPad visitors.

Sidenote: If you decide to redirect iPad users rather than apply different CSS style rules, than I would recommend using server side detection and redirection. You can see an example PHP code by David Walsh.

iPhone / iPod detection using jQuery & JavaScript

In this post you will learn how to detect iPhone/iPod using javascript/jQuery, redirect your iPhone users to mobile version of your site using javascript and alternative and better way to redirect your visitors using server-side PHP code snippet.

The latest buzz around jQuery is upcoming jQuery mobile – support for mobile devices. Current jQuery core work fine on iPhone and iPod touch browsers and most of us have created a mobile version of our websites, developed or converted websites for others. Basically, jQuery is already being used on iPhone and iPod touch devices. Without any further ado…

Javascript code to detect iPhone and iPod browsers

// Return boolean TRUE/FALSE function isiPhone(){ return ( (navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1) ); }

You might wonder why do we even need to detect if our website is ran on iPhone Safari or normal desktop Safar if jQuery works fine on both. Well, there are Safari specific CSS features that you might want to utilize and you need to know if the current browser is Safari, then you may also want to consider reducing resource consuming features like animations for iPhone version of your site.

Redirecting iPhone & iPod users

You may also use this script to redirect iPhone and iPod users to your website’s mobile version:

// Redirect iPhone/iPod visitors function isiPhone(){ return ( (navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1) ); } if(isiPhone()){ window.location = "mob.example.com"; }

For example: if your website is www.example.com and you have a mobile version at mob.example.com, then put the following script to your www.example.com.

Redirect iPhone users using PHP

It is better to detect and redirect your iPhone users on the server-side. Here is a PHP code to redirect iPhone users:

// Redirect iPhone/iPod visitors if(strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strpos($_SERVER['HTTP_USER_AGENT'], 'iPod')){ header("Location: http://mob.example.com"); }

User agent strings for your reference:

/* User Agent String for iPhone Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 User Agent String for iPod Touch Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3 */

As final words, I would like to remind you that sometimes your visitors would not like to be redirected to mobile versions of your websites. That’s why your mobile version should always include a link to your non-mobile website. The above scripts can be rewrote to check if user has chosen not to be redirected. Either set cookie or a URL parameter.

jQuery.live() – event binding to AJAX loaded elements

jQuery.live() function was introduced in jQuery version 1.3. It makes it easy to dynamically bind events to DOM elements that have not yet been created. In other words, it helps you to easily attach events to AJAX loaded elements that match your criteria.

NOTE:
If for some reason you are using old versions of jQuery, prior to 1.3, you will need to use event delegation or another method as they are described in my previous post named “How to bind events to AJAX loaded elements in jQuery 1.2.x”.

So, how does .live() function works?

It uses event delegation technique to bind to the events that fire on your page. In other words, it binds an event to the DOM tree’s root and listens to all events. When an event is fired it checks it’s originator and checks if we have bound any events to that particular DOM element.

// Example usage of jQuery().live() function $('.mySelector').live('click', function(event){ // my click event handler }); // As of jQuery 1.4.1 .live() can accept // multiple events, just like .bind() does $('input').live('focus blur', function(event){ // fires on focus and blur });

You can also pass in additional data to your events to overcome some issues caused by closure. This was introduced in jQuery 1.4. Also, it worth mentioning that data is passed when the binding is made. Keep this in mind when you pass in dynamic data.

$('.mySelector').live('click', {myVar: 'myVal'}, function(event){ // my click event handler });

NOTE:
Some events were not supported cross browser in jQuery 1.3. Events like submit were supported in Firefox only. This is resolved in jQuery 1.4. Other methods that were not supported cross browser in jQuery 1.3 include: focusin, focusout, mouseenter, mouseleave, etc.

NOTE:
.live() function also works with custom events.

jQuery.live() function performance

Because .live() uses event delegation and performs additional checks, it will always be slower then events attached to the DOM elements using .bind() function (this includes shorthands like: .click(), .submit(), etc.). However, you can improve your .live() function performance providing context (as of ver. 1.4).

// Using context for better performance // Note that context is a DOM element, not jQuery $('.mySelector', $('.myParent')[0]).live('click', function(event){ // my faster click event });

Unbinding events attached using .live() function

.unbind() function equivalent of .live() function is .die(). You can unbind ALL events attached using .live() function from an element by simply calling .die(). If you want to remove a specific event or a specific handler function of a specific event type, you can call .die('event', functionHandler).

// Remove ALL events attached using .live() $('.mySelector').die(); // Remove myFunk() from click event $('.mySelector').die('click', myFunk); function myFunk(){ alert("Clicked!"); }

If you have any questions or need any help, you can ask me on Facebook.

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.

Dynamically create iframe with jQuery

This article explains and shows how to dynamically create an iframe in your HTML document’s DOM using jQuery and/or JavaScript. It also gives you an example code. This post is not extensive explanation of how to manage and work with iframes using jQuery. This post simply shows you how to dynamically create iframes using jQuery and JavaScript and serves as a note.

Creating iframe is similar to creating any DOM element. All you need to do is to use jQuery factory like this:

// Create an iframe element $(‘<iframe />’); // You can also create it with attributes set $('<iframe id="myFrame" name="myFrame">'); // Finnaly attach it into the DOM $('<iframe id="myFrame" name="myFrame">').appendTo('body');

Don’t forget that the iframe source is just an iframe’s attribute. So you can set that just like any other attribute.

// Setting iframe's source $('<iframe />').attr('src', 'http://www.google.com'); 

UPDATE:

As BinaryKitten point’s out below, with jQuery 1.4 you can do it using the following syntax:

// Set attributes as a second parameter $('<iframe />', { name: 'myFrame', id: 'myFrame', ... }).appendTo('body');

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' });