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

資訊專欄INFORMATION COLUMN

tinyscrollbar鎖滾動問題引出對wheel事件的探索

leanote / 2157人閱讀

摘要:鎖滾動問題近日做需求,發(fā)現(xiàn)一個常用插件突然出毛病了,于是探究了一番個中原因。但在最新版下,準確的說是系統(tǒng)環(huán)境下,發(fā)生了自定義滾動條鎖滾動的問題。是通過監(jiān)聽頁面滾輪事件,進一步進行設(shè)置內(nèi)容位置來實現(xiàn)自定義滾動條的。

tinyscrollbar鎖滾動問題

近日做需求,發(fā)現(xiàn)一個常用插件jquery.tinyscrollbar突然出毛病了,于是探究了一番個中原因。

出問題的場景

在ie,chrome以及其他主流瀏覽器下,jquery.tinyscrollbar能夠正常響應并滾動自定義滾動條。但在最新版firefox下,準確的說是OS X系統(tǒng)環(huán)境下,發(fā)生了自定義滾動條鎖滾動的問題。

尋找問題源頭

我們發(fā)現(xiàn)場景下,是滾動了一段距離后,插件突然卡住。

于是我開始翻閱jquery.tinyscrollbar的源碼,尋找設(shè)置內(nèi)容位置的代碼。jquery.tinyscrollbar是通過監(jiān)聽頁面滾輪事件,進一步進行設(shè)置內(nèi)容位置來實現(xiàn)自定義滾動條的。其中響應滾動事件的方法是_wheel,那好,我們來看_wheel的源碼

通過閱讀jquery.tinyscrollbar源碼發(fā)現(xiàn),有一段源碼是如此陳述的:

/**
 * @method _wheel
 * @private
 */
function _wheel(event) {
    if(self.hasContentToSroll) {
        // Trying to make sense of all the different wheel event implementations..
        // 接洽原生事件
        var evntObj = event || window.event
        // 獲取滾輪的差量
        ,   wheelDelta = -(evntObj.deltaY || evntObj.detail || (-1 / 3 * evntObj.wheelDelta)) / 40
        // 獲取滾動單位
        ,   multiply = (evntObj.deltaMode === 1) ? self.options.wheelSpeed : 1
        ;
        // 計算內(nèi)容位置
        self.contentPosition -= wheelDelta * multiply * self.options.wheelSpeed;
        self.contentPosition = Math.min((self.contentSize - self.viewportSize), Math.max(0, self.contentPosition));
        // 計算滾動條位置
        self.thumbPosition = self.contentPosition / self.trackRatio;

        /**
         * The move event will trigger when the carousel slides to a new slide.
         * 向外拋出移動事件
         * @event move
         */
        $container.trigger("move");

        // 設(shè)置滾動條位置
        $thumb.css(posiLabel, self.thumbPosition);
        // 設(shè)置內(nèi)容位置
        $overview.css(posiLabel, -self.contentPosition);

        // 判斷是否觸底,觸底的話阻止事件繼續(xù)觸發(fā)
        if(self.options.wheelLock || _isAtBegin() && _isAtEnd()) {
            evntObj = $.event.fix(evntObj);
            evntObj.preventDefault();
        }

        if(_isAtBegin() && _isAtEnd()){
            evntObj.stopPropagation(); 
        }
        
    }
}

既然是內(nèi)容滾不動了,那么問題一定出在設(shè)置內(nèi)容位置的地方了

確定問題

我們在這個方法里對self.contentPosition打了個log,果不其然,self.contentPosition顯示為NaN。要知道NaN和任何數(shù)做計算最后所得的值都是NaN的,所以出現(xiàn)了bug。

那么這個NaN是哪里來的呢?繼續(xù)對wheelDelta和multiply打log,發(fā)現(xiàn)wheelDelta產(chǎn)生了NaN值。

此時一頭黑人問號。近一步翻閱MDN發(fā)現(xiàn),大部分現(xiàn)代瀏覽器支持wheel事件(DOM Level 2的事件),ie和webkit瀏覽器支持mousewheel事件(非標準),老的火狐瀏覽器支持的是DOMMouseScroll事件(非標準)。于是我們開始探究幾個事件中的差異

wheel事件所具有的read-only屬性

WheelEvent.deltaX
雙精度值,表示滾輪在水平方向的差量
WheelEvent.deltaY
雙精度值,表示滾輪在豎直方向的差量
WheelEvent.deltaZ
雙精度值,表示滾輪在z軸上的差量
WheelEvent.deltaMode
無符號長整形,表示滾動的單位, 0為表示px,1為表示以行為單位滾動,2為以頁為單位滾動

wheel事件同時繼承了父類MouseEvent, UIEvent 和 Event的屬性

UIEvent.detail
返回一個長整型數(shù)值,用于描述該事件,依賴于事件類型

delta的值并不代表真實的滾動量,只是針對鼠標指針的位置來計算的

MouseWheelEvent read-only屬性

wheelDelta
長整型,以像素來計算的滾輪偏移值
wheelDeltaX
長整型,以像素來計算的滾輪x軸偏移值
wheelDeltaY
長整型,以像素來計算的滾輪y軸偏移值
detail
該值總是0,除了Opera瀏覽器以外

DOMMouseScroll只有一個屬性

detail
用于精確描述滾動,正值表示向下滾,負值表示向上滾。向上滾一頁-32768,向下滾一頁32768,其他值表示滾動行數(shù)

重要描述,該值永遠不為0

detail值的描述

在MouseWheelEvent中,

Opera設(shè)置這個值和firefox的Gecko內(nèi)核DOMMouseScroll 事件的 detail是一樣的。都用來表示以行來滾動,負值用來表示向底部或者向右滾動。在mac上,滾動加速階段會計算該值。在linux上,是由原生滾動事件設(shè)置的,值為2或者-2

所以新版firefox中wheel事件發(fā)生了啥?

我們打印console.log(evt.deltaX,event.detail,event.wheelDelta)。發(fā)現(xiàn)在觸底的時候,日志顯示(0,0,undefined),真相大白!

在webkit或者blink中,deltaX這個值永遠不會被設(shè)置為0,而在新版firefox中(mac os x),這個值在某時阻尼滾動結(jié)束的時候是會變?yōu)?0。由于下式的斷言,最終整個計算中被引入了一個NaN

wheelDelta = -(evntObj.deltaY || evntObj.detail || (-1 / 3 * evntObj.wheelDelta)) / 40
是插件的缺陷嗎

很明顯,插件作者最初是沒有設(shè)想到deltaY為0的情況,于是依托或運算的截斷操作寫了這句經(jīng)驗而來的代碼。對我們這些工作者而言,這樣的判斷是不嚴謹?shù)?。如果嚴格按照瀏覽器的區(qū)分來判斷,就能避免這個問題。以測試而言,明顯作者沒有考慮到undefined這樣的極端情況。

作者去哪兒啦?

在git上尋找作者,發(fā)現(xiàn)該倉庫已經(jīng)年久失修了。。。作者棄坑而去

解決辦法

臨時的:
自己把插件源碼改了,將默認值設(shè)為0,避免NaN引入的風險wheelDelta = -(evntObj.deltaY || evntObj.detail || (-1 / 3 * evntObj.wheelDelta)) / 40 || 0
永久的:
向火狐提issue~
可能實現(xiàn)的(極小):
向作者提pr

給我們的啟示

一切按標準或者文檔來(MSDN有時候不可信,佐證如下)

Interface :MouseWheelEvent
Synchronicity :asynchronous
Bubbles : yes (Though, MSDN documents "No")
Target :Element, Document, Window
Cancelable : yes (Though, MSDN documents "No")
Default action : Scroll, moving history, or zooming in/out
MDN賽高!

MDN目前已經(jīng)變成最大的web標準,文檔集散地了

參考資料

MouseWheelEvent
DomMouseScrollEvent
WheelEvent

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

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

相關(guān)文章

  • 自定義滾動條插件

    摘要:本插件是對插件的一個封裝。因為在用的時候需要同時引用和文件,同時還需要修改結(jié)構(gòu),比較麻煩,為了方便起見,將和文件都用引入,修改的方法也放在文件中。具體代碼使用方法引入文件引入文件初始化滾動條為內(nèi)容容器的主要的代碼如下創(chuàng)建文本片段 本插件是對tinyscrollbar插件的一個封裝。因為在用的時候需要同時引用css和js文件,同時還需要修改dom結(jié)構(gòu),比較麻煩,為了方便起見,將tinys...

    snowLu 評論0 收藏0
  • 一文讀懂鼠標滾輪事件wheelEvent)

    摘要:下面正式推薦大神的博文前段時間使用做滾動條控件,添加滾輪事件時,查閱了一些資料,發(fā)現(xiàn)大都是文檔描述或簡單示例,對于開發(fā)者還是不夠。一測試目標探索事件中常用屬性的有效性,垂直步進算法滑動幅度以及與電腦個性化設(shè)置的關(guān)聯(lián)。 最近在用VUE寫一個后臺管理系統(tǒng),頂部標簽頁涉及鼠標滾輪事件,由于每個瀏覽器對滾輪事件的處理方式不一樣,個人對這個又不懂,折騰了很久,參考了大神的代碼,也把百度翻爛了,找...

    doodlewind 評論0 收藏0
  • 滑動穿透(body)終極探索

    摘要:場景當頁面出現(xiàn)浮層的時候,滑動浮層的內(nèi)容,正常情況下預期應該是浮層下邊的內(nèi)容不會滾動然而事實并非如此。當屬性的值為的時候,代表該監(jiān)聽器內(nèi)部不會調(diào)用函數(shù)來阻止默認滑動行為,瀏覽器稱這類型的監(jiān)聽器為被動監(jiān)聽器。 場景 當頁面出現(xiàn)浮層的時候,滑動浮層的內(nèi)容,正常情況下預期應該是浮層下邊的內(nèi)容不會滾動;然而事實并非如此。showImg(https://user-gold-cdn.xitu.io...

    Michael_Lin 評論0 收藏0
  • 滑動穿透(body)終極探索

    摘要:場景當頁面出現(xiàn)浮層的時候,滑動浮層的內(nèi)容,正常情況下預期應該是浮層下邊的內(nèi)容不會滾動然而事實并非如此。當屬性的值為的時候,代表該監(jiān)聽器內(nèi)部不會調(diào)用函數(shù)來阻止默認滑動行為,瀏覽器稱這類型的監(jiān)聽器為被動監(jiān)聽器。 場景 當頁面出現(xiàn)浮層的時候,滑動浮層的內(nèi)容,正常情況下預期應該是浮層下邊的內(nèi)容不會滾動;然而事實并非如此。showImg(https://user-gold-cdn.xitu.io...

    RaoMeng 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<