移動端滑屏全應用【二】滑屏封裝注意事項與移動端輪播
阿新 • • 發佈:2018-12-02
移動端滑屏封裝注意事項:
1.touchMove時候方向判斷(可以控制在 以x軸位中心正負15度之內為橫向滑屏,縱向滑屏同理)
2.上下滑屏與左右滑屏的衝突(判斷使用者滑動方向後,只做單方向的處理)
3.安卓觸控(例如某個人手指很粗)觸發touchMove(記錄上一次的手指座標,每一次move的時候判斷,上次的座標與這一次的座標相同則return掉)
移動端輪播封裝注意事項:
1.使用transition做過度效果時,需要在每次start的時候清除transition,否則效果會有卡頓
2.每次end時算出當前應處於的位置,再利用transition做過渡效果
3.做無縫滾動時,需要在將結點複製一份,在start時判斷:若是第一張,則迅速移動到新複製結點的第一張;若是最後一張,則迅速移動到第一份結點的最後一張。(仿照PC端複製第一張和最後一張行不通)
輪播圖封裝如下:
function transform (el, attr, val) { if (!el.transform) { el.transform = { }; } if (val === undefined) { return el.transform[attr]; } el.transform[attr] = val; var str = ""; // 此處要注意必須要在原由的基礎上遍歷 for (var s in el.transform) {switch (s) { case "rotate": case "rotateX": case "rotateY": case "rotateZ": case "skewX": case "skewY": str += s + "(" + el.transform[s] + "deg) "; break; case "scale":case "scaleX": case "scaleY": str += s + "(" + el.transform[s] + ") "; break; case "translateX": case "translateY": case "translateZ": str += s + "(" + el.transform[s] + "px) "; break; } } el.style.WebkitTransform = el.style.transform = str; } function css (el, attr, val) { var transformAttr = ["rotate", "rotateX", "rotateY", "rotateZ", "skewX", "skewY", "scale", "scaleX", "scaleY", "translateX", "translateY", "translateZ"]; for (var i = 0; i < transformAttr.length; i++) { if (attr === transformAttr[i]) { return transform(el, attr, val); } } if (val === undefined) { val = getComputedStyle(el)[attr]; val = parseFloat(val); return val; } if (attr === "opacity") { el.style[attr] = val; } else { el.style[attr] = val + "px"; } } function TSwiper (obj) { obj = obj || {}; this.default = { wrapper: '#wrapper', dir: 'x', start: {}, target: {}, interval: 3000, beforeSlide: function () {}, afterSlide: function () {}, dirHandler: { x: 'translateX', y: 'translateY' }, changedVal: { x: 'pageX', y: 'pageY' } }; for (var index in this.default) { if (!obj[index]) { obj[index] = this.default[index]; } } this.wrapper = obj.wrapper; this.nowPos = null; // 當前位置的translate this.dir = obj.dir; // 方向 x || y this.start = obj.start; this.target = obj.target; this.interval = obj.interval; this.beforeSlide = obj.beforeSlide; // 手指剛觸控時的回撥,可依賴注入當前滑動結點,實踐物件和當前swiper例項物件 this.afterSlide = obj.afterSlide; // 滑屏結束後的回撥,依賴注入值同上 this.autoTimer = null; this.now = 0; } TSwiper.prototype.init = function () { var _this = this; this.wrapper = document.querySelector(this.wrapper); this.slideItem = document.querySelectorAll('.slide-item'); this.pager = document.querySelector('#pager'); this.aPagerItem = document.querySelectorAll('.pager-item'); this.slideItem.forEach(function (item, index) { item.style.width = window.outerWidth + 'px'; if (index === 0) { _this.pager.innerHTML += '<li class="pager-item active"></li>' } else { _this.pager.innerHTML += '<li class="pager-item"></li>' } }) this.aPagerItem = document.querySelectorAll('.pager-item'); this.wrapper.innerHTML += this.wrapper.innerHTML; // 將結點複製一份 css(_this.wrapper, 'translateX', 0); css(_this.wrapper, 'translateY', 0); css(_this.wrapper, 'translateZ', 0); this.wrapper.style.width = this.slideItem.length * 2 * window.outerWidth + 'px'; this.judge = function (specialIndexFn) { if (_this.now === 0) { _this.now = _this.slideItem.length; specialIndexFn && specialIndexFn(); } else if (_this.now === _this.slideItem.length * 2 - 1) { _this.now = _this.slideItem.length - 1; specialIndexFn && specialIndexFn(); } } this.setPageIndex = function () { let pageIndex; // 設定輪播點 pageIndex = _this.now % _this.slideItem.length; _this.aPagerItem.forEach(function (item, index) { item.className = ''; }) _this.aPagerItem[pageIndex].className = 'active'; } this.wrapper.addEventListener('touchstart', function (ev) { clearInterval(_this.autoTimer); _this.beforeSlide && _this.beforeSlide.call(_this.wrapper, ev, _this); _this.wrapper.style.transition = 'none'; // 初始化時清除過度,手指按下時需要設定判斷並設定初始位置 _this.nowPos = css(_this.wrapper, _this.default.dirHandler[_this.dir]); _this.now = Math.round(Math.abs(_this.nowPos / window.outerWidth)) // 三張圖片複製一份一共六張,如果是第一張,迅速移動到第四張,如果是第六張,迅速移動到第三張 _this.judge(); css(_this.wrapper, _this.default.dirHandler[_this.dir], -_this.now * window.outerWidth) _this.nowPos = css(_this.wrapper, _this.default.dirHandler[_this.dir]); _this.start.x = ev.changedTouches[0].pageX; _this.start.y = ev.changedTouches[0].pageY; }) _this.wrapper.addEventListener('touchmove', function (ev) { css(_this.wrapper, _this.default.dirHandler[_this.dir], _this.nowPos + ev.changedTouches[0][_this.default.changedVal[_this.dir]] - _this.start[_this.dir]) }) _this.wrapper.addEventListener('touchend', function (ev) { _this.nowPos = css(_this.wrapper, _this.default.dirHandler[_this.dir]); _this.now = Math.round(Math.abs(_this.nowPos / window.outerWidth)); _this.wrapper.style.transition = '0.3s'; _this.afterSlide && _this.afterSlide.call(_this.wrapper, ev, _this); css(_this.wrapper, _this.default.dirHandler[_this.dir], -_this.now * window.outerWidth); _this.setPageIndex(); _this.autoTimer = setInterval(_this.timerFn, _this.interval); }) _this.timerFn = function () { _this.wrapper.style.transition = 'none'; _this.judge(function () { css(_this.wrapper, _this.default.dirHandler[_this.dir], -_this.now * window.outerWidth); }); _this.now++; setTimeout(function () { _this.wrapper.style.transition = '0.3s'; css(_this.wrapper, _this.default.dirHandler[_this.dir], -_this.now * window.outerWidth); _this.setPageIndex(); }, 50) } _this.autoTimer = setInterval(_this.timerFn, _this.interval); } export default TSwiper
呼叫方法:
var tSwiper = new TSwiper().init()
有問題可留言。