最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

原生JS實現(xiàn)移動端web輪播圖詳解(結合Tween算法造輪子)

 更新時間:2017年09月10日 09:19:51   作者:苦練內功  
在做移動端開發(fā)的時候,必不可少的是輪播圖,下面這篇文章主要給大家介紹了關于利用純JS實現(xiàn)移動端web輪播圖的相關資料,重要的是結合Tween算法造輪子,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

相信大家應該都知道,移動端的輪播圖是我們比較常見的需求, 我們最快的實現(xiàn)方式往往是 使用第三方的代碼, 例如 swiper , 但當遇到一些比較復雜的輪播圖需求時, 往往是束手無策,不知道怎么改.      

所以我們要嘗試去自己造一些輪子, 以適應各種復雜多變的需求;  另外一點, 自己寫的代碼如果有bug是很容易修復的, 對自身的提高也很大.

在沒有閱讀swiper源碼的過程下,我嘗試自己實現(xiàn)一個簡易而不失實用的移動端輪播圖, 經(jīng)過幾個小時的思考和實踐終于還是實現(xiàn)了(如圖):


實現(xiàn)移動端的輪播圖要比pc復雜一些,主要表現(xiàn)在以下幾個方面:

     1.輪播圖要適應不同寬度/dpr的屏幕 

     2.需要使用 touch相關的事件 

     3.不同機型對 touch事件支持的不太一樣,可能會有一些兼容性問題 

     4.手指移動圖片一部分距離,剩下的距離需要自動完成 

     5.自動完成距離需要有 ease 時間曲線 

但編程解決問題的思路都是差不多的,

我們在使用輪播圖的時候可以仔細觀察,通過現(xiàn)象看到本質:

  • 我們在使用輪播圖的時候可以仔細觀察,通過現(xiàn)象看到本質: 
  • 手指放在圖片上, 手指向左或者向右移動, 圖片也隨之移動; 
  • 手指移動的距離少時,圖片自動復原位置;手指移動的距離多時,自動切換到下一張; 
  • 手指向左或者向右移動的快時,會切換到下一張; 
  • 圖片輪播是無限循環(huán)的, 我們需要采用  3 1 2 3 1的方式來實現(xiàn), 即 N+2張圖來實現(xiàn)N張圖的無限循環(huán)輪播 

我們通過分析現(xiàn)象,可以提出一個基本實現(xiàn)方案:

     1. 手指觸摸事件可以通過 touchstart touchmove touchend 3個事件來實現(xiàn) 

     2.在手指 touchstart的時候我們需要記錄 手指的x坐標,  可以使用 touch的pageX屬性; 還有 這個時間點, 

     3.手指touchmove的時候我們也需要記錄pageX,并且記錄累計移動的距離 moveX 

     4.手指離開的時候,記錄時間點, 根據(jù)前兩步計算的 x方向移動的距離,時間點之差 

     5.通過比較x方向移動距離來判斷移動方向, 以及是否應該切換到下一張圖; 根據(jù)時間判斷用戶是否進行了左右掃動的操作 

     6.移動圖片可以使用 translate3d來實現(xiàn),開啟硬件加速 

     7.移動一段距離需要 easeOut效果,我們可以使用 Tween算法中的easeOut來實現(xiàn)我們每次移動的距離; 當然也可以使用 js設置 transition動畫 

實現(xiàn)源碼(僅供參考):

head頭部樣式

<head> 
 <meta charset="UTF-8"> 
 <meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5"> 
 <title>移動端輪播圖</title> 
 <style> 
 * { 
 box-sizing: border-box; 
 margin: 0; 
 padding: 0 
 } 
 .banner { 
 overflow: hidden; 
 width: 100%; 
 height: 300px 
 } 
 .banner .img-wrap { 
 position: relative; 
 height: 100% 
 } 
 .banner img { 
 display: block; 
 position: absolute; 
 top: 0; 
 width: 100%; 
 height: 100% 
 } 
 </style> 
</head> 

HTML結構

<div class="banner"> 
 <div class="img-wrap" id="imgWrap"> 
 <img src="images/banner_3.jpg" data-index="-1"> 
 <img src="images/banner_1.jpg" data-index="0"> 
 <img src="images/banner_2.jpg" data-index="1"> 
 <img src="images/banner_3.jpg" data-index="2"> 
 <img src="images/banner_1.jpg" data-index="3"> 
 </div> 
</div> 

JS代碼1, easeOut動畫式移動,

這里的   HTMLElement.prototype.tweenTranslateXAnimate ,是給所有的HTML元素類擴展的tweenTranslateXAnimate方法

移動一段距離我們需要使用定時器來幫助我們完成,這個重復的操作

<script> 
 HTMLElement.prototype.tweenTranslateXAnimate = function (start, end, callback) { 
 var duration = 50; 
 var t = 0; 
 var vv = end - start; 
 var Tween = { 
 Quad: { 
 easeOut: function (t, b, c, d) { 
  return -c * (t /= d) * (t - 2) + b; 
 } 
 } 
 }; 
 
 this.timer = setInterval(function () { 
 var dis = start + Tween.Quad.easeOut(++t, 0, vv, duration); 
 this.style.transform = 'translate3d(' + dis + 'px, 0, 0)'; 
 if (vv > 0 && parseInt(this.style.transform.slice(12)) >= end) { 
 this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; 
 clearInterval(this.timer); 
 callback && callback(); 
 } 
 if (vv < 0 && parseInt(this.style.transform.slice(12)) <= end) { 
 this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; 
 clearInterval(this.timer); 
 callback && callback(); 
 } 
 }.bind(this), 4); 
 } 
</script> 

touch事件部分

<script> 
 ~function () { 
 var lastPX = 0; // 上一次觸摸的位置x坐標, 需要計算出手指每次移動的一點點距離 
 var movex = 0; // 記錄手指move的x方向值 
 var imgWrap = document.getElementById('imgWrap'); 
 var startX = 0; // 開始觸摸時手指所在x坐標 
 var endX = 0; // 觸摸結束時手指所在的x坐標位置 
 var imgSize = imgWrap.children.length - 2; // 圖片個數(shù) 
 var t1 = 0; // 記錄開始觸摸的時刻 
 var t2 = 0; // 記錄結束觸摸的時刻 
 var width = window.innerWidth; // 當前窗口寬度 
 var nodeList = document.querySelectorAll('#imgWrap img'); // 所有輪播圖節(jié)點數(shù)組 NodeList 
 
 // 給圖片設置合適的left值, 注意 querySelectorAll返回 NodeList, 具有 forEach方法 
 nodeList.forEach(function (node, index) { 
 node.style.left = (index - 1) * width + 'px'; 
 }); 
 
 /** 
 * 移動圖片到當前的 tIndex索引所在位置 
 * @param {number} tIndex 要顯示的圖片的索引 
 * */ 
 function toIndex(tIndex) { 
 var dis = -(tIndex * width); 
 var start = parseInt(imgWrap.style.transform.slice(12)); 
 // 動畫移動 
 imgWrap.tweenTranslateXAnimate(start, dis, function () { 
 setTimeout(function () { 
  movex = dis; 
  if (tIndex === imgSize) { 
  imgWrap.style.transform = 'translate3d(0, 0, 0)'; 
  movex = 0; 
  } 
  if (tIndex === -1) { 
  imgWrap.style.transform = 'translate3d(' + width * (1 - imgSize) + 'px, 0, 0)'; 
  movex = -width * (imgSize - 1); 
  } 
 }, 0); 
 }); 
 } 
 
 /** 
 * 處理各種觸摸事件 ,包括 touchstart, touchend, touchmove, touchcancel 
 * @param {Event} evt 回調函數(shù)中系統(tǒng)傳回的 js 事件對象 
 * */ 
 function touch(evt) { 
 var touch = evt.targetTouches[0]; 
 var tar = evt.target; 
 var index = parseInt(tar.getAttribute('data-index')); 
 if (evt.type === 'touchmove') { 
 var di = parseInt(touch.pageX - lastPX); 
 endX = touch.pageX; 
 movex += di; 
 imgWrap.style.webkitTransform = 'translate3d(' + movex + 'px, 0, 0)'; 
 lastPX = touch.pageX; 
 } 
 if (evt.type === 'touchend') { 
 var minus = endX - startX; 
 t2 = new Date().getTime() - t1; 
 if (Math.abs(minus) > 0) { // 有拖動操作 
  if (Math.abs(minus) < width * 0.4 && t2 > 500) { // 拖動距離不夠,返回! 
  toIndex(index); 
  } else { // 超過一半,看方向 
  console.log(minus); 
  if (Math.abs(minus) < 20) { 
  console.log('距離很短' + minus); 
  toIndex(index); 
  return; 
  } 
  if (minus < 0) { // endX < startX,向左滑動,是下一張 
  toIndex(index + 1) 
  } else { // endX > startX ,向右滑動, 是上一張 
  toIndex(index - 1) 
  } 
  } 
 } else { //沒有拖動操作 
 
 } 
 } 
 if (evt.type === 'touchstart') { 
 lastPX = touch.pageX; 
 startX = lastPX; 
 endX = startX; 
 t1 = new Date().getTime(); 
 } 
 return false; 
 } 
 
 imgWrap.addEventListener('touchstart', touch, false); 
 imgWrap.addEventListener('touchmove', touch, false); 
 imgWrap.addEventListener('touchend', touch, false); 
 imgWrap.addEventListener('touchcancel', touch, false); 
 
 }(); 
 
</script> 

在觸摸事件中最關鍵的參數(shù)是  pageX參數(shù), 記錄x的位置.

當然這只是一個demo,還需要進一步的優(yōu)化和封裝, 以便于我們用在真實的項目.

本demo僅僅是提供了一個解決問題的思路, 有了這個思路,相信各種復雜的需求也得以解決...

本文中使用的 tween算法來實現(xiàn) ease-out效果 ,也可以使用 transtion動畫實現(xiàn), 代碼更加簡潔,參見輪播圖優(yōu)化篇: http://www.fzitv.net/article/123304.htm

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • 用JS實現(xiàn)圖片輪播效果代碼(一)

    用JS實現(xiàn)圖片輪播效果代碼(一)

    這篇文章主要介紹了用JS實現(xiàn)圖片輪播效果代碼(一)的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • JavaScript中獲得CheckBox狀態(tài)的方法小結

    JavaScript中獲得CheckBox狀態(tài)的方法小結

    在 JavaScript 中,獲取復選框(CheckBox)的狀態(tài)(選中或未選中)可以通過以下幾種方式實現(xiàn),以下是具體方法及示例,并通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2025-03-03
  • JavaScript實現(xiàn)換膚功能

    JavaScript實現(xiàn)換膚功能

    js換膚功能的實現(xiàn)原理非常簡單,就是使用js切換對應的css樣式表文件,本文重點給大家介紹JavaScript實現(xiàn)換膚功能,感興趣的朋友參考下吧
    2017-09-09
  • ZeroClipboard.js使用一個flash復制多個文本框

    ZeroClipboard.js使用一個flash復制多個文本框

    這篇文章主要為大家詳細介紹了ZeroClipboard.js使用一個flash復制多個文本框,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • JavaScript flash復制庫類 Zero Clipboard

    JavaScript flash復制庫類 Zero Clipboard

    開發(fā)中經(jīng)常會用到復制的功能,在 IE 下實現(xiàn)比較簡單。但要想做到跨瀏覽器比較困難了。
    2011-01-01
  • 【消息提示組件】,兼容IE6/7&&FF2

    【消息提示組件】,兼容IE6/7&&FF2

    【消息提示組件】,兼容IE6/7&&FF2...
    2007-09-09
  • 什么是cookie?js手動創(chuàng)建和存儲cookie

    什么是cookie?js手動創(chuàng)建和存儲cookie

    cookie 是存儲于訪問者的計算機中的變量,在這個例子中我們要創(chuàng)建一個存儲訪問者名字的 cookie,需要的朋友可以參考下
    2014-05-05
  • js 窗口抖動示例

    js 窗口抖動示例

    想必大家對窗口抖動一詞并不陌生吧,其實原理很簡單,下面為大家簡單介紹下js中時如何實現(xiàn)的,喜歡的朋友可以參考下
    2013-09-09
  • 不使用瀏覽器運行javascript代碼的方法

    不使用瀏覽器運行javascript代碼的方法

    用js寫一段小程序,但是又覺得使用瀏覽器去運行挺麻煩的,下面為大家介紹下如何使用java程序調用javascript程序,有類似需求的朋友可以參考下哈,希望對大家有所幫助
    2013-07-07
  • BootstrapValidator不觸發(fā)校驗的實現(xiàn)代碼

    BootstrapValidator不觸發(fā)校驗的實現(xiàn)代碼

    BootstrapValidator是基于bootstrap3的jquery表單驗證插件,是最適合bootstrap框架的表單驗證插件,本文給大家介紹BootstrapValidator不觸發(fā)校驗的實現(xiàn)代碼,感興趣的朋友一起看看吧
    2016-09-09

最新評論

石渠县| 福建省| 广灵县| 南陵县| 平谷区| 丹东市| 延川县| 连南| 尼玛县| 同仁县| 同仁县| 宝应县| 鄂托克前旗| 双桥区| 双牌县| 文山县| 松滋市| 延边| 永安市| 岑溪市| 桂林市| 兴义市| 金阳县| 越西县| 都江堰市| 白水县| 江城| 庆安县| 博野县| 吉木乃县| 湟源县| 攀枝花市| 绥宁县| 青田县| 阿克陶县| 自治县| 利津县| 密山市| 葵青区| 孟津县| 女性|