Animierte TYPO3-Menüs mit JavaScript und CSS: jQuery trifft TMENU
Es ist nicht ungewöhnlich, dass Freelancer oder Agenturen von ihren Kunden mit konkreten Referenz-Websites konfrontiert werden, die mitunter rein auf Flash basieren. Eine sinnvolle Reaktion: Auf Webstandards wie HTML & CSS setzen und den
Einsatz von Flash so gering wie möglich halten – erst recht beim Thema Navigation und im Hinblick auf
Suchmaschinenfreundlichkeit und Barrierefreiheit.
„On Top“ kann JavaScript die gewünschten Interaktionen im Menü ausführen und die User Experience steigern. Das JavaScript-Framework jQuery bietet hierfür von Haus aus einen reichen Schatz an Effekten und lässt sich bei Bedarf durch zahlreiche Plugins erweitern.
Valides HTML
Grundlage für die hier vorgestellte Navigation ist eine ungeordnete Liste, die durch TYPO3 generiert wird (Details siehe Listing 5). Die gekürzte Form der HTML-Ausgabe ist im Listing 1 zu sehen, jeder Listenpunkt bekommt hier eine eindeutige ID zugeordnet. Auch die Submenü-Listenpunkte werden mit fortlaufenden IDs versehen. Fährt der Besucher mit der Maus über einen Hauptmenüpunkt, wird das jeweilige Untermenü eingeblendet.
<ul class="nav clearfix"> <li class="current" id="home"> <a href="#" title="Dogtronic. Ferntrainer"><span class="nav-inner">Dogtronic.</span></a> </li> ... <li id="products"> <a href="#" title="25 Produkte">span class="nav-inner"><span>25 </span>Produkte</span></a> <ul class="subnav"> <li id="produkteItem1"> <a href="#" title="Dogtronic MT 300 Mini">Für <br />Familienhunde <span>Dogtronic MT 300 Mini </span><a> </li> <li id="produkteItem2"> <a href="#" title="Dogtronic MT 500 Eco">Für <br />Familienhunde <span>Dogtronic MT 500 Eco </span></a> </li> <li id="produkteItem3"> <a href="#" title="Dogtronic MT 500-w">Für <br />Familienhunde <span>Dogtronic MT 500-w </span></a> </li> ... </ul> </li> ... </ul>
Listing 1
Grundfunktionalität mit CSS
Das CSS wird nach dem Vorbild von „Suckerfish Dropdowns“ [1] aufgebaut: Vorhandene Untermenüs sind bereits im Markup enthalten und werden bei Mousover eingeblendet.
.nav {width: 440px; position: absolute; top: 40px; left: 0; z-index: 99} .nav li {float: left; height: 110px; width: 110px; background-color: #444;} .nav li:hover ul {left: auto} ... .nav .nav-inner {position: absolute; left: 5px; bottom: 5px; width: 90px} .nav a {border: 5px solid #fff; color: #fff; display: block; height: 90px; padding: 5px; text-decoration: none; position: relative;} ... .subnav {position: absolute; font-size: 12px !important; left:-9999px; width: 380px; z-index:100} .subnav li {float: left} .subnav a {position: relative; height: 75px; padding: 20px 5px 5px} ...
Listing 2
Im Untermenü wurde den Buttons per CSS ein leichter Verlauf spendiert. Browser, die das nicht unterstützen, zeigen die normale Farbe an. Allerdings unterstützt selbst der Internet Explorer einen einfachen Verlauf. Leider ist für Mozilla-Browser und Webkit-Browser eine unterschiedliche Syntax nötig. Ein umfangreiches Tutorial zu CSS3-Verläufen findet sich im Blog der Marit AG [2].
#produkte li { background-color: #999; /* Fallback Farbe */ background-image: -moz-linear-gradient(top,#999999,#b2b2b2); background-image: -webkit-gradient(linear,left top, left bottom,from(#999999),to(#b2b2b2)); /* IE filter */ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#999999', endColorstr='#b2b2b2'); /* IE8 filter */ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr='#999999', endColorstr='#b2b2b2')';}
Listing 3
Im Untermenü von „Produkte“ wird die erste Zeile des Textes immer in einer bestimmten Farbe angezeigt, dies erreicht man über den Pseudo-Selektor „:first-line“.
Diese eher unbekannte CSS-Eigenschaft ist bereits seit CSS1 in allen Browsern implementiert.
#produkte .subnav a:first-line {color: #ccc;}
Listing 4
Umsetzung in TYPO3
In TypoScript wird hier für die Generierung der Navigation die TMENU-Funktion des HMENU genutzt. Ziel ist eine valide, verschachtelte, ungeordnete Navigationsliste. Für die Generierung der Listenpunkte werden zwei zusätzliche Register eingebunden, die in den Untermenüs zum Tragen kommen. Zum einen wird der „parentTitle“ aus dem Feld „nav_title“ der Hauptmenüpunkte im Register gespeichert. Zum anderen werden die Menüpunkte über die Register L2N sowie L3N durchgezählt.
Diese spezielle Vorgehensweise kann man im TYPO3-Kochbuch zum Thema „Menü und Titel mit hierarchischer Nummerierung“ nachlesen [3]. Diese beiden Register werden zusammengesetzt in den Untermenüs als individuelle IDs ausgegeben.
Für die Hauptmenüpunkte wurde ein zusätzlicher Span-Wrap benötigt, da der Text innerhalb der verlinkten Listenpunkte unterschiedlich (absolut) positioniert werden sollte.
lib.navigation = HMENU lib.navigation { 1 = TMENU 1 { wrap = <ul class="nav clearfix">|</ul> ... NO { after.cObject = LOAD_REGISTER after.cObject { parentTitle.cObject = TEXT parentTitle.cObject.field = nav_title } stdWrap.prepend = COA stdWrap.prepend { 10 = LOAD_REGISTER 10 { tempN.data = register:L2N tempN.wrap = |+1 L2N.data = register:tempN L2N.prioriCalc = 1 L3N = 0 } } wrapItemAndSub = <li id="{field:nav_title}">|</li> wrapItemAndSub.insertData = 1 ... } ... } 2 < .1 2.wrap = <ul class="subnav">|</ul> 2.NO.stdWrap.prepend { 10 { tempN.data = register:L3N L2N > L3N.data = register:tempN L3N.prioriCalc = 1 } } 2.NO.wrapItemAndSub = <li id="{register:parentTitle}Item{register:L3N}">|</li> ... }
Listing 5
jQuery – das JavaScript-Zusatzmittel
Das Menü funktioniert jetzt schon, wie geplant, nur mit Hilfe von CSS. Mit jQuery kann man nun noch ein wenig Bewegung hinzufügen. Die jeweiligen Untermenüpunkte sollen sanft ein- und ausgeblendet werden, wenn die Maus die Navigation verlässt.
Auf Unterseiten wird nicht das komplette Hauptmenü eingeblendet, sondern nur der Home-Button und der aktive Menüpunkt – selbst das wird schon per CSS geregelt. Über JavaScript wird allerdings beim Überfahren des Home-Buttons das komplette Hauptmenü eingeblendet. So kann man bequem von jeder Unterseite auf andere Seiten navigieren.
... var _animateIn = function() { _count = 0; var _subNav = $('ul', $(this)); if (_subNav.css('display') == 'block') { _subNav.stop().css('opacity', 1); return; } _lis = $('li', _subNav); _subNav.show().css('left', 'auto'); _lis.hide(); //fuer alle Browser ausser IE if (!$.browser.msie) { _active = window.setInterval(_fadeTileIn, 30); return; } //fuer den lahmen IE _lis.fadeIn('fast'); }; var _animateOut = function() { var _subNav = $('ul', $(this)); _subNav.fadeOut('fast'); window.setTimeout(function() { _subNav.css('left', ''); }, 300); }; this.animateOpacity = function() { $('.subnav').hide(); $('.nav > li').hover(_animateIn, _animateOut); }; ...
Listing 6
Darüber hinaus hat jQuery noch weitere Aufgaben auf der Startseite. Klickt man auf ein Produkt im Submenü „Produkte“, wird ein Infoblock mit Produktbild eingeblendet. Über den Teaser bekommt der Besucher erste Produktinformationen und kann bei Bedarf weitere Informationen abrufen. Ist JavaScript deaktiviert, wird er sofort auf die Detailseite geleitet. Findet keine Interaktion statt, werden die versteckten Teaser abwechselnd eingeblendet. Die Mouseover-Funktion stoppt die Animation.
Die hier abgebildeten Code-Listings sind teilweise stark gekürzt. Die kompletten Lisitngs kann man auf t3n.de/magazin herunterladen, indem man dort den am Ende des Artikels abgedruckten Softlink eingibt.
Fazit
Mit JavaScript können Entwickler sehr viele Animationen, die bisher mit Flash gemacht wurden, mindestens genauso gut umsetzen. Durch jQuery als performantes Framework und die vielen fertigen Funktionen lassen sich schnell beeindruckende Ergebnisse erzielen. Grundsätzlich sollte man aber immer bedenken, dass die Website auch ohne JavaScript noch intuitiv funktionieren sollte – gerade im Hinblick auf Suchmaschinenoptimierung und Barrierefreiheit.