мирное сосуществование прототипа и jQuery?

Я очень мало знаю о JavaScript, но, несмотря на это, я пытаюсь что-то сколотить в своем блоге на wordpress. Он не работает, и я не знаю, как его решить, и, эй, для этого и нужен StackOverflow, верно?

Во-первых, сообщение об ошибке:

Error: element.dispatchEvent is not a function
Source File: http://.../wp-includes/js/prototype.js?ver=1.6
Line: 3936

Это происходит при загрузке страницы. Обработчик загрузки моей страницы зарегистрирован таким образом:

Event.observe(window, 'load', show_dates_as_local_time);

Ошибка исчезнет, ​​если я отключу некоторые другие плагины, и это (плюс поиск в Google) привело меня к выводу, что это конфликт между прототипом и jQuery (который используется некоторыми другими плагинами).

Во-вторых, я следую рекомендованной WordPress практике использования wp_enqeue_script, чтобы добавить зависимость от моего JavaScript к библиотеку прототипов, как показано ниже:

add_action( 'wp_print_scripts', 'depo_theme_add_javascript' );

function depo_theme_add_javascript() {
    wp_enqueue_script('friendly_dates', 'javascript/friendly_dates.js', array('prototype'));
}

Теперь я также знаю, что есть некоторые потенциальные конфликты между jQuery и Prototype, которые разрешаются с помощью метода jQuery noConflicts. Я пробовал звонить из разных мест, но безуспешно. Я не думаю, что это проблема, потому что а) функция noConflict относится исключительно к переменной $, которая здесь не кажется проблемой, и б) я бы ожидал < / em> wordpress, чтобы разобраться в этом для меня, потому что он может ...

Наконец, используя отладчик Venkman, я определил, что element, указанный в сообщении об ошибке, действительно является HTMLDocument, но ему также не хватает dispatchEvent. Не знаете, как это могло произойти, если это стандартный метод DOM?


person Alastair    schedule 06.01.2009    source источник


Ответы (4)


Во многих библиотеках есть неприятный трюк, который мне очень нравится, и похоже, что прототип - один из них.

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

Точно так же я столкнулся со странным поведением, когда присутствовали mootools и jQuery, обычно jQuery умирает, потому что он вызывал какой-то метод объекта, который каким-то образом был перегружен / обезьяна исправлен Mootools.

Кроме того, загадочным образом исключение mootools из списка использования скриптов привело к тому, что все работало намного быстрее, что, как я пришел к выводу, было связано с меньшим загрязнением объектов.

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

Я рекомендую вам рассматривать миграцию как минимум как один из возможных вариантов.

Еще кое-что, когда пишете:

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

Код времени выполнения Ожидает document.ready перед выполнением:

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

Плагины jQuery

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

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

По сути, это позволит им убедиться, что их код не делает ничего действительно волшебного.

person Kent Fredric    schedule 06.01.2009
comment
Спасибо, да, это выглядит все более и более вероятным. Конечно, jQuery несколько пугает кого-то вроде меня, который ничего не знает о JavaScript ... Но это, вероятно, проще, чем решить эту конкретную проблему! - person Alastair; 06.01.2009

Стоит прочитать эту статью на сайте JQuery об использовании JQuery с другими библиотеками. Он имеет дело не только с параметром noConflict.

person Soviut    schedule 06.01.2009

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

jQuery.noConflict();

Но опять же, думаю, нет смысла загружать более 15-20кб для каждой библиотеки :)

person Ionuț Staicu    schedule 06.01.2009

Спасибо всем за предложения. В конце концов, я думаю, что объяснение Кента было наиболее близким, которое в основном сводилось к «Прототип сломан». (Извините, если я вас неправильно резюмирую :)

Что касается опции jQuery.noConflict - я уже упоминал об этом в вопросе. Имеет значение, когда вы запускаете этот метод, и у меня очень мало контроля над этим. Как я уже сказал, я пробовал запускать его в нескольких разных местах (в частности, в заголовке страницы, а также в моем файле сценария), но безрезультатно. Итак, как бы мы все ни хотели, «просто используйте noConflict» не ответ на этот вопрос, по крайней мере, без дополнительной информации.

Кроме того, jQuery.noConflict кажется о переменной $, а код вокруг точки ошибки вообще не имеет отношения к этой переменной. Конечно, они могли иметь косвенное отношение, я этого не отследил.

По сути, я переписал сценарий, используя jQuery вместо Prototype, что на самом деле имело свои проблемы. В любом случае я опубликовал всю историю войны в моем блоге, если вам интересно.

person Alastair    schedule 11.01.2009