實現小小的fullpage

需求背景

今天運營給了一個需求,要作個引導頁,也就是全屏滾動。考慮到只有3張圖,就本身碼個吧!說幹就幹。javascript

思路

  1. 設置一個外層container, 用戶的可見區域,也就是全屏css

  2. container內有3個層次,每一個層次大小都跟container同樣大小html

  3. 每次滾動時候經過css的transform屬性進行偏移,並結合transition過渡一下效果java

*{
    margin: 0;
    padding: 0;
}
.container{
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 99999;
    overflow: hidden;
}
.scrollContainer{
    display: none;
    transition: all ease 1s;
}
.slide1{
    background-color: rgb(27, 188, 155);
}
.slide2{
    background-color: rgb(255, 153, 0);
}
.slide3{
    background-color: rgb(123, 170, 190);
}
<div class="container">
    <div class="scrollContainer">
        <div class="slide slide1">
        </div>
        <div class="slide slide2">
        </div>
        <div class="slide slide3">
        </div>
    </div>
</div>

scrollContainer是用來滾動內容的,因此在頁面進入的時候要獲取用戶區域jquery

var $container = $('.container');
var $scroll = $container.find('.scrollContainer');
var height = $container.height();
var len = 3;
var current = 1;
$container.find('.slide').css('height', height + 'px');
$scroll.show();

邏輯部分

爲了防止滾動屢次滾動,須要經過一個變量來控制是否滾動,這裏的動畫是1s執行完,使用setTimeout延遲1s後解鎖,這樣大致邏輯差很少git

// page控制器
var len = 3;
var current = 1;
var page = {
    isScrolling: false,
    next: function() {
        if((current + 1) <= len) {
            current += 1;
            page.move(current);
        }
    },
    pre: function() {
        if(current -1 > 0) {
            current -= 1;
            page.move(current);
        }
    },
    move: function(index) {
        page.isScrolling = true;
        var di = -(index-1)*height + 'px';
        page.start = +new Date();
        $scroll.css('transform', 'translateY('+di+')');
        setTimeout(function(){
            page.isScrolling = false;
        }, 1010);
    }
};
// 滾動事件綁定
function bindMouseWheel (page) {
    var  type = 'mousewheel';
    var  deltaY = 0;

    function mouseWheelHandle (event) {
        if (page.isScrolling) {// 加鎖部分
            return false;
        }
        var e = event.originalEvent || event;

        deltaY = e.deltaY;
        if (deltaY > 0) {
            page.next();
        } else if (deltaY < 0) {
            page.pre();
        }
    }
    $(document).on('mousewheel', mouseWheelHandle);
}

差很少了,大致已經完成,在瀏覽器中運行也幾乎完美!可是咱們是一家千牛應用,在千牛裏面運行,看似不錯,可是鼠標快速移動就會出現閃屏、多滾動問題github

解決問題

出現這個問題,第一反應是代碼寫錯了,沒有兼容瀏覽器,可是一想千牛就是chrome內核,不須要寫兼容代碼啊!web

方案1

不採用css動畫,採用jquery動畫。改變top值。
也嘗試了這個方案,選擇800毫秒效果相對最佳。chrome

方案2

繼續思考一開始的思路爲啥出現問題。通過老大提醒,並結合千牛以前出現的css動畫問題,感受是動畫結束和js控制沒有達到一致。爲了驗證這個假設,去除setTimeout延遲,添加webkitTransitionEnd事件,並打印出每次滾動時間。瀏覽器

// page控制更改
 move: function(index) {
    page.isScrolling = true;
    var di = -(index-1)*height + 'px';
    page.start = +new Date();
    $scroll.css('transform', 'translateY('+di+')');
},
// 添加了滾動結束控制
moveEnd: function() {
    page.end = +new Date();
    console.log('end', (page.end - page.start)/1000);
    page.isScrolling = false;
}
// 給添加滾動結束事件
$scroll.on('webkitTransitionEnd', page.moveEnd);

最終結果了滾動出現的問題,再查看每次滾動時間

end 1.022
end 1.055
end 2.344
end 2.273

在chrome裏面查看滾動時間

end 0.999
end 0.994
end 1.006
end 1.023
end 0.991
end 0.997
end 1.005
end 1.046

結論

從結果來看在chrome裏面css動畫幾乎沒有延遲的跟設定1s過渡時間基本吻合,可是在千牛應用裏面可以看出css動畫會受其餘條件影響,好比上面所遇到的鼠標滾動過快等因素。

因此在css動畫這方面就應該用css動畫事件來控制。除了過渡有且只有webkitTransitionEnd事件,動畫開始webkitAnimationStart,動畫結束事件webkitAnimationEnd,動畫重複運動事件 webkitAnimationIteration。後面再玩玩
演示地址

本文原地址http://xiaoqiang730730.github.io/2016/06/03/fullpage/

相關文章
相關標籤/搜索