INDEVELOPMENTbeta






Subskrybuj m1chu.eu – another devblog
 
  •  Łukasz: Na stronce http://www.beautifulcode.pl/we bmaster/php/przewodnik-po-zabe zpieczeniach-aplikacji-php/...
  •  m1chu: Gdyby ktoś miał kiedyś problem z nieprawidłową wielkością pobieranego pliku, chociażby w moich, wyżej...
  •  m1chu: Jeżeli chodzi o szybką konwersję z Flash na HTML to szczerze nie wiem. Nigdy nie potrzebowałem żadnej...
  •  m1chu: @Michal: wrzuć linki w jakieś kontenery (listę ul -> li, dl -> dt/dd, czy chociażby w divy). Ustaw ich...
  •  Józek: Wszystko pięknie opisane, ja mam małe pytanko. Od jakiegoś czasu staram się dowiedzieć jak zmienić...
  •  Michal: a co jesli chciałbym umiescic kilka takich linkow obok siebie ?jesli zmienie wartość display na inline...
  •  mano: Co należy zrobić aby podmiane przycisku zastasowac kilka razy na stronie z różnymi grafikami ? Trzeba...

Dołącz do fanów!

Ankieta!

  • Jak oceniasz poziom artykułów? (dokładną opinię umieść w komentarzu)

    View Results

    Loading ... Loading ...




Kolizje współdziałania bibliotek JavaScript na podstawie wtyczek WordPress…


Współdziałanie framework'ów na przykładzie WordPress'a

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.

Różnorodne metody korzystania z elementów strony

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.


6 komentarzy

Dodaj własny komentarz

Możesz użyć następujących tagów XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>