• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

$(window).scroll() zu langsam auf Touchscreens?

Chronos

Aktives Mitglied
Hallo Forum,

ich bin gerade dabei das Verhaltens des "Beitrag schreiben"-Buttons aus der Google Plus App nachzubauen.

8vxr1u2.png

Dieser macht folgendes;
scrollt man nach unten, wird er ausgeblendet (so verdeckt er beim stöbern keinen Inhalt),
scrollt man nach oben, wird er eingeblendet.

Ich habe eine Funktion über die per jQuery animate den bottom Wert des Buttons setze und eine die das scrollen abfängt.

Aber irgendwie ist das nicht besonders fix oder "smooth", das fällt besonders dann auf, wenn ich nach unten scrolle und dann direkt wieder hoch - im Chrome kann man ja angeschlossene Geräte und deren Tabs im Browser untersuchen und zu sehen ist, dass noch gerechnet wird also erst mal auf den Stand ausgeblendet und wenn das fertig ist, einblenden.

In meinem Fall ist das evtl. sowieso nicht so optimal gelöst, ich will ja nur einmal das Event auslösen, so wie ich das jetzt mache, wird es ja so oft wie man scrollt aufgerufen.

Egal ich zeige euch mal meinen Code, vllt. fällt uns ja was gescheites dazu ein.

JavaScript:
Code:
// IIFE - Immediately Invoked Function Expression
(function($, window, document) {
    // Listen for the jQuery ready event on the document
    $(function() {
        // The DOM is ready
        var btn_floating        = $('#btn-floating');
      
        var previousScroll = 0;
         // Den Code findet man so im Netz, ich glaub aber sehr viel anders würde man es eh nicht schreiben ;)
        $(window).scroll(function() {
           var currentScroll = $(this).scrollTop();
         
           if (currentScroll > previousScroll){     
               setBtnFloatingPosition(btn_floating, "-100%", 500);
           }
           else {    
              setBtnFloatingPosition(btn_floating, "100", 100);
           }
         
           previousScroll = currentScroll;
        });
    });
  
    // Bottom-Position des Buttons setzen
    function setBtnFloatingPosition(element, bottomValue, time) {
        element.animate({
            bottom: bottomValue,                  
        }, time);
    };

}(window.jQuery, window, document));

CSS:
Code:
a {
    text-decoration: none;
    color: #000;
}

.btn {
    display: block;
    position: fixed;
    left: 10px;
    bottom: 100px;
  
    border: 1px solid #000;
    border-radius: 100%;
    width: 150px;
    height: 150px;
  
    background: rgb(220, 220, 220);
}

.content-wrapper {
    margin: 20px auto;
    width: 240px;
    height: 3000px;
    border: 1px solid gray;
}

und noch das bissl HTML dazu:
HTML:
<!DOCTYPE html>
<html lang="de">
    <head>
        <link rel="stylesheet" type="text/css" href="./floating-button.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script src="./floating-button.js"></script>
    </head>

    <body>
        <div class="content-wrapper"></div>
      
        <a id="btn-floating" class="btn"></a>
    </body>
</html>

Das ganze schaue ich mir übrigens am Nexus 5 im Chrome und parallel dazu im Chrome Desktop / Remote an.

Hat so was schon mal jemand gemacht und kann mir helfen?

Edit: jetzt mit JSFiddle, auch wenn ich es da nicht so gut nachvollziehbar finde http://jsfiddle.net/Chronos90/mteve5ns/
 
Werbung:
Hallo Forum,

ich bin gerade dabei das Verhaltens des "Beitrag schreiben"-Buttons aus der Google Plus App nachzubauen.

8vxr1u2.png

Dieser macht folgendes;
scrollt man nach unten, wird er ausgeblendet (so verdeckt er beim stöbern keinen Inhalt),
scrollt man nach oben, wird er eingeblendet.

Ich habe eine Funktion über die per jQuery animate den bottom Wert des Buttons setze und eine die das scrollen abfängt.

Aber irgendwie ist das nicht besonders fix oder "smooth", das fällt besonders dann auf, wenn ich nach unten scrolle und dann direkt wieder hoch - im Chrome kann man ja angeschlossene Geräte und deren Tabs im Browser untersuchen und zu sehen ist, dass noch gerechnet wird also erst mal auf den Stand ausgeblendet und wenn das fertig ist, einblenden.

In meinem Fall ist das evtl. sowieso nicht so optimal gelöst, ich will ja nur einmal das Event auslösen, so wie ich das jetzt mache, wird es ja so oft wie man scrollt aufgerufen.

Egal ich zeige euch mal meinen Code, vllt. fällt uns ja was gescheites dazu ein.

JavaScript:
Code:
// IIFE - Immediately Invoked Function Expression
(function($, window, document) {
    // Listen for the jQuery ready event on the document
    $(function() {
        // The DOM is ready
        var btn_floating        = $('#btn-floating');
   
        var previousScroll = 0;
         // Den Code findet man so im Netz, ich glaub aber sehr viel anders würde man es eh nicht schreiben ;)
        $(window).scroll(function() {
           var currentScroll = $(this).scrollTop();
      
           if (currentScroll > previousScroll){  
               setBtnFloatingPosition(btn_floating, "-100%", 500);
           }
           else { 
              setBtnFloatingPosition(btn_floating, "100", 100);
           }
      
           previousScroll = currentScroll;
        });
    });

    // Bottom-Position des Buttons setzen
    function setBtnFloatingPosition(element, bottomValue, time) {
        element.animate({
            bottom: bottomValue,               
        }, time);
    };

}(window.jQuery, window, document));

CSS:
Code:
a {
    text-decoration: none;
    color: #000;
}

.btn {
    display: block;
    position: fixed;
    left: 10px;
    bottom: 100px;

    border: 1px solid #000;
    border-radius: 100%;
    width: 150px;
    height: 150px;

    background: rgb(220, 220, 220);
}

.content-wrapper {
    margin: 20px auto;
    width: 240px;
    height: 3000px;
    border: 1px solid gray;
}

und noch das bissl HTML dazu:
HTML:
<!DOCTYPE html>
<html lang="de">
    <head>
        <link rel="stylesheet" type="text/css" href="./floating-button.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script src="./floating-button.js"></script>
    </head>

    <body>
        <div class="content-wrapper"></div>
   
        <a id="btn-floating" class="btn"></a>
    </body>
</html>

Das ganze schaue ich mir übrigens am Nexus 5 im Chrome und parallel dazu im Chrome Desktop / Remote an.

Hat so was schon mal jemand gemacht und kann mir helfen?

Edit: jetzt mit JSFiddle, auch wenn ich es da nicht so gut nachvollziehbar finde http://jsfiddle.net/Chronos90/mteve5ns/

Habe es mir jetzt nicht genau angeschaut aber vielleicht kannst du es mal mit CSS3 Transitions und add/removeClass versuchen.
Denke dass aus Leistungsgründen während dem Scrollen JavaScript basierte Style-Anweisungen niedriger priorisiert werden - aber das ist nur eine Vermutung :)

Achja, sollte im Beispiel nicht ein element.stop(true) vor animate kommen, da sonst ja die queue verstopft wird ;)
 
Zuletzt bearbeitet:
Werbung:
Ok, hat mich jetzt doch noch interessiert...

http://jsfiddle.net/mteve5ns/2/ // edit

haha :D hm auf die Idee mit der Transition hätte ich ja auch selbst noch kommen müssen.
Naja so gesehen lag ich ja nicht falsch, nur die Art wie animate arbeitet, scheint komisch :D.

Hast du noch eine Idee wie man es so schreiben könnte, dass das Scroll Event nicht unnütz angesprochen wird?
Ich meine wenn der Button schon da ist und ich nach oben scrolle, dann muss es ja nicht jedes mal die Abfrage erneut starten.

Ansonsten danke schon mal :)
 
haha :D hm auf die Idee mit der Transition hätte ich ja auch selbst noch kommen müssen.
Naja so gesehen lag ich ja nicht falsch, nur die Art wie animate arbeitet, scheint komisch :D.

Hast du noch eine Idee wie man es so schreiben könnte, dass das Scroll Event nicht unnütz angesprochen wird?
Ich meine wenn der Button schon da ist und ich nach oben scrolle, dann muss es ja nicht jedes mal die Abfrage erneut starten.

Ansonsten danke schon mal :)

Du könntest dir mit setTimeout oder setInterval etwas zusammen basteln, aber ich wüsste nicht wieso?
An der Performance ändert das nichts.
 
Du könntest dir mit setTimeout oder setInterval etwas zusammen basteln, aber ich wüsste nicht wieso?
An der Performance ändert das nichts.
Na gut das wär dann quatsch, hm nee ich dacht halt nur, den riesen Unterschied wird es da wohl nicht ausmachen.
Jetzt muss ich das nur noch bissl feintunen aber so passt es ja erstmal
 
Werbung:
Dafür gibt es ein Plugin, mir fällt aber der Name gerade nicht ein.

Scroll und Resize Events sind Performance Killer. :)
 
Setze die Class nur neu wenn sich der Zustand ändert und mach das ganze nativ. Der Event wird natürlich trotzdem sehr oft gefeuert, aber das kostet dann kaum noch performance, weil meistens fast nichts passiert.

Code:
var btn_floating = document.getElementById('btn-floating');
var isUp = true;        
var previousScroll = 0;

window.onscroll = function() {
    var currentScroll = window.pageYOffset != undefined?window.pageYOffset:document.documentElement.scrollTop || document.body.scrollTop || 0;
    var goUp =  currentScroll > previousScroll;
    if (goUp && isUp ){      
        btn_floating.className = btn_floating.className + " hide";
        isUp = false;
    }
    else if(!goUp && !isUp){        
        btn_floating.className = btn_floating.className.replace("hide","")
        isUp = true;
    }
    previousScroll = currentScroll;
};
 
Setze die Class nur neu wenn sich der Zustand ändert und mach das ganze nativ. Der Event wird natürlich trotzdem sehr oft gefeuert, aber das kostet dann kaum noch performance, weil meistens fast nichts passiert.

Code:
var btn_floating = document.getElementById('btn-floating');
var isUp = true;       
var previousScroll = 0;

window.onscroll = function() {
    var currentScroll = window.pageYOffset != undefined?window.pageYOffset:document.documentElement.scrollTop || document.body.scrollTop || 0;
    var goUp =  currentScroll > previousScroll;
    if (goUp && isUp ){     
        btn_floating.className = btn_floating.className + " hide";
        isUp = false;
    }
    else if(!goUp && !isUp){       
        btn_floating.className = btn_floating.className.replace("hide","")
        isUp = true;
    }
    previousScroll = currentScroll;
};

Sieht auch noch mal interessant aus. Ich denke aber, da ich eh noch hier und da jQuery "brauchen" werde, dass ich bei der Variante bleibe.
Die Variable zu setzen, ob schon nach oben gescrollt wurde oder nicht ist aber eine gute Idee.
 
Werbung:
Ich denke aber, da ich eh noch hier und da jQuery "brauchen" werde
Ja, ich nutze jQuery auch und möchte nicht darauf verzichten. Aber wenn der Code fertig ist und es Gründe zur Performanceoptimierung gibt, ist es meist kein Problem, Teile davon wieder auf natives Script herunter zu brechen. Je nach Komplexität des Codes lassen sich so einige 100% Geschwindigkeit herausholen.
 
Ja, ich nutze jQuery auch und möchte nicht darauf verzichten. Aber wenn der Code fertig ist und es Gründe zur Performanceoptimierung gibt, ist es meist kein Problem, Teile davon wieder auf natives Script herunter zu brechen. Je nach Komplexität des Codes lassen sich so einige 100% Geschwindigkeit herausholen.
Jup stimmt, aber das ganz ganz zum Schluss :D
 
Zurück
Oben