Monday, March 28, 2016

Handling jQuery conflicts

Many times you have to deal with multiple versions of jQuery in single page. jQuery provides a way to do that:

 <script src="~/Scripts/jquery-1.10.2.min.js"></script>  
 <script type="text/javascript">  
   var jQuery_1_10_2 = $.noConflict();  
 </script>  
 <script src="~/Scripts/Closure/NewVersion.js"></script>  
 <script src="~/Scripts/jquery-1.7.2.min.js"></script>  
 <script src="~/Scripts/Closure/OldVersion.js"></script>  

HTML
 <div id="container" style="margin-bottom:20px;">  
 </div>  
 <input type="button" id="btnAddNew" value="Add new" />  


Scenario:
There is a div and a button inside HTML page. We want to add new buttons to this div dynamically, when button 'btnAddNew' is clicked. We'll add 2 buttons: 
1) To test the code in older version of jQuery i.e. 1.7.2
2) To test the code in new version i.e. 1.10.2


I've included 2 references of jQuery: version 1.10.2 and 1.7.2.

Version 1.7.2 had live feature, which is obsolete in 1.10.2. 
Version 1.10.2 has on feature, which is missing in 1.7.2.

We'll use both these features on the same page i.e. use both the jQuery versions on the same page.


After including 1.10.2, I've included the script for noConflict. This would tell jQuery to use variable jQuery_1_10_2 instead of default '$' variable for referring jQuery 1.10.2. This means, that if you want to use any function or feature in 1.10.2, you'll have to use jQuery_1_10_2 variable, not '$'.

NewVersion.js contains the code to bind the click event for 'newbtn' class:


 jQuery_1_10_2(function () {  
   jQuery_1_10_2(document).on('click', '.newbtn', function () {  
     alert(jQuery_1_10_2(this).val() + ' clicked!!!');  
   });  
 });  

The code above, binds the click event of the buttons (added dynamically) having the class 'newbtn'. 

OldVersion.js contains the code to bind click event for 'oldjsbtn' class:


 $(function () {  
   $('#btnAddNew').click(function () {  
     var buttonText = "Button " + $('.newbtn').length + 1;  
     $('#container').append('<div class="col-xs-12"><input class="oldjsbtn btn-secondary" type="button" value="Old Js ' + buttonText + '" /><input class="newbtn btn-primary" type="button" value="New Js ' + buttonText + '" /></div>');  
   });  
   $('.oldjsbtn').live('click', function () {  
     alert($(this).val() + ' clicked');  
   });  
 });  


Note that we've used the jQuery variable jQuery_1_10_2 instead of $ here. This can however, make the code very untidy. 

Imaging you'd a javascript file with thousands of lines of code. Changing the $ sign with jQuery_1_10_2 won't be a good solution for that. You'll need to check each and every line and make sure that the code is replaced correctly. This can be cumbersome and time consuming. There is a slick way to resolve this issue using javascript closure.

Closure is basically a self executing function, which initializes and calls itself. You can also pass parameters to this function, which we'll be using in our case. 

Below is our modified NewVersion.js file using closure:


 (function ($) {  
   $(function () {  
     $(document).on('click', '.newbtn', function () {  
       alert($(this).val() + ' clicked!!!');  
     });  
   });  
 })(jQuery_1_10_2);  

We've passed jQuery_1_10_2 as an argument to this closure function and used '$' as alias. Because of it, we'll be able to use '$' throughout our script and get rid of the messy code using the variable jQuery_1_10_2. 

No comments: