es6+移動輪播插件

前言:以前趕項目,都是直接用框架,對於touch事件是模擬兩可,趁着有心情,用es6寫一個原生移動輪播插件。html

用了es6的新特性,確實挺爽的,說到es6,就不得不說到babel,博主已經碼好了,直接用就行了。下面簡單說一下如何「搭環境」。java

用Gulp、Babel等爲瀏覽器構建ES6環境

[注意:該環節默認你電腦已經有node,gulp環境]node

  • 項目目錄下,運行 npm init
  • 找到package.json文件,找到dependencies,修改以下
 1 "dependencies": {
 2     "babel-preset-es2015": "^6.5.0",
 3     "gulp-load-plugins": "^1.1.0",
 4     "gulp-babel": "^6.1.2",
 5     "gulp-plumber": "^1.0.1",
 6     "gulp-rename": "^1.2.2",
 7     "gulp": "^3.9.1",
 8     "gulp-jshint": "^2.0.0",
 9     "gulp-concat": "^2.6.0",
10     "gulp-uglify": "^1.4.1",
11     "gulp-util": "^3.0.1"
12   }
  • 命令行  運行npm install  [該命令會安裝package裏面全部的依賴包,因此開發項目時,最好使用npm install --save '' ,方便其餘合做者安裝項目所須要的包]
  • 在根目錄下 新建gulpfile.js
 1 const gulp = require('gulp'),
 2     concat = require('gulp-concat'),
 3     rename = require('gulp-rename'),
 4     jshint = require('gulp-jshint'),
 5     uglify = require('gulp-uglify');
 6 
 7 
 8 // Load plugins
 9 const $ = require('gulp-load-plugins')();
10 
11 /* es6 */
12 gulp.task('es6', function () {
13     return gulp.src('src/js/*.js')
14         .pipe($.plumber())
15         .pipe($.babel({
16             presets: ['es2015']
17         }))
18         .pipe(gulp.dest('dist/js/'));
19 });
20 
21 gulp.task('watch', ['es6'], function () {
22     gulp.watch(['src/js/*.js'], ['es6']);
23 });
24 
25 // 默認任務
26 gulp.task('default', function () {
27     gulp.run('watch');
28 });

[注意:上面的目錄須要 更改成實際項目 的目錄]git

  • 命令行 運行 gulp 編譯 便可。  

項目總體架構

 1 class Slider {
 2     /*構造函數*/
 3     constructor(opts) {
 4         this.wrap = opts.dom;
 5         this.list = opts.list;
 6         this.init();
 7     }
 8     /*初始化*/
 9     init() {}
10     /*繪製dom*/
11     renderDOM() {}
12     goIndex(n) {}
13     bindDOM() {}
14 }

調用方式

 1  var list = [{
 2         img: "src/imgs/1.jpg"
 3     }, {
 4         img: "src/imgs/2.jpg"
 5     }, {
 6         img: "src/imgs/3.jpg"
 7     }, {
 8         img: "src/imgs/4.jpg"
 9     }, {
10         img: "src/imgs/5.jpg",
11     }, {
12         img: "src/imgs/6.jpg",
13     }, {
14         img: "src/imgs/7.jpg",
15     }];
16 
17     var x = new Slider({
18         'dom': document.getElementById('canvas'),
19         'list': list
20     });

項目實現原理

  • 繪製dom結構
 1  renderDOM() {
 2         let wrap = this.wrap,
 3             data = this.list,
 4             i = 0,
 5             html = [];
 6         this.outer = document.createElement('ul');
 7 
 8         for (let val of data) {
 9             if (val) {
10                 html.push(`<li style="transform: translate3d(${i * this.scaleW}px ,0,0)">
11                     <img src="${val['img']}" alt="img" width="${window.innerWidth}px" height="180px" />
12                   </li>`);
13             }
14             i++;
15         }
16         this.outer.innerHTML = html.join('');
17         wrap.appendChild(this.outer);
18     }
  • 根據手指移動方向 判斷向左(右)移動
1   /*手指開始的事件*/
2  let startHandle = (evt)=> {}
3  /*手指移動的處理事件*/
4  let moveHandler = (evt)=> {}
5  /*手指擡起的事件*/
6 let endHandler = (evt)=> {}
 1 let endHandler = (evt)=> {
 2             evt.preventDefault();
 3             let boundary = scaleW / 6,
 4                 endTime = new Date() * 1;
 5             /*
 6              * 手指滑動距離超過 boundary 翻頁
 7              * 當手指移動時間超過300ms的時候,按位移算
 8              * */
 9             if (endTime - this.startTime > 300) {
10                 if (this.offsetX >= boundary) {/*進入上一頁*/
11                     this.goIndex('-1');
12                 } else if (this.offsetX < 0 && this.offsetX < -boundary) {/*進入下一頁*/
13                     this.goIndex('+1');
14                 } else {/*留在本頁*/
15                     this.goIndex('0');
16                 }
17             } else {
18                 /*快速滑動的時候,較少滑動的間隔,便可滑動*/
19                 if (this.offsetX > 50) {
20                     this.goIndex('-1');
21                 } else if (this.offsetX < -50) {
22                     this.goIndex('+1');
23                 } else {
24                     this.goIndex('0');
25                 }
26             }
27         };

綁定事件

1  outer.addEventListener('touchstart', startHandle);
2  outer.addEventListener('touchmove', moveHandler);
3  outer.addEventListener('touchend', endHandler);

 

使用es6開發有什麼顯著優點?

  • 使用es6新增的類class,不須要像下面這樣的寫法去模擬類
 1 function Slider(opts) {
 2     this.wrap = opts.dom;
 3     this.list = opts.list;
 4     this.init();
 5 }
 6 Slider.prototype = {
 7     init: function () {},
 8     renderDOM: function () {},
 9     bindDOM: function () {},
10     goIndex: function (n) {}
11 }

優勢:直觀上,es6更容易理解,寫法也更爲簡單。es6

1.constructor: 構造方法,構造方法裏面的this,指向的是該類實例化後的對象。github

constructor是一個類必需要有的方法,也是惟一的。若是你沒有編寫constructor方法,執行的時候也會被加上一個默認的空的constructor方法。npm

2.相似於java,它也有靜態方法,顧名思義,就是不須要實例化就能夠直接調用該方法,直接看例子更容易理解json

 1 class Animal {
 2     //構造方法
 3     constructor(name){
 4         this.name = name;
 5     }
 6     //自定義一個靜態方法
 7     static friends(a1,a2){
 8         console.log(`${a1} and ${a2} are friends`);
 9     }
10     sayHello(){
11         console.log('hello');
12     }
13 }
14 //調用靜態方法
15 Animal.friends('dog','cat');//dog and cat are friends
16 Animal.sayHello();  //出錯
17 var animal = new Animal('dog');
18 animal.sayHello();  //hello
  • 該例子中還使用了es6的另外一個特性——模版字符串

上面的例子,若是用以前的實現方式,就要gulp

1 (a1 + 'and' + a2 + 'are friends');

注意:canvas

1.在``中,換行也會被保存,[``是否是有點像markdown 哈哈 ]若是不想要換行,使用trim方法消除它,一樣的,舉個例子

1 $('#list').html(`
2 <ul>
3   <li>first</li>
4   <li>second</li>
5 </ul>
6 `.trim());

2.嵌入變量,將變量名寫在${}之中,{}中能夠進行運算,還能夠調用函數

  • 函數 默認傳參

傳統實現方式:

1  function person(n,a){
2         var name = n || 'Zhangsan';
3         var age  = a ||  25;
4  }

缺點:參數對應的布爾值不能false(好比:數字0,空字符串等轉換成布爾值就是false)

新新方式:

1 function person(name = 'Zhangsan',age = 25){
2        console.log(name,age);
3 }
4     
5 person();//結果:Zhangsan  25
6 person('Lisi',18);//結果:Lisi  18

注意:設定默認值的參數必定要放在最後,否則會出錯

  • 箭頭函數
 1 //傳統實現方法
 2 var obj = {
 3     x:100,
 4     show(){  //對象方法的簡單寫法
 5         setTimeout(
 6             function(){console.log(this.x);},
 7             500
 8         );
 9     }
10 };
11 obj.show();//打印結果:undefined
12 //es6箭頭函數
13 var obj = {
14     x:100,
15     show(){
16         setTimeout(
17             //不一樣處:箭頭函數
18             () => { console.log(this.x)},
19             500
20         );
21     }
22 };
23 obj.show();//打印結果:100

仔細看看上面的例子,爲何第一個輸出的是undefined?

問題出在了this上,當代碼執行到了setTimeout( )的時候,此時的this已經變成了window對象(setTimeout( )是window對象的方法),已經再也不是obj對象了,因此咱們用this.x獲取的時候,獲取的不是obj.x的值,而是window.x的值,再加上window上沒有定義屬性x,因此獲得的結果就是:undefined。

不懂this指向的能夠看看個人另外一篇博客:http://www.cnblogs.com/beidan/p/5371275.html

再對比箭頭函數

一樣的一段代碼,惟一的不用就是setTimeout中,本來的匿名函數用箭頭函數代替了。神奇的是由於

優勢:
1. 箭頭函數中的this指向的是定義時的this,而不是執行時的this
2.  箭頭函數沒有獨立的this, 因此有些狀況,好比事件調用,須要緩存this,可是用箭頭函數就不用啦
3.看上面,箭頭函數簡化函數的實現,大大地減小代碼量,真是不錯的特性

 

還有另一些es6的新特性,也是挺不錯的, 推薦[排名不分前後]

let,const,for of,繼承,rest參數,模塊,解構,promise…………

還有哪些屬性比較常使用,請告訴我,謝謝~~~

 

github地址:https://github.com/beidan/slide

若是這篇博文對你有幫助,請給我star或者fork,謝謝~

相關文章
相關標籤/搜索