逐步解決動態添加樣式致使的元素閃爍

元素閃爍很醜,難解決。javascript

修改 Class 而不是 Style

我在不久前作過一個導航欄,要求其滾動到屏幕頂端後固定。很常見。開始的時候沒問題,很快就能夠搞定。css

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;
    }
});

運行很流暢。html

作好,我天然就忙着網頁內容去了。沒曾想,隨着頁面 JS 的不斷增長,導航欄在固定時出現了可怕的閃動。java

唔,就是 一下看得見 一下看不見 的東西!瀏覽器

應該有很多人和我同樣。百度,無果。谷歌,看不懂,翻譯也不行。
不知道真相的我,眼淚 流下來。翻譯

哦!一道莫名的亮光從個人眼前閃過!這道亮光裏,有但願,,有興奮,,組成了四個大字:code

元素重繪htm

就在這千萬分之一秒,億萬分之一秒 裏,我理解了:ip

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

這一句 JS 產生了兩次 DOM 寫入,影響瀏覽器渲染頁面兩次。rem

使用 $.addClass 語句能夠解決。

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;
    }
});

閃爍問題獲得了臨時解決。

採用不可見元素減小 DOM 變動產生的運算

「臨時」 說法的緣由是當 JS 數量再次增長,達到又一新高度後,閃爍問題再現。
緣由大概是 $.addClass 時瀏覽器須要從新計算該元素位置, JS 數量過多使計算過程明顯。
很少說,在 HTML 裏多放一個包含 .fixed 的寬高爲 0 的元素便可解決。

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

別讓這個 div.fixed 顯示出來。

至此,全面解決 「動態添加樣式致使的元素閃爍」 。

原生 JS 進一步加快速度避免閃爍

jQuery 是個好東西。原生 JS 更是個好東西。

有些 jQuery 代碼,被轉化爲好多條原生 JS 才實現效果。
然而其實只須要一條。
將 jQuery 代碼轉化爲原生 JS 是個加快速度,避免閃爍的不二選擇。

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;
    }
};

謝謝閱讀!

相關文章
相關標籤/搜索