
Coraz więcej różnorodnych stron internetowych korzysta z techniki która w szeroki sposób pozwoliła rozwinąć się przede wszystkim JavaScriptowi – z Ajaxa. Podobnie jest z różnorodnymi wtyczkami do systemu blogów WordPress. Z reguły korzystają one jednak z jakiejś biblioteki JavaScript zbierającej w całość jego najważniejsze funkcje i pozwalającej na ich prostsze użycie. W momencie jednak, kiedy w naszych pluginach pojawi się w użyciu kilka wtyczek możemy napotkać problem kolizji ich współdziałania.
Prolog!
Zanim zacznę muszę wspomnieć, że kolizja opisywana poniżej może występować na jakiejkolwiek stronie, a opisywana przeze mnie sytuacja jest tylko przykładem. Nie mniej jednak mankament ten postaram się wytłumaczyć na podstawie jednoczesnego działania AJAX Comments i przystosowanej do personalnych potrzeb modyfikacji zakładek (przykładem są te umieszczone z lewej strony tego wpisu). Pierwsza wtyczka domyślnie używa Script.Aculo.Us, a co za tym idzie także frameworku Prototype. W drugim wypadku oprę się o kurs tworzenia zakładek w WP palmiaka, który używa za to jQuery.
Po poprawnej instalacji obydwu modyfikacji pewnie spora część z Was nie dostrzeże dręczącego nas feleru. Dlaczego? Gdyż na stronie głównej wszystko będzie działało prawidłowo, ale bynajmniej nie na podstronach w których będzie możliwe komentowanie wpisów. Dla przykładu w momencie wczytania najpierw prototype.js i scriptaculous.js, a później jquery.js stworzone przez nas zakładki nie będą poprawnie działać (nie zostaną one ukryte i nie będzie możliwości przejścia pomiędzy nimi). Dlaczego tak się dzieje? Tutaj należałoby poruszyć pewną sprawę dotyczącą samego działania frameworków tego typu.
Funkcja $(argumenty)
Między innymi do tworzenia obiektu danej biblioteki używa się funkcji $(argumenty);. Dzięki temu operujące np. na obiektach DOM, czy tablicach frameworki dzięki tej specjalnej konstrukcji pozwalają użytkownikowi na wykorzystywanie ich konkretnych funkcji.

Problematyka korzystania z więcej niż jednej biblioteki naraz…
W momencie kiedy w skrypcie korzystamy z dwóch lub większej ilości frameworków może nastąpić kolizja w ich działaniu. W uproszczeniu przez użycie $(); w każdej z nich. I tak to w naszym przykładzie funkcje, czy odwołania do obiektów które powinny być wykonane za pomocą jQuery zostaną wykonane przez pierwszą wczytaną klasę. A wszystko przez to, że każda z podanych bibliotek odwołuje się do danego elementu w taki sam sposób.
Solucja!
Na szczęście od wersji 1.1.4 z pomocą przychodzą nam developerzy jQuery wraz z funkcją pozwalającą na interoperacyjność – jQuery.noConflict(param);.
jQuery.noConflict(); // zwraca kontrolę nad $ bibliotece domyślnej (wcześniej używanej)
jQuery.noConflict(true); // zwraca kontrolę nad $ i jQuery (którego $ jest aliasem) oryginalnemu właścicielowi - należy używać z ostrożnością!
Co należy wiedzieć w kwestii używania tego to przede wszystkim fakt, że wymaga się, aby powyższą funkcję wywołać przed użyciem elementów innych bibliotek, a także jQuery powinno być wczytywane po pozostałych frameworkach. W konkretnym wypadku związanym z WP który opisujemy należy także domyślnie dostarczone niżej wymienione biblioteki uaktualnić. Niestety w opisywanych tutaj wtyczkach i systemie blogów są to wersje starsze i przedstawiony trick w tym artykule nie zadziała dopóki nie ściągniemy zaktualizowanych wersji frameworków.
<script type="text/javascript" src="libs/prototype.js" />
<script type="text/javascript" src="libs/scriptaculous.js" />
<script type="text/javascript" src="libs/jquery.js" />
Domyślnie także należy używać w tym trybie jQuery zamiast $.
jQuery.noConflict();
jQuery("p").hide(); // użycie frameworka jQuery
$("div").style.display = 'none'; // użycie innego frameworka, np. prototype
Ponieważ oczywiście zaprezentowana funkcja jest podatna na przypisywanie do zmiennych to niekoniecznie musimy używać standardowej, dłuższej nazwy. Negatywem tego rozwiązania jest jednak potencjalny konflikt nazw w przypadku pisania aplikacji internetowej przez wielu programistów.
var q = jQuery.noConflict();
q("p").hide();
$("div").style.display = 'none';
Ostatecznie moglibyście także spytać “co zrobić, aby móc wewnątrz bloku kodu używać $ dla jQuery?”. Wystarczy poprzedzić zadaną funkcję przez jQuery, bądź zakończyć poprzez (jQuery).
jQuery(function($) { [...] }); // wersja pierwsza
(function($) { [...] })(jQuery); // wersja druga
Niestety w takim wypadku wewnątrz powyższych bloków kodu nie ma możliwości odniesienia się do obiektów innych bibliotek.
Przykład pozwalający na prawidłowe działanie wspomnianych zakładek…
Poprawiony przykład z vivee, który należy użyć w wypadku w.w. konfliktu (kod JavaScript).
jQuery.noConflict();
function tabs(id) {
jQuery("#"+id+" h2:first a").addClass("active");
jQuery("#"+id+" div").not(":first").hide();
jQuery("#"+id+" h2 a").click(function() {
var licznik = jQuery("#"+id+" h2 *").index(this);
jQuery("#"+id+" h2 a").removeClass("active");
jQuery(this).addClass("active");
jQuery("#"+id+" div:visible").hide();
jQuery("#"+id+" div").eq(licznik).show();
return false;
});
}
jQuery(document).ready(function(){
tabs("zakladki");
});
Epilog…
WPNinja na swoim blogu poświęconym WordPressowi prawidłowo stwierdził w stosunku do mojej osoby, że mieszanie bibliotek nie jest dobrym zwyczajem.
"@m1chu,
Mieszanie ze sobą bibliotek to masakra. Nie dość, że zajmuje to niemiłosiernie dużo miejsca to, jak zauważyłeś w swoim artykule, może powodować konflikty."
Opisany przeze mnie artykuł powinien być stosowany tylko w wyjątkowych sytuacjach. Należy z reguły unikać użytkowania kilku frameworków naraz, bo to obciąża w znacznym stopniu skrypt poprzez ich wagę, a co za tym idzie ilością danych do załadowania. Zdaję sobie jednak sprawę, że niekiedy jest to niezmiernie trudne (czego jak na razie w fazie rozwojowej przykładem jest mój blog ;]). Podziękowania za przypomnienie dla WPNinja’y o tym, że zapomniałem tak ważnego faktu umieścić w swoich wpisie.
Zapraszam do zapoznania się także z powiązanymi artykułami:
Wpis ten został opublikowany dnia:
czwartek, 2 Październik 2008 o godzinie 12:45
w działach JavaScript, Prototype, Webhosting, WordPress, jQuery.
Możesz śledzić rozwój tematu, w tym odpowiedzi dla tego artykułu poprzez kanał informacyjny RSS 2.0.
Możesz także zostawić swój komentarz lub trackbackować ze swojej własnej strony.
[...] Kolizje współdziałania bibliotek JavaScript na podstawie wtyczek WordPress… (02.10.2008) [...]
A jak sprawdzić co działa z którego js?a? Bo w tej chwili jak przeglądam informację przygotowywanego przez mnie szablonu to takie JS mi się ładują.
Skrypt (11) 264,65 KB
http://www.transblog.xt.pl/wp-includes/js/prototype.js?ver=1.6 121,23 KB
http://www.transblog.xt.pl/wp-includes/js/scriptaculous/wp-scriptaculous.js?ver=1.8.0 2,56 KB
http://www.transblog.xt.pl/wp-includes/js/scriptaculous/effects.js?ver=1.8.0 38,07 KB
http://www.transblog.xt.pl/wp-includes/js/jquery/jquery.js?ver=1.3.2 55,93 KB
http://www.transblog.xt.pl/wp-includes/js/swfobject.js?ver=2.1 9,53 KB
Tu bym chciał pozbyć się prototype, bo jak widać zajmuje 1/2 wszystkich js. Tylko muszę najlpier sprawdzić jakie pluginy na nim działją. A niestety niewiem jak to zrobić
http://www.transblog.xt.pl/wp-content/plugins/wordtube/javascript/statistic.js?ver=0.1 1,21 KB
http://www.transblog.xt.pl/wp-content/plugins/flash-video-player/swfobject.js 8,46 KB
http://www.transblog.xt.pl/wp-content/plugins/lightbox-2/lightbox.js?ver=1.8 20,84 KB
Tu z pluginami nie mam kłopotu, za jakiś czas jak wszystkie filmiki z flash-video-player przeniosę do wordtube to zniknie jeden. Ew jak ktoś zna sposób jak wykonać lightboxa tylko wykorzystują jQuery to będę wdzięczny
http://www.transblog.xt.pl/wp-content/themes/panorama/scripts/tabber-minimized.js 4,79 KB
http://www.transblog.xt.pl/wp-content/themes/panorama/scripts/utils.js 123 bajtów
http://www.transblog.xt.pl/wp-content/themes/panorama/scripts/horizmenu.js?ver=2.8.2 1,91 KB
Tu za wiele nie zrobię, tab to zakładki na jQ, ultils to niewiem, a hirizonam odpowiada za zmienne wyświetlanie grafik w topie.
Przykładowy lightbox, jQuery: http://utnij.eu/ea7f82/
[...] bibliotek JavaScript na podstawie wtyczek WordPress… | m1chu.eu – another devblog m1chu.eu/…ania-bibliotek-javascript… Pokaż reakcje /* */ inne strony z tej witryny + obserwuj co [...]