Gradually solve the element flickering caused by dynamically adding styles

 

Element flickering is ugly and hard to fix.

Modify Class instead of Style

I made a navbar a while back and asked it to be fixed after scrolling to the top of the screen. very common. No problem in the beginning, it will be done in no time.

nav {
    position: absolute;
    top: 60px;
}
var scroll=0;
var nav=$("nav");
var navST=60; //该元素距离网页顶端60px
 $(window).scroll(function(){
    if($(document).scrollTop()>navST && scroll==0){
        nav.css({position: "fixed",top: "0"});
        scroll=1;
    }
    else if($(document).scrollTop()<=navST && scroll==1){
        nav.removeAttr("style");
        scroll=0;
    }
});

It runs smoothly.

Well done, I am naturally busy with the web content. Unexpectedly, as the JS of the page continues to increase, the navigation bar will flicker terribly when it is fixed.

Well, it's just to see what you can't see!

There must be many like me. Baidu, to no avail. Google, can't read, can't translate.
I, who didn't know the truth, burst into tears.

Oh! An inexplicable light flashed before my eyes! In this light, there is hope, and there is excitement, forming four big characters:

element repaint

In this ten-millionth, one-billionth of a second, I understood:

nav.css({position: "fixed",top: "0"});

This sentence of JS generates two DOM writes, which affects the browser rendering the page twice.

This can be solved using the $.addClass statement.

nav {
    position: absolute;
    top: 60px;
}
.fixed {
    position: fixed;
    top: 0;
}
var scroll=0;
var nav=$("nav");
var navST=60; //该元素距离网页顶端60px
 $(window).scroll(function(){
    if($(document).scrollTop()>navST && scroll==0){
        nav.addClass("fixed");
        scroll=1;
    }
    else if($(document).scrollTop()<=navST && scroll==1){
        nav.removeClass("fixed");
        scroll=0;
    }
});

The flickering issue has been temporarily resolved.

Use invisible elements to reduce the computation of DOM changes

The reason for the "temporary" statement is that the flickering problem reappeared when the amount of JS increased again, reaching another new height.
The reason is probably that the browser needs to recalculate the element position when $.addClass is used, and the calculation process is obvious due to the excessive amount of JS.
Needless to say, it can be solved by placing one more element with .fixed width and height in the HTML.

<div class="fixed"></div>
<nav>something...</nav>

Don't let this div.fixed show up.

At this point, the "element flickering caused by dynamically adding styles" has been fully solved.

Native JS further speeds up and avoids flickering

jQuery is a good thing. Native JS is even better.

Some jQuery code is converted into a lot of native JS to achieve the effect.
However, only one is needed.
Converting jQuery code to native JS is a great way to speed things up and avoid flickering.

var scroll=0;
var navST=60; //该元素距离网页顶端60px
 window.onscroll = function(){
    if(document.documentElement.scrollTop || document.body.scrollTop>navST && scroll==0){
        document.getElementsByTagName("nav")[0].classList.add("fixed");
        scroll=1;
    }
    else if(document.documentElement.scrollTop || document.body.scrollTop<=navST && scroll==1){
        document.getElementsByTagName("nav")[0].classList.remove("fixed");
        scroll=0;
    }
};

thanks for reading!

 

Original link: https://segmentfault.com/a/1190000006216880

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324887824&siteId=291194637