国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

解決頁(yè)面滾動(dòng)時(shí)吸頂操作不能及時(shí)響應(yīng)bug

gaomysion / 851人閱讀

摘要:這個(gè)界限就是該元素頂部距離窗口頂部的距離等于該元素設(shè)置的值比如以下像素分割線當(dāng)我的頂部距離窗口頂部為值時(shí),我就會(huì)像一樣在距離窗口值處的時(shí)代發(fā)送分效果圖當(dāng)頁(yè)面滾動(dòng)到距離黃色區(qū)塊頂部時(shí),黃色區(qū)塊就會(huì)在窗口頂部處,頁(yè)面再往下滾動(dòng)距離也不會(huì)變。

position: sticky;

fixed 吸頂

頁(yè)面滾動(dòng)結(jié)束后頁(yè)面才渲染

需求

經(jīng)常會(huì)有這樣的需求,當(dāng)頁(yè)面滾動(dòng)到某一個(gè)位置fixedTopValue時(shí),需要某個(gè)元素fixedElement固定在屏幕頂部。基本方法是獲取頁(yè)面的scrollTop值做判斷:
如果 scrollTop > fixedTopValue; 則添加position:fixed;top: 0;否則刪除position:fixed;屬性。

當(dāng)在pc瀏覽器操作的時(shí)候正常。真機(jī)測(cè)試時(shí)總會(huì)出現(xiàn)千奇百怪的現(xiàn)象。比如:
1、 當(dāng)頁(yè)面往下滾時(shí),fixedElement需要等頁(yè)面滾動(dòng)停止之后才會(huì)出現(xiàn)。
2、往上滾動(dòng)時(shí)出現(xiàn)到固定的位置時(shí)不恢復(fù)原樣,而是到達(dá)頂部、等頁(yè)面停止?jié)L動(dòng)之后才會(huì)唰的一下恢復(fù)原樣
3、滾動(dòng)到頂部之后,會(huì)出現(xiàn)兩個(gè)一樣的fixedElement, 過(guò)一會(huì)才恢復(fù)正常。
這樣的用戶體驗(yàn)真的很差,所以迫切需要解決這個(gè)問(wèn)題。

解決方法主要涉及一下三個(gè)方面
1、使用新的定位屬性 position: sticky; (如果支持)
2、如果不支持1,使用window.requestAnimationFrame方法確保改變定位屬性在固定時(shí)間內(nèi)執(zhí)行一次
3、 給fixedElement開(kāi)啟硬件加速

基本邏輯如下圖:

測(cè)試頁(yè)面二維碼:

position:sticky是個(gè)什么鬼?

對(duì)與css的position屬性我們只知道有static、relative、absolute、fixed這四個(gè)值,什么時(shí)候又多出了sticky這個(gè)值。看下MDN文檔解釋

Sticky positioning
Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.

大概意思是:sticky定位時(shí)relative定位與fixed定位的混合體。對(duì)于設(shè)置了sticky定位的元素,在它的頂部到達(dá)一個(gè)指定的界限之前會(huì)被當(dāng)作relative定位,超過(guò)這個(gè)界限字后則被當(dāng)作fixed定位。這個(gè)界限就是 該元素頂部距離窗口頂部的距離等于該元素設(shè)置的top值
比如以下demo:

60像素分割線
當(dāng)我的頂部距離窗口頂部為10px(top值)時(shí),我就會(huì)像fixed一樣fixed在距離窗口10px(top值處)
sticky的co時(shí)代發(fā)送分ntent
.top{height:60px;background:#f20;width:100%;color: #fff;font-size:16px;text-align:center;line-height:60px;}
.sticky{position:sticky;position:-webkit-sticky;top:10px;height:40px;background:#dd5;color:#fff;line-height:20px;text-align:center;}
.sticky-t10{top:0px;}
.content{height:1000px;width:100%;background:#f8f8f8;text-align:center;padding-top:40px;color:#333;}

效果圖:

當(dāng)頁(yè)面滾動(dòng)到距離黃色區(qū)塊頂部10px時(shí),黃色區(qū)塊就會(huì)fixed在窗口頂部10px處,頁(yè)面再往下滾動(dòng)距離也不會(huì)變。當(dāng)頁(yè)面網(wǎng)上滾動(dòng)時(shí),頁(yè)面頂部距離黃色區(qū)塊頂部大于10px時(shí),黃色區(qū)塊又會(huì)恢復(fù)原樣固定在原來(lái)的位置。

position:sticky這個(gè)屬性并不會(huì)出現(xiàn)當(dāng)頁(yè)面滾動(dòng)停止之后才會(huì)出現(xiàn)的bug,因?yàn)樗旧砭褪菍儆谡A鳌2⒉粫?huì)像fixed 與static相互切換時(shí)引起重排于重繪,而移動(dòng)端瀏覽器滾動(dòng)時(shí)是禁止重排跟重繪的,所以才會(huì)導(dǎo)致以上出現(xiàn)的問(wèn)題。下圖是對(duì)于position:sticky的支持情況:

發(fā)現(xiàn)支持的瀏覽器一般般,但是經(jīng)過(guò)測(cè)試像微信、safari、uc等瀏覽器是支持的,雖然chrome不支持,但是在chrome使用優(yōu)化后的fixed定位也可以解決這個(gè)問(wèn)題,基本能滿足主流的瀏覽器就夠了,其他的見(jiàn)鬼去吧。

滾動(dòng)時(shí)減少性能損耗,強(qiáng)制觸發(fā)瀏覽器的同步布局

如果瀏覽器不支持position:sticky,那么就使用js動(dòng)態(tài)的在節(jié)點(diǎn)在fixed定位于static定位中切換,但是需要對(duì)切換過(guò)程做一些優(yōu)化。
1、使用函數(shù)節(jié)流防抖減少dom操作頻繁粗發(fā),但是保證在規(guī)定時(shí)間內(nèi)必須執(zhí)行一次。
2、使用window.requestAnimationFrame 方法在下一幀前觸發(fā)瀏覽器的強(qiáng)制同步布局,是對(duì)dom的操作能及時(shí)渲染到頁(yè)面上。
3、減少對(duì)dom的讀寫操作,或者把dom操作把讀、寫操作分開(kāi),可以減少渲染次數(shù)。

給需要定位的元素開(kāi)啟硬件加速

由于移動(dòng)設(shè)備的硬件限制,導(dǎo)致移動(dòng)端的瀏覽器的渲染能比較差。此時(shí)對(duì)需要定位的元素開(kāi)啟硬件加速,會(huì)把需要渲染的元素放到特定的復(fù)合層『Composited Layer』中,當(dāng)該元素改變時(shí)可以較少重繪或重排的范圍。給元素添加 transform: translateZ(0);屬性就行。

參考:

硬件加速:
http://div.io/topic/1348
http://www.cnblogs.com/shyton...
提升頁(yè)面性能:
https://developer.mozilla.org...
http://www.ruanyifeng.com/blo...
http://www.jianshu.com/p/a32b...

具體實(shí)現(xiàn)請(qǐng)參考以下jquery版本的代碼:

//jquery
(function() {
    function Sticky(){
        this.init.apply(this, arguments);
    }

    /**
     * 滾動(dòng)fixed組件初始化
     * @param {object}         setting                allocate傳進(jìn)來(lái)的參數(shù)
     * @param {object}         setting.stickyNode     需要設(shè)置position:sticky的節(jié)點(diǎn),通常是最外層
     * @param {object}         setting.fixedNode      當(dāng)滾動(dòng)一定距離時(shí)需要fixed在頂部的節(jié)點(diǎn)
     * @param {int}            setting.top            fixed之后距離頂部的top值
     * @param {int}            setting.zIndex         fixed之后的z-index值
     * @param {string}         setting.fixedClazz     fixed時(shí)給fixedNode添加的類
     * @param {function}     setting.runInScrollFn  滾動(dòng)期間額外執(zhí)行的函數(shù)
     * @return {void}  
     */
    Sticky.setting = {
        stickyNode: null,
        fixedNode: null,
        top: 0,
        zIndex: 100,
        fixedClazz: "",
        runInScrollFn: null
    };
    var sPro = Sticky.prototype;
    var g = window;

    /**
     * 初始化
     * @param  {object} options 設(shè)置
     * @return {void}         
     */
    sPro.init = function(options){
        this.setting = $.extend({}, Sticky.setting, options, true);
        if (options.fixedNode) {
            this.fixedNode = options.fixedNode[0] || options.fixedNode;
            this.stickyNode = options.stickyNode[0] || options.stickyNode;
            this.cssStickySupport = this.checkStickySupport();
            this.stickyNodeHeight = this.stickyNode.clientHeight;
            this.fixedClazz = options.fixedClazz;
            this.top = parseInt(options.top, 10) || 0;
            this.zIndex = parseInt(options.zIndex) || 1;
            this.setStickyCss();
            this.isfixed = false;
            // 把改變定位的操作添加到節(jié)流函數(shù)與window.requestAnimationFrame方法中,確保一定事件內(nèi)必須執(zhí)行一次
            this.onscrollCb = this.throttle(function() {
                this.nextFrame(this.sticky.bind(this));
            }.bind(this), 50, 100);
            this.initCss = this.getInitCss();
            this.fixedCss = this.getFixedCss();
            this.addEvent();
        }
    };

    /**
     * 獲取原始css樣式
     * @return {string} 定位的樣式
     */
    sPro.getInitCss = function() {
        if (!!this.fixedNode) {
            return "position:" + this.fixedNode.style.position + ";top:" + this.fixedNode.style.top + "px;z-index:" + this.fixedNode.style.zIndex + ";";
        }
        return "";
    };

    /**
     * 生成fixed時(shí)的css樣式
     * @return {void}
     */
    sPro.getFixedCss = function() {
        return "position:fixed;top:" + this.top + "px;z-index:" + this.zIndex + ";";
    };

    /**
     * 給fixedNode設(shè)置fixed定位樣式
     * @param {string} style fixed定位的樣式字符串
     */
    sPro.setFixedCss = function(style) {
        if(!this.cssStickySupport){
            if (!!this.fixedNode){
                this.fixedNode.style.cssText = style;
            }
        }
    };

    /**
     * 檢查瀏覽器是否支持positon: sticky定位
     * @return {boolean} true 支持 false 不支持
     */
    sPro.checkStickySupport = function() {
        var div= null;
        if(g.CSS && g.CSS.supports){
            return g.CSS.supports("(position: sticky) or (position: -webkit-sticky)");
        }
        div = document.createElement("div");
        div.style.position = "sticky";
        if("sticky" === div.style.position){
            return true;
        }
        div.style.position = "-webkit-sticky";
        if("-webkit-sticky" === div.style.position){
            return true;
        }
        div = null;
        return false;
    };

    /**
     * 給sticyNode設(shè)置position: sticky定位
     */
    sPro.setStickyCss = function() {
        if(this.cssStickySupport){
            this.stickyNode.style.cssText = "position:-webkit-sticky;position:sticky;top:" + this.top + "px;z-index:" + this.zIndex + ";";
        }
    };

    /**
     * 監(jiān)聽(tīng)window的滾動(dòng)事件
     */
    sPro.addEvent = function() {
        $(g).on("scroll", this.onscrollCb.bind(this));
    };

    /**
     * 讓函數(shù)在規(guī)定時(shí)間內(nèi)必須執(zhí)行一次
     * @param {Function} fn     定時(shí)執(zhí)行的函數(shù)
     * @param {int}      delay  延遲多少毫秒執(zhí)行
     * @param {[type]}   mustRunDelay 多少毫秒內(nèi)必須執(zhí)行一次
     * @return {[type]}      [description]
     */
    sPro.throttle = function(fn, delay, mustRunDelay){
        var timer = null;
        var lastTime;
        return function(){
            var now = +new Date();
            var args = arguments;
            g.clearTimeout(timer);
            if(!lastTime){
                lastTime = now;
            }
            if(now - lastTime > mustRunDelay){
                fn.apply(this, args);
                lastTime = now;
            }else{
                g.setTimeout(function(){
                    fn.apply(this, args);
                }.bind(this), delay);
            }
        }.bind(this);
    };

    /**
     * window.requestAnimationFrame的兼容性寫法,保證在100/6ms執(zhí)行一次
     * @param  {Function} fn 100/16ms需要執(zhí)行的函數(shù)
     * @return {void}      
     */
    sPro.nextFrame = (function(fn){
        var prefix = ["ms", "moz", "webkit", "o"];
        var handle = {};
        handle.requestAnimationFrame = window.requestAnimationFrame;
        for(var i = 0; i < prefix.length && !handle.requestAnimationFrame; ++i){
            handle.requestAnimationFrame = window[prefix[i] + "RequestAnimationFrame"];
        }
        if(!handle.requestAnimationFrame){
            handle.requestAnimationFrame = function(fn) {
                var raf = window.setTimeout(function() {
                    fn();
                }, 16);
                return raf;
            };
        }
        return function(fn) {
            handle.requestAnimationFrame.apply(g, arguments);
        }
    })();

    /**
     * 判斷stickyNode的當(dāng)前位置設(shè)置fixed|static|sticky定位
     * @return {void}
     */
    sPro.sticky = function() {
        this.setting.runInScrollFn && this.setting.runInScrollFn();
        var stickyNodeBox = this.stickyNode.getBoundingClientRect();
        if(stickyNodeBox.top <= this.top && !this.isfixed){
            this.setFixedCss(this.fixedCss);
            this.fixedClazz && $(this.fixedNode).addClass(this.fixedClazz);
            this.isfixed = true;
            $(this).trigger("onsticky", true);
        } else if(stickyNodeBox.top > this.top && this.isfixed) {
            this.setFixedCss(this.initCss.replace(/position:[^;]*/, "position:static"));
            g.setTimeout(function() {
                this.setFixedCss(this.initCss)
            }.bind(this), 30);
            this.fixedClazz && $(this.fixedNode).removeClass(this.fixedClazz);
            this.isfixed = false;
            $(this).trigger("onsticky", true);
        }
    };

    $.initSticky = function(options){
        return new Sticky(options);
    };
})();

html 結(jié)構(gòu)

css 結(jié)構(gòu)

.g-page-box .m-nav?{

 height:?1.33333rem;

}

.g-page-box .m-nav .nav-fixed?{

 height:?.86667rem;
 padding:?.22667rem .50667rem;
 background-color:?#1aadbb;
 position:?relative;
 transform:?translate3d(0, 0, 0);
 -webkit-transform:?translate3d(0, 0, 0);
 transition:?height 4s;

}

.fixed{
position:?fixed;
 top:?0px;
 z-index:?100;
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/115453.html

相關(guān)文章

  • 解決頁(yè)面滾動(dòng)時(shí)吸頂操作不能時(shí)響應(yīng)bug

    摘要:這個(gè)界限就是該元素頂部距離窗口頂部的距離等于該元素設(shè)置的值比如以下像素分割線當(dāng)我的頂部距離窗口頂部為值時(shí),我就會(huì)像一樣在距離窗口值處的時(shí)代發(fā)送分效果圖當(dāng)頁(yè)面滾動(dòng)到距離黃色區(qū)塊頂部時(shí),黃色區(qū)塊就會(huì)在窗口頂部處,頁(yè)面再往下滾動(dòng)距離也不會(huì)變。 position: sticky; fixed 吸頂 頁(yè)面滾動(dòng)結(jié)束后頁(yè)面才渲染 需求 經(jīng)常會(huì)有這樣的需求,當(dāng)頁(yè)面滾動(dòng)到某一個(gè)位置fixedTopV...

    wapeyang 評(píng)論0 收藏0
  • 解決頁(yè)面滾動(dòng)時(shí)吸頂操作不能時(shí)響應(yīng)bug

    摘要:這個(gè)界限就是該元素頂部距離窗口頂部的距離等于該元素設(shè)置的值比如以下像素分割線當(dāng)我的頂部距離窗口頂部為值時(shí),我就會(huì)像一樣在距離窗口值處的時(shí)代發(fā)送分效果圖當(dāng)頁(yè)面滾動(dòng)到距離黃色區(qū)塊頂部時(shí),黃色區(qū)塊就會(huì)在窗口頂部處,頁(yè)面再往下滾動(dòng)距離也不會(huì)變。 position: sticky; fixed 吸頂 頁(yè)面滾動(dòng)結(jié)束后頁(yè)面才渲染 需求 經(jīng)常會(huì)有這樣的需求,當(dāng)頁(yè)面滾動(dòng)到某一個(gè)位置fixedTopV...

    gggggggbong 評(píng)論0 收藏0
  • 【前端詞典】5 種滾動(dòng)吸頂實(shí)現(xiàn)方式的比較[性能升級(jí)版]

    摘要:用于獲得當(dāng)前元素到定位父級(jí)頂部的距離偏移值。后來(lái)在項(xiàng)目中總會(huì)遇到滾動(dòng)吸頂?shù)男Ч枰獙?shí)現(xiàn),現(xiàn)在我將我知道的種滾動(dòng)吸頂實(shí)現(xiàn)方式做詳細(xì)介紹。有兼容性問(wèn)題,在微信瀏覽器某些版本中的值會(huì)為,于是乎也就有了第三種方案的兼容性寫法。修改版預(yù)覽 這篇文章是三天前寫就的,有大佬給我提了一些修改意見(jiàn),我覺(jué)得這個(gè)意見(jiàn)確實(shí)中肯。所以就有了這個(gè)升級(jí)的修改版本。代碼同步更新到 GitHub 了。 修改內(nèi)容如下: 添加...

    happyfish 評(píng)論0 收藏0
  • Vue開(kāi)發(fā)——實(shí)現(xiàn)吸頂效果

    摘要:因?yàn)轫?xiàng)目需求,最近開(kāi)始轉(zhuǎn)到微信公眾號(hào)開(kāi)發(fā),接觸到了框架,這個(gè)效果的實(shí)現(xiàn)雖說(shuō)是基于框架下實(shí)現(xiàn)的,但是同樣也可以借鑒到其他地方,原理都是一樣的。上面我們得到了一個(gè)的屬性值,接下來(lái)我們只需要根據(jù)它的值來(lái)設(shè)置吸頂元素的屬性就可以了。 因?yàn)轫?xiàng)目需求,最近開(kāi)始轉(zhuǎn)到微信公眾號(hào)開(kāi)發(fā),接觸到了Vue框架,這個(gè)效果的實(shí)現(xiàn)雖說(shuō)是基于Vue框架下實(shí)現(xiàn)的,但是同樣也可以借鑒到其他地方,原理都是一樣的。 進(jìn)入正題...

    amuqiao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<