Docked Navigation: Unterschied zwischen den Versionen
Aus Contao Community Documentation
(5 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 17: | Zeile 17: | ||
<body> | <body> | ||
<div id="navi"></div> | <div id="navi"></div> | ||
− | <div id= | + | <div id="dienste"></div> |
− | <div id= | + | <div id="arbeiten"></div> |
− | <div id= | + | <div id="profil"></div> |
</body> | </body> | ||
</source> | </source> | ||
Das ganze kann noch verpackt sein und weitere Elemente davor und dahinter enthalten, das ist irrelevant. Wichtig ist, dass die Navigation und die anszusprechenden Bereiche eine eindeutige ID oder Klasse haben. | Das ganze kann noch verpackt sein und weitere Elemente davor und dahinter enthalten, das ist irrelevant. Wichtig ist, dass die Navigation und die anszusprechenden Bereiche eine eindeutige ID oder Klasse haben. | ||
− | |||
== Die Navigation == | == Die Navigation == | ||
Zeile 61: | Zeile 60: | ||
<source lang="css"> | <source lang="css"> | ||
− | .scrolled { | + | #navi.scrolled { |
position:fixed; | position:fixed; | ||
top:0; | top:0; | ||
Zeile 86: | Zeile 85: | ||
//nun soll alles weitere passieren, sobald man scrolled, also ein neues Event hinzufügen | //nun soll alles weitere passieren, sobald man scrolled, also ein neues Event hinzufügen | ||
− | + | window.addEvent('scroll',function(){ | |
− | + | ||
− | + | //den aktuellen Scrollstatus fragt man hiermit ab | |
− | + | var scroll = this.getScroll(); | |
− | + | ||
− | + | //jetzt der abgleich fensterposition mit navigationsposition | |
− | + | if(scroll.y > navicoords.top) | |
− | + | { | |
− | + | //und nun der Navigation die Klasse scrolled geben | |
− | + | navi.addClass('scrolled'); | |
− | + | }else | |
− | + | { | |
− | + | //die klasse scrolled wieder entfernen | |
− | + | navi.removeClass('scrolled'); | |
− | + | }; | |
− | + | ||
− | + | }); | |
− | |||
//damit bei einem klick auf einen Navigationslink sanft gescrollt wird | //damit bei einem klick auf einen Navigationslink sanft gescrollt wird | ||
Zeile 115: | Zeile 113: | ||
x: 0, | x: 0, | ||
y: -navicoords.height | y: -navicoords.height | ||
− | } | + | } |
+ | }); | ||
Zeile 121: | Zeile 120: | ||
</source> | </source> | ||
+ | So sollte das schon funktionieren. Allerdings ergibt sich nun folgendes Problem: | ||
+ | Sobald die navi die Klasse scrolled erhält und auf Position:fixed steht, wird sie aus dem normalen HTML Fluss gerissen. Das macht sich dann dadurch bemerkbar, dass der nachstehende Inhalt nach oben springt, und zwar soweit, wie die Navi vorher hoch war. Das beheben wir einfach, indem wir dem nächsten relativen Element einfach ein margin-top verpassen. In unserem Beispiel ist das das dienste div. | ||
+ | |||
+ | <source lang="javascript"> | ||
+ | dienste.set('style','margin-top:'+navicoords.height+'px'); | ||
+ | </source> | ||
+ | |||
+ | Das kommt dann gleich hinter der Klassenvergabe. Und wenn man wieder in den Normalzustand springt, muss der Margin wieder weg. | ||
+ | |||
+ | <source lang="javascript"> | ||
+ | dienste.set('style','margin-top:0'); | ||
+ | </source> | ||
Das war die ganze Hexerei mit der Positionierung. Demnächst folgt dann darauf aufbauend die Beschreibung, wie man die Links in der Navigation auf aktiv schaltet, wenn man sich in dem jeweiligen Bereich befindet. | Das war die ganze Hexerei mit der Positionierung. Demnächst folgt dann darauf aufbauend die Beschreibung, wie man die Links in der Navigation auf aktiv schaltet, wenn man sich in dem jeweiligen Bereich befindet. |
Aktuelle Version vom 30. September 2012, 13:12 Uhr
Inhaltsverzeichnis
Einleitung
In diesem Tutorial möchte ich beschreiben, wie man eine Navigation einrichtet, welche beim scrollen ab einem gewissen Punkt an der oberen Kante des Fensters andockt. bsp.stefanmelz.de
Aufbau des HTML
Das ist eigentlich recht simpel. Man benötigt zu allererst das Grundgerüst. Einmal angenommen, man hat auf der Seite 3 Bereiche, welche man ansteuern möchte.
<body> <div id="navi"></div> <div id="dienste"></div> <div id="arbeiten"></div> <div id="profil"></div> </body>
Das ganze kann noch verpackt sein und weitere Elemente davor und dahinter enthalten, das ist irrelevant. Wichtig ist, dass die Navigation und die anszusprechenden Bereiche eine eindeutige ID oder Klasse haben.
Eine Standard Navigation ist eine einfache unsortierte Liste. Da man auf der Seite bleiben soll, braucht man hier lediglich Anker. Das HTML kommt dann so in das div mit der ID „navi“.
<ul> <li class="dienste"><a href="#top">Dienstleistungen</a></li> <li class="arbeiten"><a href="#arbeiten">Arbeitsbeispiele</a></li> <li class="profil"><a href="#profil">Profil und Kontakt</a></li> </ul>
Die Navigation funktioniert also ohne Javascript schonmal ganz gut und ist so nun einsetzbar.
Das Javascript / CSS
Nun möchte man nicht immer wieder nach oben scrollen um die Navigation benutzen zu können. Diese soll immer am oberen Fensterrand „kleben“ bleiben. Allerdings erst, wenn die Navigation aus dem sichtbaren Bereich verschwinden würde. Dazu benötigt man ein wenig Javascript und CSS.
CSS
Um die Navigation am oberen Fensterrand zu positionieren ist nichts weiter nötig als die CSS Angabe:
position:fixed; top:0;
Der Rest ist stark davon abhängig wie die Navigation aussieht und wo die Seite platziert ist. Soll zum Beispiel die komplette Bildschirmbreite eingenommen werden, fügen wie hinzu:
width:100%;
Dieses CSS wird in die klasse „scrolled“ gepackt. Das sieht dann im Endeffekt so aus:
#navi.scrolled { position:fixed; top:0; width:100%; }
JS
Nun soll die klasse „scrolled“ der Navigation zugewiesen werden, sobald diese aus dem sichtbaren Bereich verschwinden würde. Dazu muss die Position der Navigation ermittelt werden. Mootools hilft da mit der Methode getCoordinates(); Das ganze soll erst starten, wenn das DOM aufgebaut ist. Also in die eingebundene JS Datei folgendes schreiben:
window.addEvent('domready',function(){ //das selektierte Element in eine Variable packen um schreibarbeit und performance zu sparen var navi = $('navi'); //dann die Koordinaten der Navigation abfragen und in eine Variable packen var navicoords = navi.getCoordinates(); //nun soll alles weitere passieren, sobald man scrolled, also ein neues Event hinzufügen window.addEvent('scroll',function(){ //den aktuellen Scrollstatus fragt man hiermit ab var scroll = this.getScroll(); //jetzt der abgleich fensterposition mit navigationsposition if(scroll.y > navicoords.top) { //und nun der Navigation die Klasse scrolled geben navi.addClass('scrolled'); }else { //die klasse scrolled wieder entfernen navi.removeClass('scrolled'); }; }); //damit bei einem klick auf einen Navigationslink sanft gescrollt wird var mySmoothScroll = new Fx.SmoothScroll({ links: 'a', wheelStops: false, // der offset muss so gross sein, wie die navi hoch ist, damit man beim smoothscroll nicht den eigentlichen Bereich mit der Navi ueberdeckt offset: { x: 0, y: -navicoords.height } }); })
So sollte das schon funktionieren. Allerdings ergibt sich nun folgendes Problem: Sobald die navi die Klasse scrolled erhält und auf Position:fixed steht, wird sie aus dem normalen HTML Fluss gerissen. Das macht sich dann dadurch bemerkbar, dass der nachstehende Inhalt nach oben springt, und zwar soweit, wie die Navi vorher hoch war. Das beheben wir einfach, indem wir dem nächsten relativen Element einfach ein margin-top verpassen. In unserem Beispiel ist das das dienste div.
dienste.set('style','margin-top:'+navicoords.height+'px');
Das kommt dann gleich hinter der Klassenvergabe. Und wenn man wieder in den Normalzustand springt, muss der Margin wieder weg.
dienste.set('style','margin-top:0');
Das war die ganze Hexerei mit der Positionierung. Demnächst folgt dann darauf aufbauend die Beschreibung, wie man die Links in der Navigation auf aktiv schaltet, wenn man sich in dem jeweiligen Bereich befindet.
--Stefanmelz 23:15, 10. Sep. 2012 (CEST)