Masonry JS von DeSandro (Lösungscode inkl. Animation Post #39 bzw. #50 mit Overlay)

  • Das gute Ding steht jetzt. Nun versuch ich, Scroll-Effekte einzubauen. Ob das nun gut oder schlecht ist, sei mal dahingestellt. Ich möchte es halt gern ausprobieren und was dazulernen. Die Effekte 1 und 2 sind ja ganz annehmbar.

    Das ganze basiert auf li-Items. Hab schon Verschiedenes durchprobiert, noch läuft es nicht. In der AnimOnScroll.js sollen alle li-Items animiert werden. Ich hab das dort mal zu img geändert. Diese JS basiert auf der Classie.js, die dazu dienen soll, diverse CSS-Klassen hin- und herzutauschen. Daran scheint es bei mir zu scheitern. Ich sehe jedenfalls keine Bilder, da sie auf opacity:0 stehen, aber im ausgeführten Code auch keine Klassen. Original stehen in dem Demo-Code auch keine Klassen, absolut nix, wird alles über Classie geregelt.

    Ich hab das IMG dann auch wieder zu LI zurückgetauscht und sogar die original CSS eingebunden, alle JS natürlich auch. ID grid hab ich auch hinzugefügt, um das Script auszuführen, wobei getElementByClass ja auch gehen würde.

    Meine Vorgehensweise wäre eig, den Grundstock zu übernehmen und dann Schritt für Schritt zu ändern.


    Bevor ich also hier nochmal einen Link poste, probiere ich noch ein Weilchen.



    //

    So, nun bin ich tatsächlich weitergekommen. Die Animation funktioniert, dafür ist jetzt mein ganzes Raster nicht mehr das, was es war. Das liegt jetzt wahrscheinlich an den LI. Dazu gibt's im AnimOnScroll 2 Einträge, die ich durch IMG ersetzen möchte. Zudem will ich hier ( '#' + this.el.id + ' li ' ) ) eig auch nicht mit IDs, sondern mit Klassen arbeiten. In Zeile 100 gibt's nochmal ein LI. Im CSS habe ich dann auch alle LI durch IMG ersetzt. Aber so einfach scheint das leider nicht zu sein. Ich würd schon gern bei meinen .grid-items bleiben ohne LI, also mein Original-Masonry-Gerüst beibehalten und die Skripten daran anpassen. Am Ende möchte ich dann nur noch <div id="container" class="grid effect-1"> stehen haben. Also die Animation über die Klasse triggern.


    Was der Modernizr damit zu tun hat, hab ich noch nicht rausgefunden. Aber ohne ihn läuft die Animation nicht.

    Warum die Bildgröße nur noch bei jedem x-ten Bild passt, weiß ich auch nicht, aber das ist am Ende ws nicht das Problem, weil ich das bestimmt von selbst löst, wenn die LI weg sind.


    Das hier ist nun der letzte Zustand, an dem die Animation funktioniert hat. Jetzt steh ich an.

  • Guten Morgen Elly,

    wenn ich auf deine Version einen Blick werfe, frage ich mich als erstes, warum Du nicht genau die HTML-Struktur verwendest wie in dem Beispiel für die Scrolleffekte? Also ein ul mit lis darin und keine weiteren div-Container. So wundert es nicht, dass es nicht funktioniert.

    Masonry dürfte es egal sein, ob die Elemente, die positioniert werden müssen, divs oder lis sind - das Beispiel bei den Scroll-Effekten funktioniert ja.


    Zitat

    Was der Modernizr damit zu tun hat, hab ich noch nicht rausgefunden. Aber ohne ihn läuft die Animation nicht.

    Mit Modernizr kann man überprüfen, ob ein bestimmtes Feature verfügbar ist, in diesem Fall die CSS-Animationen:

    if( Modernizr.cssanimations ) {

    Wird Modernizr nicht eingebunden, kommt es an dieser Stelle zu einem Laufzeitfehler und das ganze Skript bricht ab und ist unwirksam.

  • Richtig. Masonry ist es egal welche HTML-Container verwendet werden.


    In diesem Fall verweist der Seitenersteller aber im CSS und wohl auch im JavaScript (id + ' > li)? auf li Elemente. Die dürfen sich nach den HTML-Regeln wiederum nur direkt in ul- oder ol-Elementen befinden. Von daher ist der Aufbau mit ul + li- Elementen ohne Änderungen im CSS und JavaScript hier zwingend.


    div-Elemente sind zudem nach den HTML-Regeln direkt als Kindelemente von ul-Elementen nicht zulässig. Die Browser versuchen zwar jeden Mist-Quellcode irgendwie vernünftig anzuzeigen, trotzdem kann man jede Menge Ärger vermeiden, wenn der Quellcode nach den HTML- und CSS-Regeln erstellt wird.


    Von daher solltest du erst mal die Seiten komplett runterladen, so dass die auf deinem Rechner funktionieren. Die Dateien dann vom unnötigen Ballast befreien und den Rest sinnvoll sortieren und strukturieren. Dabei dann auch schon mal ein paar eigene Bilder zum Testen einfügen. Und zum Beispiel Klassen sinnvoll umbenennen. Dabei immer wieder kontrollieren ob die Seite noch funktioniert. Dann bleiben im Endeffekt nur die notwendigen Quellcodes übrig, die sich dann deutlich einfacher in die eigene Webseite einbauen lassen.

  • So wie Murphy das beschreibt, hab ich das eig auch gemacht. Nur eben umgekehrt. Ich wollte das CSS und das JS anpassen und nicht meine Mansory-Konfiguration.

    Die Animation-Seite verwendet auch Masonry 3, sie hat auch keinerklei Klassen oder sonst was drinstehen, ich hab noch nichtmal gefunden, wo sie ihr Masonry überhaupt triggert.


    Es sollte eig funktionieren, das JS anzupassen. Wenn das dann klappt, müsste man im CSS eig nur LI durch IMG ersetzen.


    Wenn ich dann noch Bildbeschreibungen hinzufüge und eine Lightbox einbaue, werd ich wohl auch DIVs brauchen. Und die will/kann ich ja dann nicht in die LIs einbauen.

  • Zitat

    ich hab noch nichtmal gefunden, wo sie ihr Masonry überhaupt triggert.

    Das haben sie in animOnScroll.js eingebaut, ab Zeile 98:

    Code
                    // initialize masonry
                    new Masonry( self.el, {
                        itemSelector: 'li',
                        transitionDuration : 0
                    } );

    Wie Du siehst ist dort der Selektor 'li' fest eingebrannt.

  • Ja, das schon. Und an einer anderen Stelle auch. Ersetze ich das dort durch IMG, funktioniert das aber noch nicht. Das ist es ja...ich dachte, es wär ganz einfach, die bestimmten Stellen zu ersetzen, aber irgendwo versteckt sich wohl was.


    Hab jetzt mal deinen Tipp befolgt und mein Masonry in eine Liste verwandelt. Das klappt. Ander's wär's mir lieber gewesen.

    Dargestellt wird es allerdings noch nicht ganz richtig, als würde der Imageloader jetzt streiken. Ich hab's so eingestellt, dass ich 6 Bilder nebeneinander krieg. Jetzt zu finden unter anim4. Lädt die Seite, sind da 6 Bilder nebeneinander, aber falsch geladen (zT übereinander). Aktualisier ich dann, sind die Bilder richtig geladen, aber nur noch 5 nebeneinander. Da muss ich mal schauen, ob da irgendwo jetzt Abstände durch die LI dazugekommen sind. Aber laden sollte derSpaß natürlich schon vernünftig.


    PS:

    Er scheint richtig zu laden, wenn die class grid nur bei UL vorkommt und ausm DIV raus ist. Coole Sache! :)

    Der .grid war noch ein padding 0 hinzuzufügen, jetzt stimmt auch die Anzahl der Bilder wieder.


    Meint ihr, das ist jetzt problematisch, dass das eine Liste ist anstatt mit DIVs verarbeitet?

  • So, hier nochmal ein Versuch mit der DIV-Variante. Funktioniert leider noch nicht. Relevant im JS sind mMn nur Z89 und Z100. Da hab ich jetzt einiges durchprobiert, ich kriegs aber noch nicht hin. Letzten Endees übergibt der Classie noch nicht die nötigen Klassen.

    Im CSS sieht's so aus, dass es mit .grid-item div die Bilder gleich anzeigt und mit .grid div alles auf transparent steht. Verstehen tu ich das aber nicht, da ich damit doch die gleichen DIVs anspreche? Innerhalb von .grid und von .grid-item sind ja dieselben DIVs.


    Im JS der HTLM-Seite hab ich nun auch Class statt ID drinnen.

  • Vorweg: Ich habe keine Ahnung von JavaScript und habe es ähnlich wie du versucht, halt etwas im Nebel gestochert. Meine Ergebnisse dazu sind folgende (mit Fachbegriffen in Programmiersprachen kenne ich schon gar nicht aus, deshalb verwende ich die wahrscheinlich falsch):


    Zitat

    Im JS der HTLM-Seite hab ich nun auch Class statt ID drinnen.


    Nein, hast du nicht.


    Offensichtlich hast du


    Code
    .getElementById


    durch


    Code
    .getElementByClass


    ersetzt. Problem: .getElementById gehört zur JavaScript Programmiersprache, .getElementByClass gibt es nicht. Um Klassen anzusprechen gibt es


    Code
    .getElementsByClassName


    Damit funktioniert es aber auch nicht. Hintergrund ist wohl dass bei

    Code
    .getElementById


    genau eine Antwort zurückgegeben wird, bei


    Code
    .getElementsByClassName


    jedoch immer eine Matrix?, also ein Antwortgitter, auch wenn die Klasse nur einmal im Quelltext vorkommen sollte. Das Programm erwartet aber nur eine Antwort, keine Matrix.


    Das sind meine laienhaften Erkenntnisse.

  • Du meinst, es wird nur 1 Klasse verlangt, aber wenn da 2 stehen, werden automatisch beide genommen und dann klappt's nicht?

    Hab das nochmal mit ID durchgespielt, klappt aber auch nicht.


    Dann hab ich's auf className umgeschrieben. Ich meine jetzt vl was besser gemacht zu haben, funktionieren tut's noch immer nichtl

  • Eine Problemursache solltest Du als erstes beheben: Du fährst da zweigleisig, einmal wird masonry in animOnScroll.js initialisiert und außerdem in deiner HTML-Datei, einschl. imagesLoaded. Dann ist kaum vorhersagbar, wie das Resultat ist, auf jeden Fall braucht es nicht zu verwundern, wenn etwas nicht funktioniert.

  • Das ging mir auch schon durch den Kopf. Allerdings funktioniert es in der LI-Variante trotzdem. Ich hab schon versucht, den nötigen Code aus meiner HTML in die JS zu setzen, allerdings sind die Bilder dann alle nur untereinander. Und in der JS muss es ja vorkommen, da der andere Code davon abhängig ist.

    Hab das gern jetzt so auch nochmal raufgeladen.


    Der Fehler muss irgendwo im Zusammenspiel mit JS und Classie sein bzw. an der Bezeichnung in den gennanten JS-Zeilen und im CSS-Code. Den Tags werden die animated-Klassen nicht übergeben. Da muss was falsch bezeichnet sein und ich finde es nicht.

  • Jetzt ist es in der animOnScroll.js und dort haben wir ja noch ein Problem mit dem Selektor. Der Container für die Galerie hat ja die ID "container" und wir können bei getElementById bleiben und das Element so ermitteln:

    Code
            new AnimOnScroll( document.getElementById( 'container' ), {
                minDuration : 0.4,
                maxDuration : 0.7,
                viewportFactor : 0.2
            } );

    In der animOnScroll.js hast Du ja .item für Masonry verwendet und das sollte passen.

    Und bei der Ermittlung der Items hast Du es von li auf div geändert:

    this.items = Array.prototype.slice.call( document.querySelectorAll( '.' + this.el.className + ' > div' ) );

    Allerdings könnte es Probleme machen, dass das Element zwei Klassen hat. Mal abwarten, teste es so und wenn es nicht funktioniert, sehen wir weiter.

    Möglicher Weise wäre es besser, es gleich so zu machen:

    this.items = Array.prototype.slice.call( this.el.querySelectorAll( 'div.grid-item' ) );

    Das verschlechtert zwar die Wiederverwendbarkeit aber beim Masonry haben wir auch schon .grid-item fest eingebrannt.

  • Das mit 1 und 2 Klassen hatte ich schon mal durchprobiert, mit einem neuen DIV um die grid-items, funktioniert hat's nicht.

    Aber, das Gute ist schon mal: Das Masonry läuft wieder, seit ich den Code oben mit container geändert hab. Der zweite Tipp bringt tatsächlich auch die Klasse mit! Yessss, endlich! Die Animation klappt noch nicht, da hab ich sicher was an den CSS-Selektoren verbockt.


    Ich hatte übrigens folgendes auch schon ausprobiert, aber da hat es noch keine Klasse geliefert. Wahrscheinlich weil das mit container nicht drin war. Jetzt klappt das so auch.

    Code
    this.items = Array.prototype.slice.call( document.querySelectorAll( 'div.grid-item' ) );
  • Soooo, gut Ding braucht echt Weile! Danke! Der ausschlaggebende Tipp war tatsächlich ID container anzusprechen. Interessant, solche Dinge habe ich vorher alle durchprobiert, nur container nicht. Extra DIVs erstellt usw... Und am Ende ist es eine bestimmte Kombi, die es dann ausmacht.


    Jetzt bin ich happy! Das normale Masonry braucht man also für die Animation nicht umzuschreiben, sondern nur zu ergänzen. Das war das Ziel.

    Ich teil mal hier den Code und das Package.


  • Ich hab's jetzt nochmal upgedated. Mich hat container gestört, da steht jetzt gallery. Jmd anderes hat #container vl schon anderweitig verbaut.

    Nachdem wir dafür jetzt die richtige ID haben, wäre sogar das möglich, was ich scon 100x durchgespielt hab.


    Code
    this.items = Array.prototype.slice.call( document.querySelectorAll( '#' + this.el.id + ' div ' ) );


    this.el.id ist jetzt nämlich container bzw. neu gallery und das ganze ist ein div. In der LI-Variante war da ja noch ' > li ' - also war dem LI das UL übergeordnet und das hatte die ID grid im Original. Mit Klasse statt ID geht's tatsächlich nicht, da stört die 2. Klasse effect-1 dann.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!