2

In my site I have a jquery function created by using the jQuery.fn method like so:

jQuery.fn.equalHeights = function() {
    var currentTallest = 0;
    jQuery(this).each(function(){
        if (jQuery(this).height() > currentTallest) {
            currentTallest = jQuery(this).height();
        }
    });
    jQuery(this).css('min-height', currentTallest);
};

I use this function to equalize the size of sidebars on my site so I call it after the page has finished loading to make sure everything is in place before I do the sizing.

jQuery(window).load(function(){
    jQuery('#sidebar-one, #sidebar-two, #content').equalHeights();
});

This works perfectly except for on some of my pages users will add another instance of the jQuery library to their page in the body area (for whatever reason). This second library causes my function to stop working properly. I'm assuming this is because the second jQuery overwrites any functions created with the jQuery.fn method. Is there any way to prevent that from happening?

Notes: My site is running Drupal 7 so I can't easily move the scripts to the bottom of the page. The equalHeights function was not written by me; I believe I found it here on stack so my knowledge of the fn method (and JS in general) is not that extensive.



EDIT: Based on all the great suggestions below, this is how I finally got it to work.

First, I give my "default" instance of jQuery a new variable to reference:

var JQ = jQuery.noConflict();

Second, I call the more efficient version of the equalHeights function using the new jQuery variable:

JQ.fn.equalHeights = function() {
    var tallest = 0;
    return this.each(function(){
        var h = JQ(this).height();
        tallest = h > tallest ? h : tallest;
    }).css("minHeight", tallest);
};

Third, I call my function using the new jQuery variable:

JQ('#sidebar-one, #sidebar-two, #content').equalHeights();

So now any time I need to reference my original jQuery library I just use JQ and I don't have to worry about another library stepping on any of my functions.

I realize this isn't the best way to fix this problem and I'm going to work on eliminating the additional jQuery libraries but this will at least keep my sidebars properly sized in the mean time.

4

3 回答 3

1

从技术上讲,您可以将 jQuery 复制到一个新变量以供您使用 - 即JQ = jQuery;然后执行JQ(this)...

尽管您可能只想解决后续版本的插入问题 - 停止它,或者确保最后添加您的版本,并且您的所有代码都在之后执行,因此它们无法覆盖它

于 2013-07-24T13:20:37.760 回答
1

将您的代码段包装在模块 IEFE 中,传递“旧”jQuery 参考:

(function($) {
    // $ will always point to the jQuery version with the `equalHeights` method
    $(window).load(function(){
        $('#sidebar-one, #sidebar-two, #content').equalHeights();
    });
}(jQuery));

另请参阅jQuery.noConflict以了解更多技巧。

于 2013-07-24T13:26:48.977 回答
1

这是因为 jQuery 的第二个版本会覆盖前一个版本。除非您使用的是与更高版本的 jQuery 不兼容的遗留库,否则没有理由加载两个不同的版本。

要在 Drupal 7 中使用更高版本的 jQuery,您需要使用hook_js_alter脚本,然后将类似以下内容添加到您的 Drupal 主题中(由oldwildissue提供):

function MYTHEME_js_alter(&$javascript) {
  //We define the path of our new jquery core file
  //assuming we are using the minified version 1.8.3
  $jquery_path = drupal_get_path('theme','MYTHEME') . '/js/jquery-1.8.3.min.js';

  //We duplicate the important information from the Drupal one
  $javascript[$jquery_path] = $javascript['misc/jquery.js'];
  //..and we update the information that we care about
  $javascript[$jquery_path]['version'] = '1.8.3';
  $javascript[$jquery_path]['data'] = $jquery_path;

  //Then we remove the Drupal core version
  unset($javascript['misc/jquery.js']);
}

这将允许您在 Drupal 7 中使用任何版本的 jQuery。

我还注意到您的插件使用了一些非常糟糕的做法。这是您的插件的优化版本,使用良好且完善的实践:

(function($){
    $.fn.equalHeights = function() {
        var tallest = 0;
        return this.each(function(){
            var h = $(this).height();
            tallest = h > tallest ? h : tallest;
        }).css("minHeight", tallest);
    };
}(jQuery));
于 2013-07-24T13:27:40.883 回答