tags:

views:

559

answers:

4

I am modifying some code that has a lot of jQuery but I am not sure what some of the jQuery statements are doing.

At the top of the jQuery code there is

jQuery.noConflict

*1. I understand that. But then there is a some code that has:

<script type="text/javascript">
(function($) {

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}
</script>

I get that jQuery is used because of the noConflict. What's the parameter $?

*2. In another function, they use

<script type="text/javascript">
jQuery(function(){
 var $ = jQuery;
 var cc = {
  mode : 'teaser',
  featureVisible : true,
  $loader : '<p class="loadingAnimation"><img height="32" src="' +
    config.xoImgUrl +
    '/images/ajax-loader.gif" width="32" /></p>',
                ....more code...
            }
}
</script>

So they are setting $ to the jQuery from noConflict. But why? Could they have just used jQuery?

*3. There is a plugin that I want to use that is initialized by:

   var $j = jQuery.noConflict();
    var $ = {};
    $j(document).ready(function(){
     $j.history.init(pageload);
     $j("a[@rel='history']").click(function(){
      ...more code...
     });
    });

I understand what the noConflict does but what does var $ = {} do?

A: 

There is a stink to this code. Are they using another JavaScript library?

  1. $ is usually the JQuery function, but I believe Prototype uses it as well. Could this be Prototype code? 2: You are correct. At least I can't think of a reason. 3: That resets {} to a new object. Basically canceling out JQuery
Chris Brandsma
+3  A: 

1

Are you missing some code at the end of that snippet? Usually the convention is to do this:

jQuery.noConflict();

(function($){

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}

})(jQuery);

Notice at the bottom, jQuery is passed as a parameter to the function expression, so the $ is equal to jQuery, but only within that function expression.

2

They could have used jQuery, but they are probably relying on copy/pasted code that uses $.

3

I would probably refactor these to use a convention similar to the one I mention in #1. I'm not sure why they set $ equal to an object, but it has a bad smell to it.

Zach
+8  A: 

Example 1:

I think you missed out on some code:

(function($) {

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}
)(jQuery); //This line was missing in your code.

Let's rewrite this code a little bit to understand what's going on.

function complicatedFunction($) {
          // the document.ready call goes here.
}

Next, how would you call this function?

complicatedFunction(someObject);

So inside the complicatedFunction $ refers to someObject. Agree?

If you write

complicatedFunction(jQuery);

Then inside the function, $ refers to the jQuery object. So everything inside, complicatedFunction can use '$' as like how a normal jQuery user would do.

Coming back to the original code, if we decide to not name this function i.e. make it anonymous, you can visualize the code like,

(function($) { })(jQuery);

You are creating an anonymous function, taking one argument named $. You immediately call this anonymous function passing it the jQuery object. This way, you don't modify the global $ object but all the code inside your anonymous function works like $ was always available. Cool, isn't it? :)

Example 2:

jQuery(function(){
        var $ = jQuery;
        var cc = {
                mode : 'teaser',
                featureVisible : true,
                $loader : '<p class="loadingAnimation"><img height="32" src="' +
                                config.xoImgUrl +
                                '/images/ajax-loader.gif" width="32" /></p>',
                ....more code...
            }
});

Similar to example 1, I have not seen this style of coding. (I am not even sure if this would work)

Anyway, inside the anonymous function, which is passed to the jQuery, you localize the usage of $ without impacting other code. And yes, they could have simply used jQuery object everywhere but that will be very verbose, isn't it?

Example 3:

var $ = {};

Above line defines an empty object and assigns it to the variable $.

It is same as doing,

var $ = new Object();

This is similar to how you can define an array using two different syntaxes.

var items = [];  //same as var items = new Array();

A little history

Remember, there is nothing inherently special about '$'. It is a variable name just like any other. In earlier days, people used to write code using document.getElementById. Because JavaScript is case-sensitive, it was normal to make mistake while writing document.getElementById. Should I capital 'b' of 'by'? Should I capital 'i' of Id? You get the drift. Because functions are first class citizens in JavaScript, you can always do this

var $ = document.getElementById; //freedom from document.getElementById!

When Prototype library arrived, they named their function, which gets the DOM elements, as '$'. Almost all the JavaScript libraries copied this idea. Prototype also introduced $$ function to select elements using CSS selector.

jQuery also adapted $ function but expanded to make it accept all kind of 'selectors' to get the elements you want. Now, if you are already using Prototype in your project and wanted to include jQuery, you will be in problem as '$' could either refer to Prototype's implementation OR jQuery's implementation. That's why jQuery has the option of noConflict so that you can include jQuery in your project which uses Prototype and slowly migrate your code. I think this was a brilliant move on John's part! :)

SolutionYogi
+1 this is a really great answer.
Amal Sirisena
A: 

I assume you have seen this Using jQuery with other JS libraries? I think that page answers your questions (see the Referencing Magic - Shortcuts for jQuery section at the bottom of the page).

To summarise:

  1. Passing $ is a way to use jQuery within the function block without permanently overwriting it.
  2. At a guess I can only say the author preferred the more succinct $ as opposed to jQuery.
  3. Is this inside another block? Again for convenience I think they want to reuse $ for another purpose without permanently overwriting it.

The usage of the different conflict avoidance mechanisms is a little inconsistent in the code you posted, so you might want to refactor that if you are able to.

Amal Sirisena