zoukankan      html  css  js  c++  java
  • es6+移动轮播插件

    前言:之前赶项目,都是直接用框架,对于touch事件是模拟两可,趁着有心情,用es6写一个原生移动轮播插件。

    用了es6的新特性,确实挺爽的,说到es6,就不得不说到babel,博主已经码好了,直接用就好了。下面简单说一下如何“搭环境”。

    用Gulp、Babel等为浏览器构建ES6环境

    [注意:该环节默认你电脑已经有node,gulp环境]

    • 项目目录下,运行 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 });

    [注意:上面的目录需要 更改为实际项目 的目录]

    • 命令行 运行 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更容易理解,写法也更为简单。

    1.constructor: 构造方法,构造方法里面的this,指向的是该类实例化后的对象。

    constructor是一个类必须要有的方法,也是唯一的。如果你没有编写constructor方法,执行的时候也会被加上一个默认的空的constructor方法。

    2.类似于java,它也有静态方法,顾名思义,就是不需要实例化就可以直接调用该方法,直接看例子更容易理解

     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的另一个特性——模版字符串

    上面的例子,如果用之前的实现方式,就要

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

    注意:

    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,谢谢~

  • 相关阅读:
    iOS推送通知
    KVO内部实现原理
    沙盒目录结构
    UITableView的常用属性和代理方法
    优秀文章的链接
    c++面试题
    递归练习
    c#连接mysql环境配置
    mysql命令详解
    十进制转二进制
  • 原文地址:https://www.cnblogs.com/beidan/p/5759320.html
Copyright © 2011-2022 走看看