Joomla@jogger.pl

 

24

września

2010

Gdy MooTools powoduje problemy

Ponieważ mam możliwość obserwowania ogromnej ilości stron bazujących na Joomla! wiem, że od czasu wprowadzenia do tego CMS-a nowej wersji MooTools 1.2.* często pojawia się problem kompatybilności.

Niektórzy developerzy już dostosowali swoje produkty do MooTools 1.2.*, inni nie. Ja osobiście w nowych wersjach modułów planowałem dodanie w opcjach parametru wyboru wersji MooTools używanej w module.

Jednak po dokładnej analizie doszedłem do wniosku, że nie jest to idealne rozwiązanie. Czasem zdarza się, że jakiś komponent na stronie gdzie normalnie używa się MooTools 1.1 "na siłę" dołącza nowszą wersję MooTools i wtedy problem mamy gotowy.

Dlatego postanowiłem skorzystać w tej sytuacji z dobrodziejstw istnienia obiektu MooTools, który przechowuje informacje o wersji frameworka. Wystarczy stworzyć dwa skrypty: jeden dla MooTools 1.1 a drugi dla wersji 1.2 i następnie w głównym skrypcie naszego szablonu/modułu dodać następujący kod:

window.addEvent('load', function() {
        if(MooTools.version.contains('1.1')){
                new Asset.javascript('moo11.js');
        } else {
                new Asset.javascript('moo12.js');
        }
});

Należy pamiętać o tym, że skrypty w plikach moo11.js i moo12.js powinny być tak napisane by wykonywały się od razu (czyli już bez dodawania funkcji obsługi zdarzenia onLoad).

Oczywiście zamiast zdarzenia load możemy wykorzystać zdarzenie domready, ale to już zależy od tego co dokładnie robi skrypt, bo w niektórych wypadkach domready nie spełni naszych oczekiwań.

 
 

25

lutego

2010

DomReady i MooTools 1.11

Joomla! 1.5 oraz większość jej rozszerzeń w skryptach JavaScript korzysta z MooTools 1.11, które jak już kiedyś wspominałem ma czasem problem z obsługą zdarzenia DomReady w przeglądarkach IE.

Jeżeli nie chcemy oglądać błędów postaci:

Wiadomość: HTML Parsing Error: 
Unable to modify the parent container element before the 
child element is closed (KB927917)
Wiersz: 0
Znak: 0
Kod: 0

To proponuję dodać poniższy fragment kodu na końcu pliku mootools.js z katalogu media:

Element.Events.domready = {
        add: function(fn){
                if (window.loaded){
                        fn.call(this);
                        return;
                }
                var domReady = function(){
                        if (window.loaded) return;
                        window.loaded = true;
                        window.timer = $clear(window.timer);
                        this.fireEvent('domready');
                }.bind(this);
                if (document.readyState && window.webkit){
                        window.timer = function(){
                                if (['loaded','complete'].contains(document.readyState)) domReady();
                        }.periodical(50);
                } else {
                        window.addListener("load", domReady);
                        document.addListener("DOMContentLoaded", domReady);
                }
        }
};

Zamiast szukać wszystkich skryptów z linijką:

window.addEvent("domready", function(){

I zamieniać jej na:

window.addEvent("load", function(){

To rozwiązanie ma ten plus, że w normalnych przeglądarkach (innych niż IE) zdarzenie domready będzie cały czas działało jako domready, a tylko w IE zostanie od razu zamienione na zdarzenie load.

 
 

Miniblog