OnePage_XH mit jQuery

Hier der Versuch einer modifizierten Alternative des OnePage_XH - Plugins von cmb. Die Hintergründe und die Diskussion hierzu kann man im CMSimple_XH-Forum nachlesen

Es nutzt jQuery um das "Smooth Scrolling" zu realisieren. Der Grund für den ganzen Aufwand waren Beschwerden über ein Ruckeln in der Scrollfunktion. Auch mit einer neueren Version von onepage.js gab es dann Probleme mit dem mobilen Browser Dolphin bei aktiviertem Jetpack.
Mittels jQuery soll die Funktion jetzt möglichst browserübergreifend zufriedenstellend funktionieren.

Neben dem Umstieg auf jQuery, realisiert in onepage2.js jquery.onepage.js, sind noch andere Dinge hier verändert:

  • Die Links in der Navigation haben eine zusätzliche Klasse "scrollTo" erhalten. Nur Links mit dieser Klasse werden von der Scrolling-Funktion erfasst.
  • Im Edit-Modus wird das Javascript erst überhaupt nicht geladen, da hier die Seite nicht im "Onepage-Modus" läuft. Das spart dann auch die Manipulation an diversen Links etc.
  • Der "ScrollTop" - Link ist nicht mehr klickbar, wenn er ausgeblendet wurde.
  • Die Menüklassen li.doc / li.sdoc werden dynamisch angepasst

Nicht zu realisieren waren Menü-Links ohne vorangestellten Pfad. Dafür hätten zu viele Kleinigkeiten einzeln verbogen werden müssen. Zum Beispiel funktionieren Skripte die Daten per GET- / Post - Request senden dann nicht mehr. Ein Beispiel dafür ist das interne Kontaktformular. Aber auch andere Plugins würden vermutlich größere Probleme verursachen.
Und auch der Logout-Button hinterlässt sonst eine Einbahnstraße als URL...

Weitere Aktualisierungen sind beim jeweiligen Download dokumentiert.

Test interner Link mit scrollTo - Klasse -- und hier ohne.

OnePage-Container

Eine Onepage - "Seite" wird durch das Plugin immer mit einer einfachen Struktur in einem <div> - Container erstellt

<div id="SeitenID" class="onepage_page">
     Seiteninhalt
</div>

Dieser <div> - Container, mit der Seiten-ID und der Klasse "onepage_page" ist Mindestvoraussetzung für die Funktion des Plugins.

Bei Veränderungen dieses Containers funktionieren unter Umständen die mitgelieferten JavaScripte, oder auch die ganze Seite nicht mehr.

Trotzdem ist es in manchen Fällen sinnvoll, die Struktur zu erweitern, oder eine zusätzliche Klasse für den Seitencontainer zu definieren.
Hierfür gibt es im Template die Möglichkeit die auszugebende Struktur, über die globale Variable "$onepage_structure", zu erweitern:

<?php $onepage_structure =
    '<div class="onepage_page_outer">
        <div id="%s" class="onepage_page container">
            <div class="onepage_page_inner">
                %s
            </div>
        </div>
    </div>';
?>

Das erste "%s" wird durch die eindeutige Seiten-ID (je nach Konfiguration die Seitenüberschrift oder eine fortlaufende Zahl) ersetzt, das zweite "%s" ist der Platzhalter für den Seiteninhalt.

"$onepage_structure" muss natürlich vor dem Template-Tag "onepage_content()" definiert werden.

 

Weiches Scrollen

... wird hier mit jQuerys "animate()" realisiert. Die Dauer der Animation wird aus der Plugin-Konfiguration übernommen.
Allerdings ist das Feature nur an Links mit der Klasse ".scrollTo" gebunden.
Der PHP-Teil des Plugins ist so angepasst, dass die Klasse automatisch in der Navigation und im "Top-Link" generiert wird.
Als Scroll-Animation (Easing) ist "linear" momentan fest im Code definiert.

Top-Link

Der Top-Link wird z.B. über das Template-Tag onepage_toplink() erzeugt. Scrollt der User nach unten (derzeit 300px fest eingestellt), wird das Element mit der Id "onepage_toplink" eingeblendet.

Die jQuery-Version nutzt dazu die Funktionen "fadeIn()" und "fadeOut()", anstatt zwei CSS-Klassen wie in der Original-Version. 
Wenn der Link im Edit-Modus stört, kann er im Template per CSS mit "display: none;" ausgeblendet werden.

Besonderheiten

Templates mit fixiertem Header

Da sich das Javascript für das "weiche Scrollen" immer am oberen Ende des Fensters orientiert, stimmen die Scrollpositionen bei oben fix positionierten Elementen nicht mehr.
Hiergegen lässt sich ein benutzerdefiniertes Offset definieren. Je nach Anforderung kann es als feste Pixel-Zahl, oder als Rückgabewert einer Javascript-Funktion direkt im Template realisiert werden.

<script type="text/javascript">
     /* <![CDATA[ */
          var onepage_customOffset = 80;
     /* ]]> */
</script>

Das Skript kann im Template ganz unten, aber vor dem schließenden </body> - Tag,
eingefügt werden.

Das "H1-Problem"

Nur eine H1-Überschrift?

Generell sollte man für ein OnePage-Projekt das CMS auf eine einzige Menüebene konfigurieren:
Einstellungen -> CMS -> Menü -> Ebenen -> 1.
Alle "Seiten" erhalten dann eine einleitende H1-Überschrift, die restlichen Überschriften sind zur Strukturierung der Inhalte verfügbar.

Das Problem dabei:
bis heute hält sich die Regel, dass ein Dokument nur eine einzige H1-Überschrift haben sollte.
Wenn nun im Template, zum Beispiel zur Ausgabe von sitename(), noch keine H1 - Überschrift definiert wird, kann man das leicht mit einem kleinen, gut lesbaren Codeschnipsel ;-) direkt im Template beheben:

Anstatt

<?php echo onepage_content()?>

verwendet man zur Ausgabe der Inhalte im Template

<?php echo
    preg_replace('#<h2(.*?)<\/h2>#', '<h1$1</h1>',
        preg_replace('#<h1(.*?)<\/h1>#', '<h2$1</h2>',
        onepage_content()), 1);
?>

Die erste "OnePage" - Überschrift wird hierdurch mit <h1>...</h1> ausgezeichnet, alle weiteren werden in <h2>...</h2> eingeschlossen.

Muss die erste Inhaltsseite jedoch mit <h2> beginnen, lässt sich das selbe Verfahren analog auch für eine Ebene tiefer anwenden:

<?php echo
    preg_replace('#<h3(.*?)<\/h3>#', '<h2$1</h2>',
        preg_replace('#<h1(.*?)<\/h1>#', '<h3$1</h3>',
        onepage_content()), 1);
?>

Vorteile:

  • Semantisch richtige HTML-Struktur
  • Der im Browser integrierte Lesemodus sollte funktionieren

Nachteile:

  • Bei tieferer Verschachtelung muss der User die richtige Überschrift wählen, was nicht intuitiv ersichtlich ist
  • Die "Gewichtung" der einzelnen Abschnitte fällt mit dem Level der Überschrift und muss nicht unbedingt dem jeweiligen Inhalt entsprechen

Oder HTML5 like?

Mit HTML5 gibt es neue Möglichkeiten zur semantischen Strukturierung der Inhalte. Zum Beispiel lässt sich eine "OnePage-Seite" in ein <article> - Tag verpacken. In jedem dieser "Artikel" sind, entsprechend der Standardausgabe des OnePage-Plugins, <h1> - Überschriften erlaubt.

Auch die vorherige Ausgabe des Seitennamens als H1-Überschrift ist, vielleicht auch verpackt in ein <header> - Tag, zu 100% valide unter HTML5:

<header>
    <a href="#" title="Home">
        <h1><?php echo sitename();?></h1>
    </a>
</header>

Zu Demozwecken nutzt diese Seite ein angepasstes Template nach diesem Ansatz. Der OnePage-Container wurde dazu im Template umdefiniert:

<?php $onepage_structure =
    '<article>
        <div id="%s" class="onepage_page">%s</div>
    </article>'
;?>

Das angepasste Template ist auch im Download enthalten.

Ausgabe im HTML-Validator testen...

Vorteile:

  • Standard-Struktur muss nicht verändert werden
  • Der User kann zur weiteren Strukturierung auf allen "Seiten" gleichmäßig Überschriften ab H2 verwenden
  • Alle "Seiten" haben, aus Sicht des Inhaltes, die gleiche "Gewichtung"

Nachteile:

  • Der Lesemodus der Browser erkennt die (laut Validator valide) Seitenstruktur in der vorliegenden Fassung nicht sauber. Allerdings gibt es (noch) keinen echten Standard für den Lesemodus, was zu unterschiedlichen Ergebnissen bei verschiedenen Browsern führen kann
  • Der IE erkennt die neuen Tags erst ab Version 9. Wer ältere Versionen unterstützen muss, kann dafür html5shiv bemühen.

Mehr Hintergrund-Informationen zu dieser Variante finden sich im Netz zum Beispiel unter "The truth about multiple h1-tags in the html5 era".

Fazit

Welche Variante "richtig" ist, hängt vom Projekt und den Inhalten ab. Bei vielen OnePage-Seiten wird inhaltlich die HTML5-Variante die bessere Wahl sein. Aus SEO-Sicht vermute ich ebenfalls kein Problem. Neben der vielleicht besseren Gewichtung der Inhalte, gibt es aber auch Nachteile: der Lesemodus funktioniert nicht / nicht immer richtig und der Validator warnt z.B. vor Screenreadern, die vielleicht die neue Struktur noch nicht sauber interpretieren können.

Die :hover - Pseudoklasse und Touch-Geräte

... passen nicht zusammen, denn ":hover" gibt es nicht auf Touch-Geräten.
Die Navigation in dieser Demo nutzt aber :hover zur Animation beim Überfahren der Navigations-Links mit der Maus. Auf einem Touchgerät behält solch ein Link nach einem Tap die mittels :hover gestzten Styles. Dasselbe passiert zum Beispiel auch bei einem Button, der ein Formular per Ajax-Request absendet.

Wer auf die Hover-Styles nicht verzichten möchte, muss für Touch-Geräte eine passende Lösung integrieren. Zum Beispiel kann man mit Hilfe von Modernizer die Styles so definieren, dass bei Browsern, die das Touch-Event unterstützen, die :hover - Pseudoklasse nicht zugewiesen wird.
Im Template dieser Demo ist diese Lösung als Beispiel integriert.
Eine 100% - Erkennung von Touch-Geräten ist das allerdings nicht.
Warum, lässt sich hier nachlesen: http://www.stucox.com/blog/you-cant-detect-a-touchscreen/.

Was noch fehlt

Ideen hätte ich noch :)

  • Eine Auswahl, welche JS-Datei der User verwenden möchte
  • Eine Möglichkeit, ein dem Template beigefügtes JS zu laden
  • Eine separate JS-Datei, ausschließlich für den Admin-Mode (z.B.: verstecken der z.Zt. nutzlosen PageData-Tabs usw.)

Download

Das angepasste Plugin gibt es vorerst hier in der jeweils aktuellen Version zum Download.
Bitte nicht vergessen:  jQuery aktivieren und bei updates Browsercache leeren!

2016-04-27

Erste Version


2016-04-29

Änderungen:

  • HTML-Struktur optional per Variable im Template anpassbar
  • Bugfix: Scroll-Funktion springt u.U. an falsche Stelle

2016-05-07

Änderungen:

  • onepage2.js in jquery.onepage.js umbenannt
  • version.nfo entfernt
  • Code aufgeräumt ("use strict") und sauber in eine Funktion gepackt
  • Die Browser Historie wird nun richtig aktualisiert, dadurch funktioniert jetzt auch der Back-Button wie erwartet
  • Die bekannten Klassen (li.doc / li.sdoc) werden nun dynamisch, in Abhängigkeit der Scrollposition und auch beim ersten Seitenaufruf, richtig gesetzt
  • Der jeweils aktive Menü-Link erhält zusätzlich, wie bei vielen anderen Menü-Skripten üblich, die Klasse ".active"
  • Für Templates mit "fixiertem Header" kann ein Offset für die Anpassung der Scrollfunktion definiert werden

2016-05-11

  • "Blitzdingsen" bei ScrollTo, TopLink und aktivem Navigationspunkt behoben
  • Bugfix: Bei Seitenaufruf mit Hash wurden Klassen für Navigationspunkt nicht richtig gesetzt

 2016-05-29

  • Easing auf "linear" anstatt "swing" gestellt
  • Neue Konfigurationsoption: "onepage_updateNavOnScroll"
  • Beispiel-Template zum Download beigefügt

Download


Das hier verwendete Template stammt von lck. Am Template wurden keine Änderungen gemacht wurden zu Demozwecken umfangreiche Erweiterungen eingefügt. In den aktuellen Downloads ist das Template beigefügt.

Kontaktformular

Das Kontaktformular ist nur für Demo-Zwecke aktiviert. Es sendet aber wirklich Mails an mich.






Bitte diese Zahl eingeben (Spamschutz)

42300
Nach oben