今天運營給了一個需求,要作個引導頁,也就是全屏滾動。考慮到只有3張圖,就本身碼個吧!說幹就幹。javascript
設置一個外層container, 用戶的可見區域,也就是全屏css
container內有3個層次,每一個層次大小都跟container同樣大小html
每次滾動時候經過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
不採用css動畫,採用jquery動畫。改變top值。
也嘗試了這個方案,選擇800毫秒效果相對最佳。chrome
繼續思考一開始的思路爲啥出現問題。通過老大提醒,並結合千牛以前出現的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。後面再玩玩
演示地址