开发者

Using jQuery 1.4.2 and 1.6.1 but noConflict doesn't work

I'm using jQuery 1.4.2 for a fixed bar on my site that scrolls with the site as you scroll.

But I'm also using 1.6.1 for a facebook thing I'm doing, and when I add them together, the bar breaks and the facebook thing works, but when I add the noConflict in, the bar works, but the facebook breaks, so if you could look at my code, and help me?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link type="text/css" href="themes/default/jx.stylesheet.css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript">
var mc$ = jQuery.noConflict();
</script>
<script type="text/javascript" src="src/jquery.jixedbar.min.js"></script>
<script type="text/javascript">
mc$(document).ready(function() {
    mc$("#floating-bar").jixedbar();
}); 
</script>

<style type="text/css">
body {
margin: auto;
background-image: url(template.png);
background-repeat: no-repeat;
background-position: center top;
}
</style>
</head>

<body>
<div id="floating-bar">
  <ul>
        <li title="Home"><a href="http://www.atomicstarstudios.com/"><img src="icons/home.png" alt="" /></a></li>
    </ul>
    <span class="jx-separator-left"></span>
    <ul>        
        <li title="Around The Web"><a href="#"><img src="icons/network.png" alt="Share" /></a>
            <ul>
<div id="fb-root"></div>

<!-- USE 'Asynchronous Loading' version, for IE8 to work
http://developers.facebook.com/docs/reference/javascript/FB.init/ -->

<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId  : '209445949091775',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
  };

  (function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
  }());
</script>




                <li><a id="share_button" href="#"><img src="icons/facebook.png" title="Facebook" />&nbsp;&nbsp;&nbsp;Facebook</a></li>
              <script type="text/javascript">
$(document).ready(function(){
$('#share_button').click(function(e){
e.preventDefault();
FB.ui(
{
method: 'feed',
name: 'Atomic Star Studios',
link: 'http://www.facebook.com/pages/Atomic-Star-Studios/228192187207829',
picture: 'http://www.atomicstarstudios.com/logo.jpg',
caption: 'http://www.atomicstarstudios.com/',
description: 'This is the content of the "description" field, below the caption.',
message: 'Visit Atomic Star Studios for excellent prices on great printg and professional design! We Have All Your Marketing Needs!!!'
});
});
});
</script>
    <li><a href="http://www.twitter.com/atomstars"><img src="icons/twitter.png" title="Twitter" />&nbsp;&nbsp;&nbsp;Twitter</a></li>
            </ul>
        </li>
    </ul>
    <span class="jx-separator-left"></span>
    <ul>
        <li title"Top Pages"><a href="#">Top Pages</a>
            <ul>
                <li title="About"><a href="#"><img src="icons/info.png" alt="About" /></a></li>
                <li title="Products"><a href="#"><img src="icons/blogs.png" alt="Products" /></a></li>
                <li title="Portfolio"><a href="#"><img src="icons/block.png" alt="Portfolio" /></a></li>
            </ul>
        </li>
    </ul>
    <span class="jx-separator-left"></span>        
    <div class="text-container">Like us on Facebook!</div>
<iframe src="http://www.facebook.com/plugins/like.php?href=http://www.facebook.com/pages/Atomic-Star-Studios/228192187207829&layout=button_count&send=true&show_faces=false&width=100&action=like" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:80px; height:30px;" allowTransparency="true"></iframe>
    <a href="http://twitter.com/atomstars" class="twitter-follow-button">Follow @atomstars</a>
<script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
    <span class="jx-separator-left"></span>
    <ul>
        <li title="Facebook"><a href="http://www.facebook.com/pages/Atomic-Star-Studios/228192187207829"><img src="icons/facebook.png" alt="" /></a></li>
        <li title="Twitter"><a href="http://www.twitter.com/atomstars"><img src="icons/twitter.png" alt="" /></a></li开发者_开发问答>
    </ul>
    <span class="jx-separator-left"></span>
    <ul>
        <li title="Chat with us Live!"><a href="javascript:void(window.open('http://www.atomicstarstudios.com/livezilla/chat.php','','width=590,height=610,left=0,top=0,resizable=yes,menubar=no,location=no,status=yes,scrollbars=yes'))"><img src="http://www.atomicstarstudios.com/livezilla/image.php?id=04&amp;type=inlay"></a></li>
    </ul>
    <span class="jx-separator-right"></span>
</div>
</body>
</html>


There are two problems with your code.

First, you should call the noConflict in-between both jQuery requests, not after the second one. You need to load the modules you need with each version of jQuery with the version so that when you call noConflict, references to the plugins are moved with it. You should also add "true" to noConflict so that all references to jQuery are removed before loading the second one:

<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="src/jquery.jixedbar.min.js"></script>
<script type="text/javascript">
  var mc$ = jQuery.noConflict(true);
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

For more information, see the jQuery.noConflict documentation.

With that said, you should really consider find a way to not have to do this. It is not an elegant way to use jQuery.

TO ANSWER @TGR: Try this for yourself and you'll see for yourself that my solution works perfectly fine:

<html>
  <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://jixedbar.googlecode.com/svn/trunk/src/jquery.jixedbar.min.js"></script>
    <script type="text/javascript">
      var mc$ = jQuery.noConflict(true);
    </script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

    <script type="text/javascript">
      $(function()
      {
        alert('jQuery ' + mc$.fn.jquery + ': ' + ( typeof mc$.fn.jixedbar ));
        alert('jQuery ' + jQuery.fn.jquery + ': ' + ( typeof jQuery.fn.fixedbar ));
      });
    </script>

    <title>6367968</title>
  </head>
  <body>
    <p>6367968</p>
  </body>
</html>

The first alert will show "jQuery 1.4.2: function" while the second one will show "jQuery 1.6.1: undefined".


  1. load jQuery 1.4
  2. load all plugins which need to use 1.4
  3. use noConflict
  4. load jQuery 1.6

The problem is that jQuery plugins tend to be written this way:

(function($) {
    // plugin code using $ for jQuery calls
})(jQuery)

i. e. they have an internal copy of whatever window.jQuery was at the time the plugin loaded, and you cannot change that afterwards.

update: a little more detail on how noConflict works (was too long for the comments). When you load jQuery, it creates an object containing all its functions and data, and sets window.$ and window.jQuery to that object. The old value of window.$ and window.jQuery is saved in the object.

When you call noConflict, it restores the saved value (by default for $; if you call it with true, also for jQuery). This is useful if you had something in those variables before loading jQuery, and don't want it to be overwritten. E.g. if you loaded things like this:

  1. load jQuery 1.6
  2. load jQuery 1.4
  3. call noConflict(true)

then the first step would put jQuery 1.6 into $ and jQuery, the second would overwrite them with 1.4, and noConflict would restore $ and jQuery to the 1.6 version.

But since you load 1.4 first, and call noConflict between the two, the old value for $ and jQuery which is restored is undefined, which is not particularly useful, and will be overwritten by 1.6 anyway, so the noConflict call does not do anything useful beyond returning the value of $ which then can be stored by some other name ($mc in this case). var $mc = $; would work just as well for that.

As for the plugins, the auto-executing function copies the value of window.jQuery at the moment the plugin is loaded, and it does not matter at all what happens to window.jQuery afterwards:

window.jQuery = 'foo';

(function($) {
    window.fun = function () {
        console.log($);
    }
})(jQuery);

window.jQuery = 'bar';

fun(); // will log 'foo'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜