2013-07-24 3 views
2

В моем сайте у меня есть функция JQuery, созданная с помощью метода jQuery.fn как так:jquery.fn перезаписывается

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

Я использую эту функцию, чтобы уравнять размер боковых панелей на моем сайте, так что я называю это после того, как страница закончила загрузку, чтобы убедиться, что все на месте, прежде чем я сделаю калибровку.

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

Это отлично работает для некоторых из моих страниц пользователей добавят еще один экземпляр библиотеки JQuery на свою страницу в области тела, за исключением (по любой причине). Эта вторая библиотека заставляет мою функцию перестать работать должным образом. Я предполагаю, что это связано с тем, что второй jQuery перезаписывает любые функции, созданные с помощью метода jQuery.fn. Есть ли способ предотвратить это?

Примечания: Мой сайт работает с Drupal 7, поэтому я не могу легко переместить скрипты в нижней части страницы. Функция equalHeights не была написана мной; Я считаю, что нашел его здесь в стеке, поэтому мои знания о методе fn (и JS в целом) не настолько обширны.



EDIT: На основе всех великих предложений ниже, это, как я, наконец, получил его работать.

Во-первых, я даю моему «по умолчанию» экземпляр JQuery новую переменную для ссылки:

var JQ = jQuery.noConflict(); 

Во-вторых, я называю более эффективную версию функции equalHeights, используя новую переменную JQuery:

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

в-третьих, я называю функцию, используя новую переменную JQuery:

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

Так теперь в любое время, когда мне нужно ссылаться на мою исходную библиотеку jQuery, я просто использую JQ, и мне не нужно беспокоиться о том, что другая библиотека переходит на любую из моих функций.

Я понимаю, что это не лучший способ устранить эту проблему, и я собираюсь работать над устранением дополнительных библиотек jQuery, но это, по крайней мере, будет поддерживать боковые панели должным образом в среднем.

+0

NB: нет никакой необходимости, чтобы обернуть 'this' внутри плагина, хотя вам нужно внутри' .each' петли - просто сделать 'return this.each (...). css (...)' – Alnitak

+0

Я пытался вытащить его из плагина без успеха. Я попробую ваш 'return this.each()' и посмотреть, как это работает. – Cloudkiller

+0

Я говорил только о плагине. Во всяком случае, вам, вероятно, понадобится '$ .noconflict()', чтобы дать вам постоянную ссылку на главную копию jQuery, которая не будет перезаписана более поздней копией. – Alnitak

ответ

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 для дальнейших трюков.

+0

По какой-то причине я не могу заставить это работать. В jQuery для Drupal уже включен noConflict, и трюки, упомянутые на странице, похоже, не делают трюк либо ... – Cloudkiller

+0

Я выяснил проблему, и теперь она работает так, как ожидалось. Спасибо, что указал мне в правильном направлении. – Cloudkiller

1

Вы можете технически скопировать Jquery к новому переменному только для использования - т.е. JQ = jQuery; затем сделать JQ(this)...

Хотя вы можете просто хотите обратиться к вставлению последующих версий - останавливая его, или гарантируя версию добавлен последним и весь код выполняется после, поэтому они не могут переопределить это

+0

Хотелось бы избежать добавления последующих версий. Проблема в том, что это добавляет один из наших программистов, и у меня нет оценки зарплаты, чтобы остановить его. Я дам ваше предложение попробовать. – Cloudkiller

+1

@Cloudkiller Просто скажи ему, он тебя не будет есть. – Stijn

+0

Да, было бы гораздо более эффективно описать проблему для них - если вы оба работаете на одном сайте, вы не должны борется друг с другом. – SmokeyPHP

1

Это потому, что вторая версия jQuery перезапишет предыдущую. Если вы не используете устаревшую библиотеку, которая несовместима с более поздними версиями jQuery, нет причин загружать две разные версии.

Чтобы использовать более позднюю версию JQuery с Drupal 7, вы должны использовать 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']); 
} 

Это позволит вам используйте любую версию jQuery с Drupal 7.

Я также заметил, что ваш плагин использует некоторые довольно плохие практики. Вот оптимизированная версия вашего плагина, используя хорошие и хорошо разработанные методы:

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

Спасибо за оптимизированный плагин, я очень ценю его. Drupal 7 по умолчанию использует jQuery 1.4, а программист, добавляющий в дополнительные библиотеки, использует 1,8. Есть модуль для обновления основного JQuery Drupal, но он представляет некоторые другие проблемы, с которыми я еще не справился. Все сложно, но что нет. – Cloudkiller

+0

@ Cloudkiller Я вижу! Я добавил информацию о том, как использовать любую версию jQuery с Drupal 7. Если у вас проблемы с совместимостью, это совсем другая история и боль, чтобы решить :( – mekwall

+0

Спасибо за код, но я недостаточно храбр, чтобы включить 1.8 на Мой сайт еще. У нас есть 20k + страниц и проверка их, чтобы увидеть, что 1.8 сломал/изменил, это то, что я сэкономю для запуска Drupal 8. – Cloudkiller

Смежные вопросы