Thomas Maier | Magento & WordPress Develover post@webzunft.de | +49 162 9313 708

Antworten auf die Fragen – nicht nur meiner Kunden 

RSS
Home Magento Magento für Entwickler WordPress Navigation für Touchpads

WordPress Navigation für Touchpads

Auf http://www.wort-suchen.de stand ich neulich vor dem Problem, den für die Hauptnavigation automatisch generierten Quellcode fit für Touchpads und Touchscreens zu machen. Navigationen in WordPress haben aber das Problem, dass die Hauptpunkte gleichzeitig Links sind und daher ein Klick bzw. eine Berührung dieser die Unterpunkte standardmäßig nicht nur einblenden, sondern gleichzeitig die hinter dem Link liegende Seite geöffnet wird.

Verhalten des Links unterdrücken

Auf einem normalen Desktopcomputer bewegt man die Maus über ein Element und löst damit den mouseover Event aus. Bei einem Klick löst sich der click Event aus. Touchpads interpretieren jedoch die „Berührung“ eines Links als beide Ereignisse zur gleichen Zeit. Genau um dieses Wissen herum habe ich schließlich die Lösung gebaut.

Zunächst musste ich verhindern, dass der Link ausgelöst wird. Das lässt sich recht einfach mit folgendem Snippet umsetzen:

$('ul#menu-hauptmenu > li > a').click(function(e) {
    e.preventDefault();
)};

Hier wird das Standardverhalten bei einem Klick auf einen Link der obersten Ebene in der Navigation unterdrückt.

Jetzt öffnet sich auch auf Touchpads der Link nicht mehr, wenn man darauf klickt. Stattdessen öffnet sich die Unternavigation und ist auch bedienbar.

In meinem Fall war es jedoch notwendig, dass der Link auf Desktop-Geräten immer bzw. auf Touchpads beim zweiten Berühren funktioniert. Ich erlaube daher das Verfolgen des Links, wenn dieser eine bestimmte Klasse hat. Diese wird ihm durch den mouseover Event zugewiesen. Oder anders: Wenn der Nutzer mit der Maus über den Link fährt, dann erhält dieser die Klasse „clickable“. In der zweiten Funktion wird überprüft, ob der Link diese Klasse hat und wenn ja, wird er verfolgt, ansonsten wird das Verhalten wie oben beschrieben unterdrückt.

    $('ul#menu-hauptmenu > li > a').mouseover(function(e) {
        $(this).addClass("clickable");
    });
 
    $('ul#menu-hauptmenu > li > a').click(function(e) {
        if( $(this).siblings('.sub-menu').length > 0 ) {
            if ( $(this).hasClass('clickable') ) {
            } else {
                e.preventDefault();
            }                
        } 
    });

Beim click Event ist noch zu sehen, dass der Test nur angewendet wird, wenn es ein Untermenü gibt. Wenn der Top-Level-Link keine Untermenüs hat, kann ihm ja auch direkt gefolgt werden.

Timeout auf dem Touchpad

Für den Nutzer hat sich durch den Quellcode oben noch nichts geändert. Der Link wird sowohl auf Desktop-Geräten als auch auf Touchpads verfolgt. Im letzten Fall liegt das wie oben beschrieben daran, dass mouseover mit der Zuweisung der Klasse und click Event mit dem Test gleichzeitig aufgerufen werden, zuerst der mouseover, dann der click. Die Reihenfolge soll auf manchen Geräten andersherum sein, aber soweit konnte ich das nicht testen.

Der Ansatz, dieses Problem zu lösen ist, die Klasse zeitversetzt zuzuweisen. Das sieht dann so aus:

    $('ul#menu-hauptmenu > li > a').mouseover(function(e) {
        $(this).delay(5).queue(function(next){
            $(this).addClass("clickable");
            next();
        });
    });

Hier erfolgt die Zuweisung der Klasse mit einer Zeitverzögerung von 5 Millisekunden. Das ist ausreichend dafür, dass die Zuweisung erst nach dem Test erfolgt und so auf Touchpads der erste Klick das Untermenü öffnet und die Klasse zuweist und der zweite Klick dann erst den Link ausführt. Auf der anderen Seite sollte auf Desktop-Geräten der Abstand zwischen mouseover und click damit auch nicht zu groß sein. Ich habe es zumindest in meinen Tests nicht geschafft, auf einen Link zu klicken bevor die Klasse zugewiesen wurde.
Zu unserem Glück fehlt noch eine Anweisung, die ich hier nicht extra aufführe, die sich aber im gesamten Quellcode befindet, der hier gleich abgebildet wird. Aktuell bleibt nämlich die Klasse nach dem mouseover zugewiesen, wodurch ein Link, der einmal ein Untermenü geöffnet hat, immer verfolgt wird. Wenn ich jetzt als Nutzer aber erstmal schauen möchte, welche Untermenüs es gibt und alle öffnet und dann später nochmal ein vorheriges öffnen möchte, ist der Link weiterhin aktiv. Hier nutze ich den mouseout-Event, um die entsprechende Klasse wieder zu schließen.

Hier also der gesamte Quellcode. Für die Übernahme für eine Standardnavigation von WordPress sollte es reichen, wenn ihr die ID des Menüs anpasst. Im Gegensatz zu den Beispielen oben habe ich hier auch alle meine Kommentare dringelassen, so dass euch das Refactoring einfacher fällt.

    // mark main link as clickable after 5 milli seconds, so after the click event was triggered
    $('ul#menu-hauptmenu > li > a').mouseover(function(e) {
        $(this).delay(5).queue(function(next){
            $(this).addClass("clickable");
            next();
        });
    });
 
    // remove menu mark if user clicks on another main link
    $('ul#menu-hauptmenu > li > a').mouseout(function(e) {
        $(this).removeClass("clickable");
    });
 
    // don't open links when has submenu and had no mouseover before
    $('ul#menu-hauptmenu > li > a').click(function(e) {
        // apply only on links without subnavigation
        if( $(this).siblings('.sub-menu').length > 0 ) {
            if ( $(this).hasClass('clickable') ) {
                // nothing, just follow the link
            } else {
                // don't open the link'
                e.preventDefault();
            }                
        } 
    });

Live seht ihr das Ganze auf http://www.wort-suchen.de

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.