netsurfer: jQuery addClass - neue Elementabmessungen

0 48

jQuery addClass - neue Elementabmessungen

netsurfer
  • css
  • javascript
  • jquery
  1. 0
    Camping_RIDER
    1. 1
      1unitedpower
      1. 0
        netsurfer
        1. 0
          1unitedpower
          1. 0
            netsurfer
            1. 0
              Matthias Apsel
              1. 0
                Gunnar Bittersmann
            2. 0
              Gunnar Bittersmann
              1. 0
                netsurfer
                1. 1
                  Gunnar Bittersmann
                  1. 0
                    netsurfer
                    1. 0
                      Gunnar Bittersmann
                      1. 0
                        Gunnar Bittersmann
                      2. 0
                        netsurfer
                        1. 0
                          Gunnar Bittersmann
                          1. 0
                            netsurfer
                          2. 0
                            Gunnar Bittersmann
                            1. 0
                              netsurfer
                            2. 0
                              Gunnar Bittersmann
                              1. 0
                                netsurfer
                                1. 0
                                  Gunnar Bittersmann
                                  1. 0
                                    netsurfer
                                    1. 0
                                      Gunnar Bittersmann
                                      1. 0
                                        netsurfer
                                        1. 0
                                          Gunnar Bittersmann
            3. 0
              1unitedpower
              1. 0
                netsurfer
                1. 0
                  1unitedpower
                  1. 0
                    netsurfer
                    1. 1
                      Camping_RIDER
                      1. 0
                        Gunnar Bittersmann
                        1. 0
                          Camping_RIDER
                          1. 0
                            Gunnar Bittersmann
                            1. 0
                              Camping_RIDER
                              1. 0
                                netsurfer
          2. 0
            netsurfer
            1. 0
              Camping_RIDER
              1. 0
                netsurfer
                1. 0
                  1unitedpower
                2. 0
                  unknown
                  1. 0
                    unknown
                    1. 0
                      netsurfer
  2. 0
    Mitleser
  3. 0

    Fiddle jQuery addClass - neue Elementabmessungen

    netsurfer
  4. 0

    [Erledigt] jQuery addClass - neue Elementabmessungen

    netsurfer
    1. 0
      Camping_RIDER
    2. 0
      unknown

Hallo zusammen!

Ich habe ein (Div) Element, dessen Klassenattributwert ich per jQuery addClass() ändere. Aufgrund der entsprechenden Styleanweisungen im Stylesheet ändern sich dadurch die Abmessungen (Breite und Höhe) des Elements. Und diese sich neu ergebenden Abmessungen brauche ich in der Folge in meinem Script.

Leider tritt hier eine gewisse zeitliche Verzögerung auf, denn eine unmittelbar folgende Abfrage im Skript liefert noch die ursprünglichen Werte zurück.

Wie kann ich denn jetzt innerhalb der kleinstmöglichen Zeitspanne herausfinden, wann das Element seine neuen Abmessungen erhalten hat?

Bin für jede Idee, jeden Tipp und jede Anregung dankbar!

Gruß Gunther

PS: Anstatt dem Klassenattribut den neuen Wert zuzuweisen direkt die Styles per css() zu ändern ist keine (wirkliche) Option - zumindest nicht, solange es eine andere Möglichkeit gibt.

  1. Aloha ;)

    Bin für jede Idee, jeden Tipp und jede Anregung dankbar!

    Das mit der Zeitverzögerung kommt mir ein wenig seltsam vor (ich setze aber meist auch kein jQuery ein, daher kann natürlich der Hund bei jQuery begraben liegen - glaube ich aber nicht wirklich dran).

    Trotzdem hab ich ne Idee zur Lösung:

    Setz eine window.setTimeout()-Schleife ein. Die soll bei jedem Aufruf überprüfen, ob sich die Abmessungen geändert haben und wenn nicht, einen weiteren timeout auf sich selbst setzen. Falls eine Änderung geschehen ist, kann deine ursprünglich gewünschte Funktionalität aufgerufen werden.

    Ich hab aber das ungute Gefühl, dass das mehr ein Workaround als eine Lösung ist, und dass das Problem an anderer Stelle besser direkt zu bekämpfen wäre.

    Bist du dir sicher, dass deine versuchte Abfrage überhaupt wirklich korrekt war? Was liefert die Abfrage, wenn du sie nur mal über die Konsole (nach einer Zeitverzögerung aufrufst)?

    Für aktive Hilfe unsererseits am Debugging wäre es nötig, ein Minimalbeispiel zusammenzustellen - z.B. mit Hilfe von jsFiddle (die haben auch jQuery verfügbar).

    Gemeinhin lässt sich ein Problem leichter finden, wenn man was zum Anschauen und dran rumspielen hat.

    Grüße,

    RIDER

    --
    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
    1. Trotzdem hab ich ne Idee zur Lösung:

      Setz eine window.setTimeout()-Schleife ein.

      Kein schlechter Gedanke, aber das wird nicht verlässlich funktionieren. Wenn man mit JavaScript eine HTML-Klasse vergibt, dann unternimmt der Browser sofort einen blockierenden Reflow. Der TO braucht die Abmessungen unmittelbar danach. Denn beim nächsten Reflow könnten die Element-Abmessungen schon wieder andere sein. Mit setTimeout() reiht man einen asynchronen Task in den Event-Loop ein, man hat keine Kontrolle darüber, dass es sich dabei um den Task handelt, der als nächstes ausgeführt wird. Es können diverse andere Tasks dazwischen kommen, zum Beispiel von einem setTimeout()-Aufruf an einer anderen Stelle im Skript, von einem Klick, den der Benutzer ausgeführt hat, oder von einer AJAX-Antwort, die inzwischen eingetroffen ist. Jeder dieser Tasks kann wiederum durch DOM-Manipulation weitere Reflows auslösen.

      setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen. Das führt natürlich zu der Frage, warum der TO trotzdem ein Szenario beobachtet hat, in dem das nicht der Fall zu sein schien. Das Mysterium können wir nur lüften, wenn wir den fraglichen Code zu Gesicht bekommen.

      1. Hallo Jungs!

        So, hab' mich erst jetzt wieder mit der Materie beschäftigen können.

        Trotzdem hab ich ne Idee zur Lösung:

        Setz eine window.setTimeout()-Schleife ein.

        Kein schlechter Gedanke, aber das wird nicht verlässlich funktionieren. Wenn man mit JavaScript eine HTML-Klasse vergibt, dann unternimmt der Browser sofort einen blockierenden Reflow.

        So dachte ich bisher auch. Scheint aber in meinem Fall (durch die per JS zugewiesene Klasse erhält das betreffende Element einen Multi-Column Style) nicht so zu sein. Der Browser braucht anscheinend für eine gewisse Zeit für die Berechnung und Umsetzung (ohne zwischenzeitliche Blockade).

        Der TO braucht die Abmessungen unmittelbar danach. Denn beim nächsten Reflow könnten die Element-Abmessungen schon wieder andere sein. Mit setTimeout() reiht man einen asynchronen Task in den Event-Loop ein, man hat keine Kontrolle darüber, dass es sich dabei um den Task handelt, der als nächstes ausgeführt wird. Es können diverse andere Tasks dazwischen kommen, zum Beispiel von einem setTimeout()-Aufruf an einer anderen Stelle im Skript, von einem Klick, den der Benutzer ausgeführt hat, oder von einer AJAX-Antwort, die inzwischen eingetroffen ist. Jeder dieser Tasks kann wiederum durch DOM-Manipulation weitere Reflows auslösen.

        setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen.

        Das halte ich bis zum Beweis des Gegenteils erstmal für ein Gerücht ...! ;-)

        Das führt natürlich zu der Frage, warum der TO trotzdem ein Szenario beobachtet hat, in dem das nicht der Fall zu sein schien. Das Mysterium können wir nur lüften, wenn wir den fraglichen Code zu Gesicht bekommen.

        Können wir uns gerne mal per Mail drüber austauschen ;-)

        Ich habe es jetzt trotzdem (erstmal) mit einer rekursiven setTimeout() Schleife gemacht (plus zusätzlichem Zähler, um ggf. eine Endlosschleife zu verhindern). In den von mir bisher getesteten Browsern (Chrome und FF) liefert sie reproduzierbar im zweiten Durchlauf den "korrekten", bzw. geänderten Wert.

        Also schon mal meinen besten Dank an alle hier!

        Wenn ich mal Zeit und Luft habe, werde ich mich noch eingehender mit diesem "Phänomen" beschäftigen.

        Gruß Gunther

        1. Kein schlechter Gedanke, aber das wird nicht verlässlich funktionieren. Wenn man mit JavaScript eine HTML-Klasse vergibt, dann unternimmt der Browser sofort einen blockierenden Reflow.

          So dachte ich bisher auch. Scheint aber in meinem Fall (durch die per JS zugewiesene Klasse erhält das betreffende Element einen Multi-Column Style) nicht so zu sein. Der Browser braucht anscheinend für eine gewisse Zeit für die Berechnung und Umsetzung (ohne zwischenzeitliche Blockade).

          Ich vermute, dass du die Klassenzuweisung und das Auslesen der Abmessungen nicht in einem Run-To-Completion-Codeblock ausführst, sondern verteilt über asynchrone Funktionsaufrufe hinweg.

          setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen.

          Das halte ich bis zum Beweis des Gegenteils erstmal für ein Gerücht ...! ;-)

          Das führt natürlich zu der Frage, warum der TO trotzdem ein Szenario beobachtet hat, in dem das nicht der Fall zu sein schien. Das Mysterium können wir nur lüften, wenn wir den fraglichen Code zu Gesicht bekommen.

          Können wir uns gerne mal per Mail drüber austauschen ;-)

          Für Privatnachhilfe stehe ich nicht zur Verfügunge, lass uns das hier im öffentlichen Raum machen, so können auch andere davon profitieren. Niemand erwartet von dir, dass du deinen gesamten Code publik machst, es genügt ein reduziertes Beispiel, an dem wir das von dir beobachtete Verhalten, reproduzieren können.

          1. Hi Raoul!

            Kein schlechter Gedanke, aber das wird nicht verlässlich funktionieren. Wenn man mit JavaScript eine HTML-Klasse vergibt, dann unternimmt der Browser sofort einen blockierenden Reflow.

            So dachte ich bisher auch. Scheint aber in meinem Fall (durch die per JS zugewiesene Klasse erhält das betreffende Element einen Multi-Column Style) nicht so zu sein. Der Browser braucht anscheinend für eine gewisse Zeit für die Berechnung und Umsetzung (ohne zwischenzeitliche Blockade).

            Ich vermute, dass du die Klassenzuweisung und das Auslesen der Abmessungen nicht in einem Run-To-Completion-Codeblock ausführst, sondern verteilt über asynchrone Funktionsaufrufe hinweg.

            Du weißt doch, dass ich JS Laie bin - wirf' mir doch bitte nicht solche "Fachbegriffe" an den Kopf! ;-)

            Ursprünglich wollte ich das schlicht in meiner $(document).ready(function(){}) machen.

            setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen.

            Das halte ich bis zum Beweis des Gegenteils erstmal für ein Gerücht ...! ;-)

            Du hast schon das "jQuery" im Betreff gelesen? :-P Aber nun gut, das tut der Sache ja keinen Abbruch. Aber den Umstand, dass ich ja extra geschrieben habe, dass dann ein Multi-Column Style auf das Element angewendet wird, könnte doch von Bedeutung für das "Problem/ Phänomen" sein, oder nicht? Denn bisher wäre mir zumindest noch nicht aufgefallen, dass ich ein solches Problem gehabt hätte. Sondern ich bin bisher auch immer davon ausgegangen, dass es sich so wie von dir geschildert verhält.

            Hab' ich bis jetzt nur mal übeerflogen.

            Das führt natürlich zu der Frage, warum der TO trotzdem ein Szenario beobachtet hat, in dem das nicht der Fall zu sein schien. Das Mysterium können wir nur lüften, wenn wir den fraglichen Code zu Gesicht bekommen.

            Können wir uns gerne mal per Mail drüber austauschen ;-)

            Für Privatnachhilfe stehe ich nicht zur Verfügunge,

            Schon klar - und von Nachhilfe war auch nicht die Rede ...! :-P

            lass uns das hier im öffentlichen Raum machen, so können auch andere davon profitieren. Niemand erwartet von dir, dass du deinen gesamten Code publik machst, es genügt ein reduziertes Beispiel, an dem wir das von dir beobachtete Verhalten, reproduzieren können.

            Reduziertes Beispiel ist immer so eine Sache ..., wenn bei der Reduktion auch das "Problem" verschwindet.

            Und es ist ein Teil in einem etwas umfangreicheren Layout, das u.a. (in dem relevanten Teil) Flexbox Elemente, absolut positionierte Elemente und dann eben auch das Multi-Column Element enthält.

            Ich denke, du kannst dir ungefähr vorstellen, dass ich da nicht mal eben ein entsprechendes Beispiel erstellen kann.

            Ich teste mal, ob ich das "Problem" auch mit weniger Aufwand reproduzierbar in einem Fiddle nachbauen kann - bitte etwas Geduld.

            Vielleicht habe ich ja auch im grundsätzlichen gedanklichen Ansatz einen "Fehler"?

            Im Prinzip handelt es sich um einen äußeren Container (DIV) und einen inneren (DIV). Wenn jetzt die Höhe des äußeren Containers (Annahme: 100vh) nicht ausreicht, damit der innere Container (variabele Höhe - abhängig vom Inhalt) vollständig ohne Überlauf aufzunehmen, dann weise ich dem inneren Container per JS eine zusätzliche Klasse im Attribut zu. Dadurch kommt ein Multi-Column Style zur Anwendung, welches den Inhalt halt "automatisch" auf die benötigte Anzahl von Spalten aufteilt. Jetzt muss ich wissen, wie breit (width) das Element dadurch geworden ist, weil ich diesen Wert wiederum explizit als width: xy px dem Element zuweisen muss (weil overflow: hidden damit keine Scollbar da ist - geblättert wird per margin-left).

            In meiner "Ahnungslosigkeit habe ich das halt so versucht:

            var scrollParent = $('#outer');
            var scrollElement = $('#inner');
            var baseHeight = scrollParent.prop('clientHeight');
            var scrolledHeight = scrollElement.prop('scrollHeight');
            var baseWidth = scrollElement.width();
            
            if(scrolledHeight > baseHeight) {
            	scrollParent.addClass('scroll');
            	var scrolledWidth = scrollElement.prop('scrollWidth');
            	console.log("baseWidth: " + baseWidth);
            	console.log("scrolledWidth: " + scrolledWidth);
            }
            

            scrolledWidth liefert dann zwar einen anderen Wert als baseWidth, ist aber nicht die tatsächliche Breite des Elements. Diese erhalte ich (zuverlässig) erst, wenn ich es in eine externe Funktion auslagere, und auch dann braucht es noch eine setTimeout() Funktion, damit es "funktioniert".

            Gruß Gunther

            1. Hallo netsurfer,

              Wenn jetzt die Höhe des äußeren Containers (Annahme: 100vh) nicht ausreicht, damit der innere Container (variabele Höhe - abhängig vom Inhalt) vollständig ohne Überlauf aufzunehmen, dann weise ich dem inneren Container per JS eine zusätzliche Klasse im Attribut zu.

              Könnte eine Mediaquery dasselbe, nur wesentlich effizienter leisten?

              Bis demnächst
              Matthias

              --
              Signaturen sind bloed (Steel) und Markdown ist mächtig.
              1. @@Matthias Apsel

                Könnte eine Mediaquery dasselbe, nur wesentlich effizienter leisten?

                Ich denke nicht, denn einspaltig/mehrspaltig hängt nicht (nur) vom Viewport, sondern vom Inhalt (seiner Länge) ab.

                LLAP

                --
                „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
            2. @@netsurfer

              Wenn jetzt die Höhe des äußeren Containers (Annahme: 100vh) nicht ausreicht, damit der innere Container (variabele Höhe - abhängig vom Inhalt) vollständig ohne Überlauf aufzunehmen, dann weise ich dem inneren Container per JS eine zusätzliche Klasse im Attribut zu. Dadurch kommt ein Multi-Column Style zur Anwendung, welches den Inhalt halt "automatisch" auf die benötigte Anzahl von Spalten aufteilt.

              Was gewinnst du dadurch? Wie breit sind denn die einzelnen Spalten?

              (weil overflow: hidden damit keine Scollbar da ist - geblättert wird per margin-left).

              Das verstehe ich nicht (vollständig). Das hört sich aber nicht gut an.

              LLAP

              --
              „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
              1. @@netsurfer

                Wenn jetzt die Höhe des äußeren Containers (Annahme: 100vh) nicht ausreicht, damit der innere Container (variabele Höhe - abhängig vom Inhalt) vollständig ohne Überlauf aufzunehmen, dann weise ich dem inneren Container per JS eine zusätzliche Klasse im Attribut zu. Dadurch kommt ein Multi-Column Style zur Anwendung, welches den Inhalt halt "automatisch" auf die benötigte Anzahl von Spalten aufteilt.

                Was gewinnst du dadurch? Wie breit sind denn die einzelnen Spalten?

                Gewinnen tue ich dadurch, dass die Höhe des inneren Elements vom Inhalt her dann an die Höhe des äußeren Containers angepasst wird (also kein overflow-y mehr). Die Spaltenbreit entspricht der Breite des äußeren Containers (abzgl. margins). Also anstatt quasi ein "Fenster im Fenster" mit vertikaler Scrollleiste zu haben (das ist die Variante für ohne JS), wird das innere stattdessen in der Höhe angepasst und dafür entsprechend breiter.

                (weil overflow: hidden damit keine Scollbar da ist - geblättert wird per margin-left).

                Das verstehe ich nicht (vollständig). Das hört sich aber nicht gut an.

                Sinn und Zweck ist u.a. keine Scrollbar zu haben, sondern "pagination". Da das ja nur dann zum Einsatz kommt, wenn JS aktiviert ist. Unter dem Fenster gibt es dann entsprechende Buttons zum Blättern ( < Seite 1/3 > ). Tatsächlich "verschoben/ positioniert" wird das innere Fenster dann durch einen entsprechenden Wert für margin-left.

                Davon mal abgesehen "funktioniert" das einwandfrei. Nur halt die Geschichte mit der neuen Fenster-/ Containerbreite, wenn der multi-column Style angewendet wird.

                Gruß Gunther

                1. @@netsurfer

                  Gewinnen tue ich dadurch, dass die Höhe des inneren Elements vom Inhalt her dann an die Höhe des äußeren Containers angepasst wird (also kein overflow-y mehr). Die Spaltenbreit entspricht der Breite des äußeren Containers (abzgl. margins). Also anstatt quasi ein "Fenster im Fenster" mit vertikaler Scrollleiste zu haben (das ist die Variante für ohne JS), wird das innere stattdessen in der Höhe angepasst und dafür entsprechend breiter.

                  Ich verstehe nicht, warum du da mit JavaScript was umschalten willst. Du kannst doch einfach Multicolumn-Layout verwenden, indem du column-width setzt, aber nicht column-count. Damit machst du die Spalten so breit wie du sie haben willst und deren Anzahl richtet sich nach dem Inhalt (kann also bei wenig Inhalt auch eine Spalte sein).

                  Beispiel

                  Sinn und Zweck ist u.a. keine Scrollbar zu haben, sondern "pagination".

                  Das überlasse ich dann mal wieder dir.

                  LLAP

                  --
                  „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                  1. @@netsurfer

                    Gewinnen tue ich dadurch, dass die Höhe des inneren Elements vom Inhalt her dann an die Höhe des äußeren Containers angepasst wird (also kein overflow-y mehr). Die Spaltenbreit entspricht der Breite des äußeren Containers (abzgl. margins). Also anstatt quasi ein "Fenster im Fenster" mit vertikaler Scrollleiste zu haben (das ist die Variante für ohne JS), wird das innere stattdessen in der Höhe angepasst und dafür entsprechend breiter.

                    Ich verstehe nicht, warum du da mit JavaScript was umschalten willst.

                    Weil ich das Multicolumn-Layout ja nur dann haben will, wenn

                    1. der Inhalt "zu groß" ist, als dass er ohne Überlauf in das äußere Fenster passt
                    2. JS aktiviert ist

                    Du kannst doch einfach Multicolumn-Layout verwenden, indem du column-width setzt, aber nicht column-count. Damit machst du die Spalten so breit wie du sie haben willst und deren Anzahl richtet sich nach dem Inhalt (kann also bei wenig Inhalt auch eine Spalte sein).

                    Das mache ich ja bereits - nur halt unter den o.g. Voraussetzungen. Denn ohne JS soll das innere Fenster eine vertikale Scrollbar haben.

                    Beispiel

                    Gut, ich könnte dann dem inneren Fenster pauschal ein Multicolumn-Layout zuweisen. Per CSS dann als Default mit column-count: 1. Aber was bringt mir das?

                    Sinn und Zweck ist u.a. keine Scrollbar zu haben, sondern "pagination".

                    Das überlasse ich dann mal wieder dir.

                    Danke, nett von dir! ;-) Ich kann das aber auch kurz erklären: Es handelt sich ja quasi um eine "Fenster im Fenster" Geschichte, die möglichst unter allen Anzeigebedingungen/ -konstellationen so benutzerfreundlich wie möglich sein soll. In Desktop Browsern, die eine Scrollbar anzeigen und der Benutzer eine Maus mit Rad verwendet, kann er dann ja (i.d.R.) per Mausrad vertikal scrollen. Problem ist nur, wenn das innere Fenster am oberen oder unteren Rand angekommen ist, scrollt anschließend das gesamte Element im Viewport => sehr unschön. In Mobile Browsern ist meist gar nicht zu erkennen, dass ein Element gescrollt werden kann. In beiden Fällen ist es auch "lästig/ umständlich" den Inhalt genau an die gewünschte Stelle zu scrollen.

                    Also "übernehme" ich das Scrollen per JS. Und eine Anzeige à la "Seite x/y" sollte auch hinreichend darauf aufmerksam machen, dass es noch mehr Inhalt gibt.

                    Und eigentlich finde ich das Multicolumn-Layout für diesen Zweck ideal, verteilt es doch automatisch den Inhalt quasi auf die benötigte Anzahl von Seiten (Spalten).

                    Was "stört" dich denn an dem Ansatz, bzw. anderer Vorschlag?

                    Die Position des inneren Fensters wird natürlich über left: -xy px (und nicht margin-left) gesteuert (wobei beides "funktioniert") - das noch als Nachtrag zu meinen vorherigen Postings.

                    Gruß Gunther

                    PS: Irgendwie verstehe ich die Textformatierung hier nicht. Habe mir die Formatierungshilfe angesehen - nutzt aber auch nichts ...

                    1. @@netsurfer

                      Ich verstehe nicht, warum du da mit JavaScript was umschalten willst.

                      Weil ich das Multicolumn-Layout ja nur dann haben will, wenn

                      1. der Inhalt "zu groß" ist, als dass er ohne Überlauf in das äußere Fenster passt

                      Und wenn der Inhalt weniger ist, gibt es auch bei Multicolumn-Layout nur eine Spalte. Ich sehe nicht, was es da per JavaScript umzuschalten gäbe.

                      1. JS aktiviert ist

                      Kannst du haben. Gewohnte Vorgehensweise: HTML per JavaScript die Klasse "js" verpassen, Elemente als Nachfahren von .js stylen. In meinem Beispiel: .js .outer {} und .js .inner {}.

                      Gut, ich könnte dann dem inneren Fenster pauschal ein Multicolumn-Layout zuweisen. Per CSS dann als Default mit column-count: 1.

                      Nein, eben nicht. column-count fasst du gar nicht an, sondern nur column-width.

                      Aber was bringt mir das?

                      Dass du keinerlei Gefrickel brauchst, um per JavaScript Ausmaße von Elementen auszulesen und zu setzen. Und keins, um dein dabei auftretendes Zeitproblem zu lösen.

                      Sinn und Zweck ist u.a. keine Scrollbar zu haben, sondern "pagination". Es handelt sich ja quasi um eine "Fenster im Fenster" Geschichte, die möglichst unter allen Anzeigebedingungen/ -konstellationen so benutzerfreundlich wie möglich sein soll.

                      Mag sein, dass Hin-und-Herscrollen per JavaScript mit Zurück-/Vor-Buttons statt nativem horizontalen Scrollen die bessere Variante ist. Screenreader dürften auch den ganzen Text vorlesen.

                      Also go ahead! Dafür JavaScript. Für das eigentliche Multicolumn-Layout nicht.

                      LLAP

                      PS: Besser (performanter) dürfte es sein, wenn du nicht den Wert von left änderst, sondern transform: translateX( … ) einsetzt. Besonders, wenn du das Hin-und-Herscrollen animierst. (Das solltest du tun. Natürlich auch nicht per JavaScript, sondern mit CSS-Transition.)

                      --
                      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                      1. @@Gunnar Bittersmann

                        Kannst du haben. Gewohnte Vorgehensweise: HTML per JavaScript die Klasse "js" verpassen

                        Gemeint war natürlich das html-Element.

                        Also

                        <script>document.documentElement.classList.add('js');</script>
                        

                        bzw. wenn alte Browser noch ein Thema sind

                        <script>document.documentElement.class += ' js');</script>
                        

                        (Sollten sie hier aber nicht sein, da sie sowieso kein Multicolumn-Layout können, dafür also auch nicht die Klasse "js" am html-Element brauchen.)

                        LLAP

                        --
                        „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                      2. @@Gunnar

                        Ich verstehe nicht, warum du da mit JavaScript was umschalten willst.

                        Weil ich das Multicolumn-Layout ja nur dann haben will, wenn

                        1. der Inhalt "zu groß" ist, als dass er ohne Überlauf in das äußere Fenster passt

                        Und wenn der Inhalt weniger ist, gibt es auch bei Multicolumn-Layout nur eine Spalte. Ich sehe nicht, was es da per JavaScript umzuschalten gäbe.

                        Ja doch! Ohne JS soll es ja ein Einspalter mit vertikaler Scrollbar sein. Mit JS ein Mehrspalter ohne Scrollbar.

                        Also muss ich ja von column-width:auto auf einen belieibig größen Wert ändern, damit er zum Mehrspalter wird.

                        1. JS aktiviert ist

                        Kannst du haben. Gewohnte Vorgehensweise: HTML per JavaScript die Klasse "js" verpassen, Elemente als Nachfahren von .js stylen. In meinem Beispiel: .js .outer {} und .js .inner {}.

                        Ja, schon klar ... ;-)

                        Gut, ich könnte dann dem inneren Fenster pauschal ein Multicolumn-Layout zuweisen. Per CSS dann als Default mit column-count: 1.

                        Nein, eben nicht. column-count fasst du gar nicht an, sondern nur column-width.

                        Ja ja, ist ja schon gut. Irrtum meinerseits. Ist ja genau das, was der Browser "automatisch" machen soll.

                        Aber was bringt mir das?

                        Dass du keinerlei Gefrickel brauchst, um per JavaScript Ausmaße von Elementen auszulesen und zu setzen. Und keins, um dein dabei auftretendes Zeitproblem zu lösen.

                        Nein, eben nicht. Um das Blättern zu ermöglichen, muss ich trotzdem die Abmessungen (und somit die Anzahl der entstandenen Spalten) ermitteln.

                        Sinn und Zweck ist u.a. keine Scrollbar zu haben, sondern "pagination". Es handelt sich ja quasi um eine "Fenster im Fenster" Geschichte, die möglichst unter allen Anzeigebedingungen/ -konstellationen so benutzerfreundlich wie möglich sein soll.

                        Mag sein, dass Hin-und-Herscrollen per JavaScript mit Zurück-/Vor-Buttons statt nativem horizontalen Scrollen die bessere Variante ist. Screenreader dürften auch den ganzen Text vorlesen.

                        Also go ahead! Dafür JavaScript. Für das eigentliche Multicolumn-Layout nicht.

                        LLAP

                        PS: Besser (performanter) dürfte es sein, wenn du nicht den Wert von left änderst, sondern transform: translateX( … ) einsetzt. Besonders, wenn du das Hin-und-Herscrollen animierst. (Das solltest du tun. Natürlich auch nicht per JavaScript, sondern mit CSS-Transition.)

                        Ja, danke! Völlig richtig ..., baue ich direkt ein, sobald ich das andere Problem gelöst habe! ;-)

                        Gruß Gunther

                        1. @@netsurfer

                          Dass du keinerlei Gefrickel brauchst, um per JavaScript Ausmaße von Elementen auszulesen und zu setzen. Und keins, um dein dabei auftretendes Zeitproblem zu lösen.

                          Nein, eben nicht. Um das Blättern zu ermöglichen, muss ich trotzdem die Abmessungen (und somit die Anzahl der entstandenen Spalten) ermitteln.

                          Njein.

                          Du kannst die Breite des .inner-Elements auslesen und um diesen Betrag nach rechts/links verschieben. Neuer Pen.

                          Jetzt brauch man „nur noch“ einen Stopper fürs Weiterblättern. Das könnte damit gehen.

                          LLAP

                          --
                          „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                          1. @@Gunnar

                            Dass du keinerlei Gefrickel brauchst, um per JavaScript Ausmaße von Elementen auszulesen und zu setzen. Und keins, um dein dabei auftretendes Zeitproblem zu lösen.

                            Nein, eben nicht. Um das Blättern zu ermöglichen, muss ich trotzdem die Abmessungen (und somit die Anzahl der entstandenen Spalten) ermitteln.

                            Njein.

                            Du kannst die Breite des .inner-Elements auslesen und um diesen Betrag nach rechts/links verschieben. Neuer Pen.

                            Sehr "elegante" Lösung - besten Dank!

                            Jetzt brauch man „nur noch“ einen Stopper fürs Weiterblättern. Das könnte damit gehen.

                            Das erscheint mir aber wie "von hinten durch die Brust ins Auge" ...! :-P Warum denn extra ein leeres Element einfügen, um die Position zu bekommen? Alles was man braucht ist ja die (richtige) scrollWidth des Elements.

                            Gruß Gunther

                          2. @@Gunnar Bittersmann

                            Jetzt brauch man „nur noch“ einen Stopper fürs Weiterblättern. Das könnte damit gehen.

                            Oder auch nicht. Bei mir geht’s nicht.

                            Andere Idee: (Pseudo)element einfügen mit column-span: all, dessen Breite auslesen. Nur dass das auch nicht funktioniert. Safari und Chrome machen das Ding auch nur eine Spalte breit (wegen overflow: hidden?) und das zerschießt das Layout. Firefox unterstützt column-span gar nicht erst.

                            TL;DR: Ich hab noch keine Lösung gefunden, an die Anzahl der Spalten oder an die Gesamtbreite aller Spalten ranzukommen.

                            LLAP 🖖

                            --
                            „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                            1. @@Gunnar Bittersmann

                              Jetzt brauch man „nur noch“ einen Stopper fürs Weiterblättern. Das könnte damit gehen.

                              Oder auch nicht. Bei mir geht’s nicht.

                              Das ist aber keine "klassische Fehlerbeschreibung" Herr Bittersmann ...! :-P

                              Andere Idee: (Pseudo)element einfügen mit column-span: all, dessen Breite auslesen. Nur dass das auch nicht funktioniert. Safari und Chrome machen das Ding auch nur eine Spalte breit (wegen overflow: hidden?) und das zerschießt das Layout. Firefox unterstützt column-span gar nicht erst.

                              TL;DR: Ich hab noch keine Lösung gefunden, an die Anzahl der Spalten oder an die Gesamtbreite aller Spalten ranzukommen.

                              Wie ich schon geschrieben hatte, braucht es diese "Verrenkungen" doch auch gar nicht. Mit scrollWidth erhält man ja den benötigten Wert. Man muss halt nur (nach Möglichkeit) sicherstellen, dass nicht irgendein Handler oder sonst etwas "dazwischen funkt".

                              Denn man braucht so oder so Javascript, um an einen der möglichen benötigten Werte zu kommen. Und da erscheint mir scrollWidth als die einfachste und direkteste Variante.

                              Bei mir "funktioniert" das inzwischen ohne Probleme (gut 200 Mal in verschiedenen Browsern getestet).

                              Gruß Gunther

                            2. @@Gunnar Bittersmann

                              Jetzt brauch man „nur noch“ einen Stopper fürs Weiterblättern. Das könnte damit gehen.

                              Oder auch nicht. Bei mir geht’s nicht.

                              Oder auch doch. Im Pen geht’s nicht, da liefert dummyElement.offsetLeft (warum auch immer) einen unbrauchbaren Wert.

                              Kaum macht man’s richtig, schon geht’s.

                              LLAP 🖖

                              --
                              „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                              1. @@Gunnar Bittersmann

                                Oder auch doch. Im Pen geht’s nicht, da liefert dummyElement.offsetLeft (warum auch immer) einen unbrauchbaren Wert.

                                Vermutlich wegen des iframes ...

                                Gruß Gunther

                                1. @@netsurfer

                                  Vermutlich wegen des iframes ...

                                  Wie auch immer. Jedenfalls funktioniert das mit CSS-Multicolumns – ohne irgendwelches anderes Gefrickel.

                                  LLAP 🖖

                                  --
                                  „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                                  1. @@Gunnar

                                    Vermutlich wegen des iframes ...

                                    Wie auch immer. Jedenfalls funktioniert das mit CSS-Multicolumns – ohne irgendwelches anderes Gefrickel.

                                    Nein, tut es nicht! ;-) Weil du so oder so per Javascript die Elementbreite (und somit die "entstandene" Anzahl an Spalten) ermitteln musst, wofür es wie bereits gesagt verschiedene Möglichkeiten gibt.

                                    Alles andere, inklusive dem "animierten" Scrollen funktioniert dann rein per CSS, da stimme ich dir zu.

                                    Und falls das hier in Zukunft mal jemand lesen sollte, der etwas Ähnliches bauen will, hier noch ein Tipp:

                                    Angenommen der in Spalten umzubrechende Text ist auf mehrere P-Elemente verteilt, und man möchte nicht, dass der Text innerhalb eines Abschnitts umgebrochen wird, dann kann man das ebenfalls per CSS verhindern (Stand heute noch mit Vendor Prefixes)

                                    p {
                                    -webkit-column-break-inside: avoid;
                                              page-break-inside: avoid;
                                                   break-inside: avoid;
                                    }
                                    

                                    siehe: CSS-Tricks - break-inside

                                    Gruß Gunther

                                    1. @@netsurfer

                                      Wie auch immer. Jedenfalls funktioniert das mit CSS-Multicolumns – ohne irgendwelches anderes Gefrickel.

                                      Nein, tut es nicht! ;-) Weil du so oder so per Javascript die Elementbreite (und somit die "entstandene" Anzahl an Spalten) ermitteln musst,

                                      Nein, muss ich nicht.

                                      Das will ich (besser gesagt du), und zwar nur deshalb, weil du das native horizontale Scrollen durch ein JavaScript-Blättern ersetzen willst. Für das eigentliche Layouten ist es nicht erforderlich.

                                      Und musstest du nicht eingangs nicht nur die Breite, sondern auch die Höhe auslesen, um überhaupt das Layout hinzubekommen?

                                      LLAP 🖖

                                      PS: Damit das native horizontale Scrollen ohne JavaScript funktioniert, muss
                                      .outerElement { overflow: scroll } sein.

                                      Nur wenn JavaScript ausgeführt wird: .js .outerElement { overflow: hidden }

                                      Ich hab mein Beispiel mal angepasst.

                                      --
                                      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                                      1. @@Gunnar

                                        Wie auch immer. Jedenfalls funktioniert das mit CSS-Multicolumns – ohne irgendwelches anderes Gefrickel.

                                        Nein, tut es nicht! ;-) Weil du so oder so per Javascript die Elementbreite (und somit die "entstandene" Anzahl an Spalten) ermitteln musst,

                                        Nein, muss ich nicht.

                                        Tust du aber mit deinem Dummy-Element ...!

                                        Das will ich (besser gesagt du), und zwar nur deshalb, weil du das native horizontale Scrollen durch ein JavaScript-Blättern ersetzen willst. Für das eigentliche Layouten ist es nicht erforderlich.

                                        Ja gut, das ist aber ja der Sinn & Zweck des Ganzen ...!

                                        Und musstest du nicht eingangs nicht nur die Breite, sondern auch die Höhe auslesen, um überhaupt das Layout hinzubekommen?

                                        Nicht um das Layout "hinzubekommen", sondern um im Bedarfsfall auf dieses Layout zu wechseln. Ohne Javascript ist der Text ja an die Elementbreite angepasst und wird ggf. vertikal gescrollt.

                                        Gruß Gunther

                                        1. @@netsurfer

                                          Ohne Javascript ist der Text ja an die Elementbreite angepasst und wird ggf. vertikal gescrollt.

                                          Stimmt auch wieder. Das ist natürlich der sinnvollere No-JS-Fallback gegenüber horizontalem Scrollen.

                                          LLAP 🖖

                                          --
                                          „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
            3. Ich vermute, dass du die Klassenzuweisung und das Auslesen der Abmessungen nicht in einem Run-To-Completion-Codeblock ausführst, sondern verteilt über asynchrone Funktionsaufrufe hinweg.

              Du weißt doch, dass ich JS Laie bin - wirf' mir doch bitte nicht solche "Fachbegriffe" an den Kopf! ;-)

              Ein Run-To-Completion-Codeblock ist eine Einheit Code, die garantiert bis zu Ende ausgeführt wird und nicht von asynchronen Aufrufen (Klicks, AJAX-Anfragen, Timeouts, etc) unterbrochen werden kann.

              Ursprünglich wollte ich das schlicht in meiner $(document).ready(function(){}) machen.

              Das ist zum Beispiel ein asyncrhoner Task, man muss also auf die Ausführungsreihenfolge achten:

              var i = 0;
              $(document).ready(function(){
                console.log(i++); // Diese Zeile wird nach der anderen console.log-Zeile ausgeführt
              });
              console.log(i++); // Diese Zeile wird vor der anderen console.log-Zeile ausgeführt
              

              setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen.

              Das halte ich bis zum Beweis des Gegenteils erstmal für ein Gerücht ...! ;-)

              Du hast schon das "jQuery" im Betreff gelesen? :-P

              Klar, aber für jQuery gelten die selben Regeln, die für Vanilla-JavaScript auch gelten. Es könnte natürlich sein, dass jQuery aus Perfomance-Gründen versucht den Reflow weg zu optimieren, dafür wäre es notwendig, die Klasse in einem asynchronen Task zu vergeben, das ginge zum Beispiel mit setImmediate() oder requestAnimationFrame(). Diese These lässt sich aber durch einen weiteren Test falsifizieren:

              http://jsfiddle.net/s9h6g2tt/

              Aber nun gut, das tut der Sache ja keinen Abbruch. Aber den Umstand, dass ich ja extra geschrieben habe, dass dann ein Multi-Column Style auf das Element angewendet wird, könnte doch von Bedeutung für das "Problem/ Phänomen" sein, oder nicht?

              Für den JavaScript-Teil in deiner Frage ist das irrelevant, der Reflow findet statt, weil eine HTML-Klasse vergeben wird. Welche CSS-Regeln nun konkret angewendet werden müssen, entscheidet sich während des Reflows und kann nicht auf magische Weise vom Browser voraus geahnt werden.

              Allerdings ist die Information hier trotzdem nicht vollkommen unnütz, denn vielleicht ergibt sich die Möglichkeit eine Lösung ohne JavaScript zu finden.

              lass uns das hier im öffentlichen Raum machen, so können auch andere davon profitieren. Niemand erwartet von dir, dass du deinen gesamten Code publik machst, es genügt ein reduziertes Beispiel, an dem wir das von dir beobachtete Verhalten, reproduzieren können.

              Reduziertes Beispiel ist immer so eine Sache ..., wenn bei der Reduktion auch das "Problem" verschwindet.

              Das ist doch auch schon mal was, dann weißt du zumindest schon mal, in welchem Teil des Codes der Fehler nicht steckt.

              Und es ist ein Teil in einem etwas umfangreicheren Layout, das u.a. (in dem relevanten Teil) Flexbox Elemente, absolut positionierte Elemente und dann eben auch das Multi-Column Element enthält.

              Ich denke, du kannst dir ungefähr vorstellen, dass ich da nicht mal eben ein entsprechendes Beispiel erstellen kann.

              Gibt es denn wenigstens eine Live-Seite, an der wir dein Problem beobachten können?

              In meiner "Ahnungslosigkeit habe ich das halt so versucht:

              var scrollParent = $('#outer');
              var scrollElement = $('#inner');
              var baseHeight = scrollParent.prop('clientHeight');
              var scrolledHeight = scrollElement.prop('scrollHeight');
              var baseWidth = scrollElement.width();
              
              if(scrolledHeight > baseHeight) {
              	scrollParent.addClass('scroll');
              	var scrolledWidth = scrollElement.prop('scrollWidth');
              	console.log("baseWidth: " + baseWidth);
              	console.log("scrolledWidth: " + scrolledWidth);
              }
              

              scrolledWidth liefert dann zwar einen anderen Wert als baseWidth, ist aber nicht die tatsächliche Breite des Elements.

              Du vergleichst hier Eigenschaften, die du unterschiedlich gemessen hast. Bei der deiner ersten Messung greifst du auf .width() zu, bei deiner zweiten Messung auf .prop('scrollWidth'). Dass diese sich unterscheiden, ist nicht weiter verwunderlich. Du solltest zunächst in Erfahrung bringen, welche Messgröße für dich interessant ist. Ansonsten vergleichst du sprichwörtlich Äpfel mit Birnen.

              Diese erhalte ich (zuverlässig) erst, wenn ich es in eine externe Funktion auslagere, und auch dann braucht es noch eine setTimeout() Funktion, damit es "funktioniert".

              Nein, zuverlässig ist die Messung mit Sicherheit nicht, die Gründe dafür habe ich ja schon erklärt. Es sind zufällig die erwarteten Messwerte, weil kein anderer asynchroner Task dazwischen funkt. Sogesehen ist dieser Workaround eine tickende Zeitbombe. Der nächste Klick vom Nutzer, die nächste Ajax-Abfrage oder die nächste Code-Änderung wird hier zu unerwartetem Verhalten führen.

              1. Ich vermute, dass du die Klassenzuweisung und das Auslesen der Abmessungen nicht in einem Run-To-Completion-Codeblock ausführst, sondern verteilt über asynchrone Funktionsaufrufe hinweg.

                Du weißt doch, dass ich JS Laie bin - wirf' mir doch bitte nicht solche "Fachbegriffe" an den Kopf! ;-)

                Ein Run-To-Completion-Codeblock ist eine Einheit Code, die garantiert bis zu Ende ausgeführt wird und nicht von asynchronen Aufrufen (Klicks, AJAX-Anfragen, Timeouts, etc) unterbrochen werden kann.

                Ursprünglich wollte ich das schlicht in meiner $(document).ready(function(){}) machen.

                Das ist zum Beispiel ein asyncrhoner Task, man muss also auf die Ausführungsreihenfolge achten:

                var i = 0;
                $(document).ready(function(){
                  console.log(i++); // Diese Zeile wird nach der anderen console.log-Zeile ausgeführt
                });
                console.log(i++); // Diese Zeile wird vor der anderen console.log-Zeile ausgeführt
                

                Ja, danke für die Erklärung. Folglich handelt es sich bei meinem ursprünglichen Ansatz aber ja nicht um einen asyncrhonen Task, richtig?

                setTimeout() wird hier also nicht den gewünschten Effekt haben (zumindest kann man sich darauf nicht verlassen). Das Positive daran ist, dass man setTimeout gar nicht benötigte, wie gesagt, findet der Reflow blockierend und unmittelbar in Folge der DOM-Manipulation statt, es ist möglich mit der nächsten Anweisung sofort die neuen Abmessungen auszulesen.

                Das halte ich bis zum Beweis des Gegenteils erstmal für ein Gerücht ...! ;-)

                Du hast schon das "jQuery" im Betreff gelesen? :-P

                Klar, aber für jQuery gelten die selben Regeln, die für Vanilla-JavaScript auch gelten. Es könnte natürlich sein, dass jQuery aus Perfomance-Gründen versucht den Reflow weg zu optimieren, dafür wäre es notwendig, die Klasse in einem asynchronen Task zu vergeben, das ginge zum Beispiel mit setImmediate() oder requestAnimationFrame(). Diese These lässt sich aber durch einen weiteren Test falsifizieren:

                http://jsfiddle.net/s9h6g2tt/

                Gut, dann scheidet eine mögliche Ursache damit schon mal aus.

                Aber nun gut, das tut der Sache ja keinen Abbruch. Aber den Umstand, dass ich ja extra geschrieben habe, dass dann ein Multi-Column Style auf das Element angewendet wird, könnte doch von Bedeutung für das "Problem/ Phänomen" sein, oder nicht?

                Für den JavaScript-Teil in deiner Frage ist das irrelevant, der Reflow findet statt, weil eine HTML-Klasse vergeben wird. Welche CSS-Regeln nun konkret angewendet werden müssen, entscheidet sich während des Reflows und kann nicht auf magische Weise vom Browser voraus geahnt werden.

                Soweit die Theorie (von der ich ja bislang auch immer ausgegangen bin). Und ich weiß ehrlich gesagt nicht, wie ich solch ein Browser internes Verhalten "prüfen" soll!?

                Ganz "offensichtlich", dauert es aber in diesem Fall ja länger, bis das Element seine neuen Abmessungen hat, bzw. per JS Abfrage zurückliefert.

                Allerdings ist die Information hier trotzdem nicht vollkommen unnütz, denn vielleicht ergibt sich die Möglichkeit eine Lösung ohne JavaScript zu finden.

                Nein, die gibt es nicht. ;-)

                lass uns das hier im öffentlichen Raum machen, so können auch andere davon profitieren. Niemand erwartet von dir, dass du deinen gesamten Code publik machst, es genügt ein reduziertes Beispiel, an dem wir das von dir beobachtete Verhalten, reproduzieren können.

                Reduziertes Beispiel ist immer so eine Sache ..., wenn bei der Reduktion auch das "Problem" verschwindet.

                Das ist doch auch schon mal was, dann weißt du zumindest schon mal, in welchem Teil des Codes der Fehler nicht steckt.

                Und es ist ein Teil in einem etwas umfangreicheren Layout, das u.a. (in dem relevanten Teil) Flexbox Elemente, absolut positionierte Elemente und dann eben auch das Multi-Column Element enthält.

                Ich denke, du kannst dir ungefähr vorstellen, dass ich da nicht mal eben ein entsprechendes Beispiel erstellen kann.

                Gibt es denn wenigstens eine Live-Seite, an der wir dein Problem beobachten können?

                Wenn dem so wäre, hätte ich bereits im Ausgangspsoting den Link gepostet ...! ;-)

                In meiner "Ahnungslosigkeit habe ich das halt so versucht:

                var scrollParent = $('#outer');
                var scrollElement = $('#inner');
                var baseHeight = scrollParent.prop('clientHeight');
                var scrolledHeight = scrollElement.prop('scrollHeight');
                var baseWidth = scrollElement.width();
                
                if(scrolledHeight > baseHeight) {
                	scrollParent.addClass('scroll');
                	var scrolledWidth = scrollElement.prop('scrollWidth');
                	console.log("baseWidth: " + baseWidth);
                	console.log("scrolledWidth: " + scrolledWidth);
                }
                

                scrolledWidth liefert dann zwar einen anderen Wert als baseWidth, ist aber nicht die tatsächliche Breite des Elements.

                Du vergleichst hier Eigenschaften, die du unterschiedlich gemessen hast. Bei der deiner ersten Messung greifst du auf .width() zu, bei deiner zweiten Messung auf .prop('scrollWidth'). Dass diese sich unterscheiden, ist nicht weiter verwunderlich.

                Ja, schon klar. Das ist aber beabsichtigt. Denn nachdem das Multicolumn-Layout angewendet wurde, wird das Element ja (logischerweise) breiter. Und dann brauche ich die 'scrollWidth', während ich vorher die ursprüngliche Breite ermittele, die dann der Spaltenbreite (column-width) entspricht.

                Was ich oben damit sagen wollte ist, dass die direkt anschließende scrolledWidth Abfrage nicht den "korrekten" Wert zurückliefert.

                Du solltest zunächst in Erfahrung bringen, welche Messgröße für dich interessant ist. Ansonsten vergleichst du sprichwörtlich Äpfel mit Birnen.

                s.o.

                Diese erhalte ich (zuverlässig) erst, wenn ich es in eine externe Funktion auslagere, und auch dann braucht es noch eine setTimeout() Funktion, damit es "funktioniert".

                Nein, zuverlässig ist die Messung mit Sicherheit nicht, die Gründe dafür habe ich ja schon erklärt. Es sind zufällig die erwarteten Messwerte, weil kein anderer asynchroner Task dazwischen funkt. Sogesehen ist dieser Workaround eine tickende Zeitbombe. Der nächste Klick vom Nutzer, die nächste Ajax-Abfrage oder die nächste Code-Änderung wird hier zu unerwartetem Verhalten führen.

                Deshalb habe ich es doch extra in eine rekursive Funktion gepackt!

                Aber nun gut, dann habe ich also 2 Fragen:

                1. Wieso liefert die direkte Abfrage von scrollWidth nicht das richtige Ergebnis
                2. Wie ermittele ich zuverlässig die scrollWidth?

                Gruß Gunther

                1. var i = 0;
                  $(document).ready(function(){
                    console.log(i++); // Diese Zeile wird nach der anderen console.log-Zeile ausgeführt
                  });
                  console.log(i++); // Diese Zeile wird vor der anderen console.log-Zeile ausgeführt
                  

                  Ja, danke für die Erklärung. Folglich handelt es sich bei meinem ursprünglichen Ansatz aber ja nicht um einen asyncrhonen Task, richtig?

                  Ich kenne deinen ursprünglichen Ansatz ja nicht. Ich kann dir nur die Theorie erläutern und an isolierten Showcases demonstrieren.

                  Für den JavaScript-Teil in deiner Frage ist das irrelevant, der Reflow findet statt, weil eine HTML-Klasse vergeben wird. Welche CSS-Regeln nun konkret angewendet werden müssen, entscheidet sich während des Reflows und kann nicht auf magische Weise vom Browser voraus geahnt werden.

                  Soweit die Theorie (von der ich ja bislang auch immer ausgegangen bin). Und ich weiß ehrlich gesagt nicht, wie ich solch ein Browser internes Verhalten "prüfen" soll!?

                  Zwei solcher Testfälle habe ich dir bei jsfiddle ja nun schon vorgekaut. Ansonsten kannst du solche Details von den Browserherstellern erfahren, einen enstrpechenden Verweis habe ich dir ja schon zukommen lassen.

                  Ganz "offensichtlich", dauert es aber in diesem Fall ja länger, bis das Element seine neuen Abmessungen hat, bzw. per JS Abfrage zurückliefert.

                  Nein, ganz offensichtlich nicht.

                  Ja, schon klar. Das ist aber beabsichtigt. Denn nachdem das Multicolumn-Layout angewendet wurde, wird das Element ja (logischerweise) breiter. Und dann brauche ich die 'scrollWidth', während ich vorher die ursprüngliche Breite ermittele, die dann der Spaltenbreite (column-width) entspricht.

                  Was ich oben damit sagen wollte ist, dass die direkt anschließende scrolledWidth Abfrage nicht den "korrekten" Wert zurückliefert.

                  Doch, das tut sie. Ich habe nun mal an verschiedenen Zeitpunkten gemessen:

                  1. Direkt nach dem Reflow, also unmittelbar nachdem die Klasse gesetzt wird
                  2. Im nächsten Animations-Task (requestAnimationFrame)
                  3. Eine Sekunde verzögert, also mit aller Wahrscheinlichkeit nach dem der Browser die Änderungen auch gezeichnet hat. (setTimeout)

                  Jedesmal erhalte ich den Wert 281 für scrollWidth. Überzeuge dich selbst von den Testergebnissen: http://jsfiddle.net/t98kgqer/1/ (Nicht vergessen die JavaScript-Konsole zu öffnen, um die Ausgabe zu sehen)

                  Offensichtlich erwartest du einfach einfach einen falschen Wert.

                  Nein, zuverlässig ist die Messung mit Sicherheit nicht, die Gründe dafür habe ich ja schon erklärt. Es sind zufällig die erwarteten Messwerte, weil kein anderer asynchroner Task dazwischen funkt. Sogesehen ist dieser Workaround eine tickende Zeitbombe. Der nächste Klick vom Nutzer, die nächste Ajax-Abfrage oder die nächste Code-Änderung wird hier zu unerwartetem Verhalten führen.

                  Deshalb habe ich es doch extra in eine rekursive Funktion gepackt!

                  Ich verstehe den Zusammenhang nicht, zu dem was ich erklärt habe. Was wolltest du mit der Rekursion bezwecken?

                  Aber nun gut, dann habe ich also 2 Fragen:

                  1. Wieso liefert die direkte Abfrage von scrollWidth nicht das richtige Ergebnis

                  Tut sie doch. Siehe das jünge Fiddle-Beispiel.

                  1. Wie ermittele ich zuverlässig die scrollWidth?

                  Genau so, wie du es jetzt schon tust. Du erwartest aber offensichtlich einen abweichenden Wert, der in deinem späteren Programmablauf auch wirklich eintritt. Dieses Eintreten des Wertes ist aber keine Folge dieser Klassenzuweisung. Du wirst in deinem Programm noch eine andere Stelle haben, die den Browser dazu veranlasst, das Layout neu zu berechnen, also einen Reflow vorzunehmen. Das ist die Stelle die du rausfinden musst, und dort muss du die Abmessungen nehmen.

                  1. Den Rest hier habe ich der Übersichtlichkeit wegen mal rausgeschmissen.

                    Aber nun gut, dann habe ich also 2 Fragen:

                    1. Wieso liefert die direkte Abfrage von scrollWidth nicht das richtige Ergebnis

                    Tut sie doch. Siehe das jünge Fiddle-Beispiel.

                    Bei mir aber nicht ...! Da nutzt mir das Fiddle auch nichts. ;-)

                    1. Wie ermittele ich zuverlässig die scrollWidth?

                    Genau so, wie du es jetzt schon tust.

                    Offensichtlich ja wohl nicht ..., denn es führt ja nicht zum gewünschten Ergebnis! :-P

                    Du erwartest aber offensichtlich einen abweichenden Wert, der in deinem späteren Programmablauf auch wirklich eintritt.

                    Der sollte/ müsste aber bereits durch die hinzugefügte Klasse eintreten (was er in dem Fiddle ja auch tut) und nicht erst im "späteren Programmablauf".

                    Dieses Eintreten des Wertes ist aber keine Folge dieser Klassenzuweisung.

                    Müsste es aber sein. Denn es gibt keine weitere "Aktion", die das bewirken würde.

                    Du wirst in deinem Programm noch eine andere Stelle haben, die den Browser dazu veranlasst, das Layout neu zu berechnen, also einen Reflow vorzunehmen.

                    Bei mir ändert sich durch die Klassenzuweisung wesentlich mehr, als in meinem Beispiel-Fiddle. Kann es sein, dass der Browser deshalb mehrere Reflows hintereinander ausführt, und somit der JS Ablauf zwischen jedem Reflow weiter läuft, sodass meine eigentliche Änderung des Elements (auf das es mir ankommt) nicht im ersten Reflow erfolgt? Denn anders kann ich mir das "nicht funktionieren" bei mir nicht erklären ...!

                    Zumal es ja den erwarteten und richtigen Wert zurückliefert, sobald ich es über eine externe setTimeout() Funktion mache.

                    Das ist die Stelle die du rausfinden musst, und dort muss du die Abmessungen nehmen.

                    Wie gesagt, andere Stelle gibt es nicht!

                    Gruß Gunther

                    1. Aloha ;)

                      Tut sie doch. Siehe das jünge Fiddle-Beispiel.

                      Bei mir aber nicht ...! Da nutzt mir das Fiddle auch nichts. ;-)

                      Doch, tut es. Du hast damit eine Fehlerquelle (die du als wahrscheinlich angenommen hattest) herausgeschmissen.

                      1. Wie ermittele ich zuverlässig die scrollWidth?

                      Genau so, wie du es jetzt schon tust.

                      Offensichtlich ja wohl nicht ..., denn es führt ja nicht zum gewünschten Ergebnis! :-P

                      Dann liegt das nicht daran, dass du die scrollWidth falsch ermittelst, sondern, dass du an einer anderen Stelle einen Fehler gemacht hast.

                      Müsste es aber sein. Denn es gibt keine weitere "Aktion", die das bewirken würde.

                      Das schreit geradezu nach Betriebsblindheit :P Schau nochmal über deinen Quellcode. Wenn das jsfiddle im selben Browser, d.h. unter denselben Rahmenbedingungen funktioniert, muss in deinem Quellcode etwas anderes stehen. Das kannst aber nur du rauszaubern, außer, du stellst uns was zum dran rumspielen zur Verfügung, das den entsprechenden Fehler aufweist ;)

                      Du wirst in deinem Programm noch eine andere Stelle haben, die den Browser dazu veranlasst, das Layout neu zu berechnen, also einen Reflow vorzunehmen.

                      Bei mir ändert sich durch die Klassenzuweisung wesentlich mehr, als in meinem Beispiel-Fiddle. Kann es sein, dass der Browser deshalb mehrere Reflows hintereinander ausführt, und somit der JS Ablauf zwischen jedem Reflow weiter läuft, sodass meine eigentliche Änderung des Elements (auf das es mir ankommt) nicht im ersten Reflow erfolgt? Denn anders kann ich mir das "nicht funktionieren" bei mir nicht erklären ...!

                      Nein, das kann nicht sein (zumindest nicht so). Wenn ich Raoul richtig verstanden habe, laufen Anweisung und zugehöriger Reflow atomar ab (was auch Sinn macht und eine unbedingte Voraussetzung dafür ist, dass überhaupt irgendwas funktioniert).

                      Du musst dich von der Vermutung, dass javascript/jquery hier ein Fehlverhalten zeigt, lösen und nach dem Fehlverhalten in deinem Quellcode suchen (das es geben muss, weil das Verhalten ja nicht reproduzierbar ist).

                      Du musst mit dem Minimalbeispiel die Stufen nachvollziehen bis zu deiner Implementierung, und an irgendeiner Stelle wird dir das Fehlverhalten unterkommen. Dann weist du, dass du den Fehler gefunden hast. Wetten, dass es dann gleich ziemlich klar ist, was falsch war ;)

                      Grüße,

                      RIDER

                      --
                      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                      1. @@Camping_RIDER

                        Das schreit geradezu nach Betriebsblindheit :P

                        Ja. Und zwar von allen, die ein Layoutproblem per JavaScript-Frickelei zu lösen gedenken, einschließlich derer, die dazu das Zeitproblem versuchen zu lösen.

                        JavaScript weg, Problem weg. :-b

                        LLAP

                        --
                        „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                        1. Aloha ;)

                          Das schreit geradezu nach Betriebsblindheit :P

                          Ja. Und zwar von allen, die ein Layoutproblem per JavaScript-Frickelei zu lösen gedenken, einschließlich derer, die dazu das Zeitproblem versuchen zu lösen.

                          JavaScript weg, Problem weg. :-b

                          Ich würde dir zustimmen, aber ich glaube du hast Gunther nicht vollständig verstanden. So wie ich Gunther verstehe, ist es eben kein Layoutproblem, sondern ein funktionelles Problem im Sinne von progressive enhancement (er möchte ja statt dem stufenlosen Scrollen als Komfortfunktion ein Seiten-springen anbieten).

                          Und das löst man durchaus mit JavaScript.

                          Grüße,

                          RIDER

                          --
                          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                          1. @@Camping_RIDER

                            JavaScript weg, Problem weg. :-b

                            Ich würde dir zustimmen, aber ich glaube du hast Gunther nicht vollständig verstanden. So wie ich Gunther verstehe, ist es eben kein Layoutproblem, sondern ein funktionelles

                            Wie ich Gunther verstehe, tritt das Zeitproblem beim Auslesen/Zuweisen der Ausmaße auf. Und das ist ein Layoutproblem. Und sollte ohne JavaScript lösbar sein (lies: gelöst werden).

                            (er möchte ja statt dem stufenlosen Scrollen als Komfortfunktion ein Seiten-springen anbieten).

                            Und das löst man durchaus mit JavaScript.

                            Das ja. Genau das sag ich doch.

                            LLAP

                            --
                            „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                            1. Aloha ;)

                              Ich würde dir zustimmen, aber ich glaube du hast Gunther nicht vollständig verstanden. So wie ich Gunther verstehe, ist es eben kein Layoutproblem, sondern ein funktionelles

                              Wie ich Gunther verstehe, tritt das Zeitproblem beim Auslesen/Zuweisen der Ausmaße auf. Und das ist ein Layoutproblem. Und sollte ohne JavaScript lösbar sein (lies: gelöst werden).

                              So wie ich ihn verstehe, tritt das Problem beim Auslesen des aktuellen Scroll-Wertes auf, d.h. da gehts dann schon um das Ersetzen der Scroll-Funktionalität durch die Pagination.

                              Kann mich aber auch täuschen. Wenn du Gunther richtig verstanden hast, hast du natürlich Recht.

                              Oder es gibt hier mehr als nur ein Problem zu lösen und die Lösungsvorschläge purzeln munter durcheinander, was auch ungünstig wäre ;)

                              Grüße,

                              RIDER

                              --
                              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                              1. Aloha ;)

                                Ich würde dir zustimmen, aber ich glaube du hast Gunther nicht vollständig verstanden. So wie ich Gunther verstehe, ist es eben kein Layoutproblem, sondern ein funktionelles

                                Wie ich Gunther verstehe, tritt das Zeitproblem beim Auslesen/Zuweisen der Ausmaße auf. Und das ist ein Layoutproblem. Und sollte ohne JavaScript lösbar sein (lies: gelöst werden).

                                So wie ich ihn verstehe, tritt das Problem beim Auslesen des aktuellen Scroll-Wertes auf, d.h. da gehts dann schon um das Ersetzen der Scroll-Funktionalität durch die Pagination.

                                Du hast mich schon ganz richtig verstanden ....! Der Browser soll mir ja (per CSS) meinen (variablen) Text von der Höhe her automatisch anpassen und in der Breite auf entsprechend viele Spalten verteilen.

                                Da ich aber die Scrollbar nicht haben möchte, muss ich dem Element anschließend die durch das mehrspaltige Layout entstandene neue Breite explizit als width zuweisen (und außerdem ja auch wissen, wie viele Spalten es denn geworden sind).

                                Und genau dabei tritt ja das Problem auf.

                                @Gunnar: Welches sich auch nicht dadurch löst, dass ich von Anfang an Multicolumn (column-width: auto) verwende - siehe Antwort auf deinen Beitrag.

                                Gruß Gunther

          2. @Raoul

            Kein schlechter Gedanke, aber das wird nicht verlässlich funktionieren. Wenn man mit JavaScript eine HTML-Klasse vergibt, dann unternimmt der Browser sofort einen blockierenden Reflow.

            So dachte ich bisher auch. Scheint aber in meinem Fall (durch die per JS zugewiesene Klasse erhält das betreffende Element einen Multi-Column Style) nicht so zu sein. Der Browser braucht anscheinend für eine gewisse Zeit für die Berechnung und Umsetzung (ohne zwischenzeitliche Blockade).

            Ich vermute, dass du die Klassenzuweisung und das Auslesen der Abmessungen nicht in einem Run-To-Completion-Codeblock ausführst, sondern verteilt über asynchrone Funktionsaufrufe hinweg.

            Dass ich das nicht tue/ getan habe, haben wir ja inzwischen gesehen. Ich frage mich gerade, wie es denn überhaupt möglich ist, dass dann bei

            var scrollParent = $('#outer');
            var scrollElement = $('#inner');
            var baseHeight = scrollParent.prop('clientHeight');
            var scrolledHeight = scrollElement.prop('scrollHeight');
            var baseWidth = scrollElement.width();
            
            if(scrolledHeight > baseHeight) {
            	scrollParent.addClass('scroll');
            	var scrolledWidth = scrollElement.prop('scrollWidth');
            	console.log("baseWidth: " + baseWidth);
            	console.log("scrolledWidth: " + scrolledWidth);
            }
            

            nicht das korrekte Ergebnis für scrolledWidth rauskommen kann?

            Das ist mir im Moment zumindest ziemlich schleierhaft. hast du eine Idee und könntest mir zu besserem Verständnis verhelfen?

            Besten Dank im Voraus.

            Gruß Gunther

            1. Aloha ;)

              Ich frage mich gerade, wie es denn überhaupt möglich ist, dass dann bei

              var scrollParent = $('#outer');
              var scrollElement = $('#inner');
              var baseHeight = scrollParent.prop('clientHeight');
              var scrolledHeight = scrollElement.prop('scrollHeight');
              var baseWidth = scrollElement.width();
              
              if(scrolledHeight > baseHeight) {
              	scrollParent.addClass('scroll');
              	var scrolledWidth = scrollElement.prop('scrollWidth');
              	console.log("baseWidth: " + baseWidth);
              	console.log("scrolledWidth: " + scrolledWidth);
              }
              

              nicht das korrekte Ergebnis für scrolledWidth rauskommen kann?

              Gar nicht. Und das behaupte ich solange, bis du mir den empirischen Gegenbeweis lieferst ;)

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
              1. Aloha ;)

                Ich frage mich gerade, wie es denn überhaupt möglich ist, dass dann bei ... nicht das korrekte Ergebnis für scrolledWidth rauskommen kann?

                Gar nicht. Und das behaupte ich solange, bis du mir den empirischen Gegenbeweis lieferst ;)

                Nun hör' aber auf ...! :-P Soll ich dir einen Screenshot von meiner Konsole posten?

                Ich habe schon fast alles andere rausgeschmissen und und und ..., aber wenn ich genau den Code in meiner Document Ready Funktion ausführe, kommt grundsätzlich (allso immer, in jedem Fall, zu 100%) derselbe (noch nicht korrekte) Wert dabei raus.

                Verwende ich hingegen eine setTimeout Funktion (separat), kommt auf Anhieb der korrekte Wert raus.

                Soweit/ sofern ich euch bisher richtig verstanden habe (und das entspricht auch meiner bisherigen Annahme) dürfte das aber gar nicht passieren. Denn der Browser blockt die weitere Ausführung des Skripts bis der Reflow abgeschlossen ist, und dann müsste das Skript ja genau an der Stelle fortgesetzt werden.

                Scheinbar "funkt" aber etwas dazwischen. Ich weiß aber langsam echt nicht mehr, was das noch sein sollte/ könnte!?

                Gruß Gunther

                1. Gar nicht. Und das behaupte ich solange, bis du mir den empirischen Gegenbeweis lieferst ;)

                  Nun hör' aber auf ...! :-P Soll ich dir einen Screenshot von meiner Konsole posten?

                  Wenn darin der fragwürdige Quelltext zu sehen ist, dann ja. Noch besser wäre es allerdings, du würdest uns den Quelltext in Textform und nicht als Screenshot präsentieren.

                  Ich habe schon fast alles andere rausgeschmissen und und und ..., aber wenn ich genau den Code in meiner Document Ready Funktion ausführe, kommt grundsätzlich (allso immer, in jedem Fall, zu 100%) derselbe (noch nicht korrekte) Wert dabei raus.

                  Dann dürftest du die Fehler ja nun ziemlich weit eingegrenzt haben. Gehe weiter so vor und irgendwann findest du den Fehler mit Sicherheit, hier sind mehrere Beteiligte im Thread unterwegs, die dir bei der Fehlersuche behilflich sein würden, so ginge es also noch schneller.

                  Verwende ich hingegen eine setTimeout Funktion (separat), kommt auf Anhieb der korrekte Wert raus.

                  Ja, das deutet nur ein weiteres mal darauf hin, dass der Fehler nicht in dem Run-To-Completion Codeblock stattfindet, den du uns hier gezeigt hast. Folglich muss der Fehler in einem anderen Run-To-Completion-Codeblock stecken, also einer Codeeinheit die später asynchron ausgeführt wird. Scanne deinen Code systematisch auf Event-Handler und asynchrone Callback-Funktionen.

                  Soweit/ sofern ich euch bisher richtig verstanden habe (und das entspricht auch meiner bisherigen Annahme) dürfte das aber gar nicht passieren. Denn der Browser blockt die weitere Ausführung des Skripts bis der Reflow abgeschlossen ist, und dann müsste das Skript ja genau an der Stelle fortgesetzt werden.

                  So ist es. Atomar ist das schöne Fachwort dafür, das mir die ganze Zeit über nicht einfallen wollte (Danke Camping_RIDER).

                  Scheinbar "funkt" aber etwas dazwischen. Ich weiß aber langsam echt nicht mehr, was das noch sein sollte/ könnte!?

                  Halte Ausschau nach Event-Handlern und asyncrhonen Callbacks. setTimeout(), setInterval(), die jQuery Event-Handler .ready(), .click(), .on(), AJAX-Anfragen usw. Dann analysiere die Callback Funktionen auf Operationen, die einen Reflow auslösen, also insbesondere DOM-Manipulationen. Achte besonders auf HTML-Klassen oder CSS-Attribute, die verändert werden, aber auch andere HTML-Attribute die verändert werden oder Elemente, die hinzukommen oder entfernt werden können eine Reflow auslösen.

                2. Nun hör' aber auf ...! :-P Soll ich dir einen Screenshot von meiner Konsole posten?

                  Das der Wert nicht der ist, den du erwartest glaubt Camping_RIDER dir.

                  Ich habe schon fast alles andere rausgeschmissen und und und ..., aber wenn ich genau den Code in meiner Document Ready Funktion ausführe, kommt grundsätzlich (allso immer, in jedem Fall, zu 100%) derselbe (noch nicht korrekte) Wert dabei raus.

                  Es kommt der zu diesem Zeitpunkt korrekte Wert raus.

                  Verwende ich hingegen eine setTimeout Funktion (separat), kommt auf Anhieb der korrekte Wert raus.

                  Wenn du setTimeout mit 0 ms aufrufst, ist die Wahrscheinlichkeit groß, daß der Wert sich im weiteren Verlauf der Document Ready Funktion(en) ändert.
                  Lass dir am Ende dieser (und evtl. weiterer) Document Ready Funktionen einfach den Wert nochmal ausgeben, dann kannst du das ganze erst mal eingrenzen.
                  Sollte doch noch ein anderer Eventhandler sich zw. Document Ready und dem Timeout quetschen, musst du zum Eingrenzen in allen Eventhandlern den Wert am Ende ausgeben lassen.

                  1. Bilder fallen mir noch ein, die sind bei Document Ready ja noch nicht geladen.

                    1. Bilder fallen mir noch ein, die sind bei Document Ready ja noch nicht geladen.

                      Die Bilder selber waren es zwar nicht, aber dennoch hat mich dein Beitrag auf die richtige Spur gebracht - besten Dank!

                      Gruß Gunther

  2. Ich habe ein (Div) Element, dessen Klassenattributwert ich per jQuery addClass() ändere. Aufgrund der entsprechenden Styleanweisungen im Stylesheet ändern sich dadurch die Abmessungen (Breite und Höhe) des Elements. Und diese sich neu ergebenden Abmessungen brauche ich in der Folge in meinem Script.

    Leider tritt hier eine gewisse zeitliche Verzögerung auf, denn eine unmittelbar folgende Abfrage im Skript liefert noch die ursprünglichen Werte zurück.

    1. hide().show() auf das Element
    2. setTimeOut(0)
  3. So, jetzt wird doch der Hund in der Pfanne verrückt ...! Es ist "natürlich" so, dass mein Problem in dem vereinfachten Beispiel nicht auftritt ...!

    Siehe DEMO

    Tja, dann verstehe ich nicht so ganz, wo der entscheidende Unterschied liegt, bzw. was in meinem Fall anders ist und das Problem verursacht!?

    Ich werde also weiter "forschen" müssen. Einstweilen schon mal meinen besten Dank für eure freundliche Unterstützung!

    Gruß Gunther

  4. Hallo alle zusammen!

    Nicht schlagen ..., ich hab' die Ursache für mein "Problem" gefunden, dank eurer hilfreichen Anregungen.

    Es hatte sich tatsächlich ein window.onload Handler "dazwischen gemogelt", der ebenfalls einen Reflow auslöst.

    Ohne diesen "funktioniert" es jetzt, bzw. liefert den korrekten Wert.

    Allerdings verstehe ich immer noch nicht so ganz, wie das möglich ist, wie sich ein asynchroner Task quasi genau zwischen die Ausführung des anderen Tasks "mogeln" kann?

    Oder anders gesagt, wenn das ja (offensichtlich) möglich ist, dann kann das ja zumindest theoretisch immer und überall passieren. Denn letztlich hat man ja keine Kontrolle darüber, wann bspw. irgendein Event-Handler zuschlägt oder nicht.

    Oder missverstehe ich da etwas?

    Gruß Gunther

    1. Aloha ;)

      Oder anders gesagt, wenn das ja (offensichtlich) möglich ist, dann kann das ja zumindest theoretisch immer und überall passieren. Denn letztlich hat man ja keine Kontrolle darüber, wann bspw. irgendein Event-Handler zuschlägt oder nicht.

      Oder missverstehe ich da etwas?

      Nein, so wie ich das sehe, hast du vollkommen Recht. Das kann immer passieren. Unter Umständen halt, so wie hier, auch an ungünstigen Stellen. Was mich irritiert ist eher ein bisschen der Umstand, dass der asynchrone onload-Handler immer am genau selben Zeitpunkt dazwischenfunkt. Da du aber ja immer denselben Aufruf mit denselben Randbedingungen tätigst, ist das schon irgendwie plausibel.

      Grüße,

      RIDER

      P.S.: Haue gibts keine, aber ein befriedigtes "habe ich doch gesagt" :D

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller Erreichbar manchmal im Self-TS (ts.selfhtml.org) oder sonst - wenn online - auf dem eigenen TeamSpeak-Server (fritz.campingrider.de) oder unter: # Facebook # Twitter # Steam # YouTube # Self-Wiki # ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
    2. Ich habe mir das nicht alles durchgelesen, ist mir zuviel, aber ich schreibe trotzdem mal was dazu.

      Allerdings verstehe ich immer noch nicht so ganz, wie das möglich ist, wie sich ein asynchroner Task quasi genau zwischen die Ausführung des anderen Tasks "mogeln" kann?

      Das kann dir immer und überall passieren. Hier vermute ich, deine Seite enthällt keine extra zu ladenden Elemente, wie z.B. Bilder. Das heißt, wenn das document fertig geparst ist ist auch alles geladen. Der Browser stellt beide events in die Queue. Wenn dein document.ready-Eventhandler abgearbeitet wird und ein Timeout mit 0 ms startet, feuert dieses Timeoutevent zwar sofort, da der Browser aber schon vorher sein window.load-Event gefeuert hat und dieses schon in der Queue steht, wird dein Eventhandler für den Timeout erst nach window.onload abgearbeitet.

      Oder anders gesagt, wenn das ja (offensichtlich) möglich ist, dann kann das ja zumindest theoretisch immer und überall passieren. Denn letztlich hat man ja keine Kontrolle darüber, wann bspw. irgendein Event-Handler zuschlägt oder nicht.

      Ja, das ist alles asynchron, aber es dürfte dich auch nicht interessieren, (workerthreads mal außen vor gelassen)da nichts parallel abgearbeitet wird und jeder Eventhandler vollständig abgearbeitet wird ehe der nächste gestartet wird. Du bist also immer konsistent, es sei denn du selbst hälst deine Daten nicht konsistent.
      Besorgst du dir hier Daten, die du an anderer Stelle benötigst? Dann ist das der Fehler. Besorge dir deine Daten dort, wo du sie brauchst, sonst bist du dazu gezwungen sie immer aktuell zu halten.