io: jQuery Anfänger: Eigenen Eventhandler unmittelbar nach(!) Default-Aktion des Click-Events ausführen

Ich möchte meinen Eventhandler nicht vor sondern unmittelbar nach dem Default-Verhalten ablaufen lassen. Lässt sich ein eigener Eventhandler überhaupt derart an ein Event binden, dass er als letztes ausgeführt wird?

Hintergrund: Nach jedem Klick in der Navigtion soll ein interner Anker angesprungen werden. Unmittelbar danach soll durch meinen Eventhandler die Seite um 30px nach unten gescrollt werden. Und nur diesen Endzustand soll der Benutzer zu Gesicht bekommen. Hat mit der 30px hohen Navigation zu tun, die oben immer mitwandert.

  1. Hallo,

    kennst du schon https://wiki.selfhtml.org/wiki/JavaScript/Window/setTimeout?

    Gruß
    Jürgen

    1. Gute Idee. jQuery mouseup() ginge eventuell auch (wenn sie denn für Smartphones funktioniert).

      Aber beide Ansätze scheinen mir nicht so "sauber" wie der Gedanke in meinem Ursprungspost.

      1. @@io

        [setTimeout]

        Gute Idee.

        Nicht wirklich.

        jQuery mouseup() ginge eventuell auch

        Du bezeichnest dich als „Anfänger“? Dann ein wohlgemeinter Tip: Lerne JavaScript, nicht jQuery. Ganz ehrlich.

        LLAP 🖖

        -- „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. @@io

    Ich möchte meinen Eventhandler nicht vor sondern unmittelbar nach dem Default-Verhalten ablaufen lassen. Lässt sich ein eigener Eventhandler überhaupt derart an ein Event binden, dass er als letztes ausgeführt wird?

    Ich glaub, du bist auf dem falschen Event.

    Nach jedem Klick in der Navigtion soll ein interner Anker angesprungen werden.

    Beim Wechsel eines seiteninternen Ankers feuert das hashchange-Event …

    Unmittelbar danach soll durch meinen Eventhandler die Seite um 30px nach unten gescrollt werden.

    … damit kannst du nach dem Anspringen des Ankers das Ganze um die Höhe der fixen Navigationsleiste nach unten verschieben …

    Und nur diesen Endzustand soll der Benutzer zu Gesicht bekommen. Hat mit der 30px hohen Navigation zu tun, die oben immer mitwandert.

    … wobei es überhaupt keine gute Idee ist, von einer festen Höhe (30px oder sonstwas) auszugehen. Was, wenn die Menüitems nicht in eine Zeile passen?

    Also: die Höhe der Navigationsleiste erstmal mit JavaScript bestimmen, dann um diesen Betrag runterscrollen.

    Codepen (Ursprünglich erstellt für dieses Posting. In jenem Thread findest du auch noch eine andere Lösung.)

    LLAP 🖖

    -- „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. Super! hashchange Event war mir nicht bekannt. Das funktioniert prima. Und die Höhe der Navigationsleiste dynamisch zu bestimmen ist auch ein toller Tip. Vielen Dank!

      Einziger Makel ist, dass das Event lt. https://caniuse.com/#search=hashchange vom Opera Mini nicht unterstützt wird. 2% der Nutzer haben den zwar nur. Aber ich frage mich ob ich daher statt JavaScript dafür nicht besser z.B. ein jQuery bzw. jQuery Mobile Plugin einsetzen soll. Ich meine gelesen zu haben dass dafür ein Plugin existiert. Vermutlich würde ein solches Plugin eine Fallback-Lösung (heisst das so?) für den Opera Mini anbieten.

      1. Korrigiere mich: Nur 0,28% nutzen Opera Mini in Deutschland.

  3. Hallo io,

    aus meiner Sicht bringen sticky headers, die mit JavaScript oder position:fixed oben am Rand schweben, mehr Ärger als Nutzen.

    Mein Lösungsvorschlag: passendes HTML Markup und CSS. KEIN JavaScript.

    <body> <header> <h1>Hello Foo</h1> </header> <nav><a href="#reallyInteresting">Click Me, I'm great!</a></nav> <div id="scrollframe"> <main> <section>...</section> <section>...</section> <section>...</section> <section> <h2 id="reallyInteresting">And now for something really interesting</h2> <p>... some vewy intewesting text ...</p> </section> <section>...</section> <section>...</section> <section>...</section> </main> <footer> ... </footer> </div> </body>

    Das wäre ein beispielhafter Seitenrahmen, wo mittendrin eine Section ist die aus der Navigation angesprungen wird.

    UM Header und Navigation oben zu lassen, mache ich in solchen Fällen aus dem Body eine Flexbox. Damit das gelingt, muss man die Standard-Margins und -Paddings von html und body etwas tweaken:

    html { margin: 0; padding: 8px; height: 100vh; box-sizing: border-box; } body { margin: 0; height: 100%; display: flex; flex-direction:column; }

    Sinn dieser Tweaks ist, in der height-Angabe nicht mit calc() herumrechnen zu müssen. Normalerweise hat der Body einen gewissen margin, den habe ich zum Padding des HTML gemacht und den Body auf margin:0 gesetzt (falls er bei Dir noch padding hat, musst Du ihm ebenfalls box-sizing:border-box geben damit height:100% nicht zu einem unerwünschten Scrollbar der Gesamtseite führt).

    Im Body befinden sich - bei meinem HTML - nun drei Boxen. Der header, die <nav>igation und das #scrollframe-Div. Ob Du dieses Div brauchst oder nicht ist eine Frage deines Seitendesigns. Soll der footer ebenfalls ständig sichtbar sein? Dann muss das div weg und <main> bekommt id="scrollframe". Auf kleinen Viewports kann das allerdings störend sein. @Gunnar Bittersmann: Ja, das div ist nervig, wenn der Footer mitscrollen soll. Aber ich wüsste nicht, wie man es weg bekommt.

    In der gezeigten Fassung werden header und nav oben bleiben. Nur der Inhalt von #scrollframe hat einen Scrollbar und kann verschoben werden. Dazu bekommt #scrollframe ein flex Attribut (header und nav brauchen keins, der Default ist okay für sie):

    #scrollframe { flex: 1 1 auto; overflow-y:scroll; }

    und natürlich noch mehr Styles, je nach deinen Layout-Wünschen. Klickst Du auf den Link, scrollt nur der #scrollframe-Inhalt.

    Der Link führt Dich auf ein jsFiddle, das das demonstriert:
    https://jsfiddle.net/ckmruxhj/

    Mit Grid statt Flexbox kannst Du auch auf diese Weise auch noch fixe Sidebars unterbringen.

    Rolf

    -- sumpsi - posui - clusi
    1. Auch sehr coole Lösung. Vielen Dank!