Vue实现移动端拖拽交换位置


Posted in Javascript onJuly 29, 2020

本文实例为大家分享了Vue实现移动端拖拽交换位置的具体代码,供大家参考,具体内容如下

<template>
  <div class="imageUploaderPage">
    <ul ref='imgList' class="imgList">
      <li ref='imgItem' class="imgCoverItem" v-for='(item, index) in filesResults' :key='index' @click="deleteImage(index)"
      :data-index='index'
      @touchstart="touchstart($event, item, index)"
      @touchmove="touchmove($event)"
      @touchend="touchend($event)" >
        <img :id="'avarimgs' + index" :src="item">
      </li>
      <li class="imgCoverItem upLoadImageWrapper">
        <input ref='upLoadImageFile' id='upLoadImage' type='file' multiple="multiple" accept="image/*" @change="change" />
      </li>
    </ul>
    <p>点击图片删除, 拖拽可更改顺序,共4张</p>
    <div class="btnConfimList" v-show="DeleteImageMask">
      <div class="btnConfimListMask" @click='setDelete(false)'></div>
      <transition name="transTop">
       <div class="btnConfimListContent">
        <ul>
         <li class="borderT" >删除该图片?</li>
         <li class="borderT" @click='setDelete(true)' style="color: var(--mRed);">删除</li>
        </ul>
        <p class="cancelDeleteImage" @click='setDelete(false)'>取消</p>
       </div>
      </transition>
    </div>
  </div>
</template>
<script>
export default {
 data () {
  return {
   files: [],
   fileItem: {},
   filesResults: [],
   DeleteImageMask: false,
   // isShow:false,
   startX: 0, // 开始触摸的位置
   startY: 0,
   moveX: 0, // 滑动时的位置
   moveY: 0,
   endX: 0,
   endY: 0, // 结束触摸的位置
   disX: 0, // 移动距离
   disY: 0,
   slideEffect: [], // 滑动时的效果
   target: null,
   startIndex: null,
   zindex: 1,
   leftW: 0,
   targetW: 0,
   clientW: 0,
   targetX: 0,
   targetY: 0,
   allItems: [],
   targetIndex: null
  }
 },
 // computed: {
 //  toRightW () { return (this.leftW + this.targetW) * (this.startIndex + 1) - this.startX },
 //  toLeftW () { return this.startX - (this.leftW + this.targetW) * this.startIndex },
 //  toTopH () { return this.startY - parseInt(this.startIndex / 4) * (this.topH + this.targetW) },
 //  toBottomH () { return (this.topH + this.targetW) - this.startY + (this.leftW + this.targetW) * (parseInt(this.startIndex / 4)) }
 // },
 mounted () {
  this.$nextTick(() => {
   this.absoluteItems()
  })
 },
 watch: {
  slideEffect (newV) {
   return newV
  }
 },
 methods: {
  change (e) {
   var fileItem = e.target.files
   let me = this
   for (let i = e.target.files.length - 1; i >= 0; i--) {
    var reader = new FileReader()
    var file = e.target.files[i]
    reader.onloadstart = function (e) {
     // console.log('开始读取....')
    }
    reader.onprogress = function (e) {
     // console.log('正在读取中....')
    }
    reader.onabort = function (e) {
     // console.log('中断读取....')
    }
    reader.onerror = function (e) {
     // console.log('读取异常....')
    }
    reader.onload = function (e) {
     if (me.filesResults.indexOf(e.target.result) >= 0) {
      me.$toast('请勿重复上传')
      return
     }
     if (me.files.length >= 7) {
      me.$toast('最多上传4张图片')
      return
     }
     me.files.unshift(fileItem)
     me.filesResults.unshift(e.target.result)
    }
    reader.readAsDataURL(file)
   }
  },
  absoluteItems () {
   for (let i = 0; i < 8; i++) {
    this.allItems = []
   }
  },
  deleteImage (index) {
   this.curIndex = index
   this.DeleteImageMask = true
  },
  setDelete (data) {
   this.DeleteImageMask = false
   this.curIndex = null
   data && this.curIndex >= 0 && this.files.splice(this.curIndex, 1) && this.filesResults.splice(this.curIndex, 1)
  },
  touchstart (e, item, index) {
   this.startIndex = index
   this.targetIndex = index
   this.target = e.target.nodeName.toLowerCase() === 'li' ? e.target : e.target.parentNode
   !this.leftW && (this.leftW = this.target.parentNode.querySelectorAll('li')[0].getBoundingClientRect().left)
   !this.topH && (this.topH = this.target.parentNode.querySelectorAll('li')[0].getBoundingClientRect().top)
   !this.targetW && (this.targetW = this.target.offsetWidth)
   !this.clientW && (this.clientW = this.leftW + this.targetW)
   this.zindex++
   this.target.style.zIndex = this.zindex
   this.startX = e.touches[0].clientX
   this.startY = e.touches[0].clientY
  },
  touchmove (ev) {
   ev = ev || window.event
   ev.preventDefault()
   if (ev.touches.length === 1) {
    this.moveX = ev.touches[0].clientX
    this.moveY = ev.touches[0].clientY
    this.disX = this.moveX - this.startX
    this.disY = this.moveY - this.startY
    // 边界处理
    this.disY <= 0 && (this.disY = 0)
    this.disY >= (this.$refs.imgList.offsetHeight - this.clientW) && (this.disY = this.$refs.imgList.offsetHeight - this.clientW)
    this.target.style.transform = 'translate3d(' + this.disX + 'px,' + this.disY + 'px, 0)'
    this.target.getBoundingClientRect().left <= 0 && (this.target.style.transform = 'translate3d(' + (-this.clientW * this.startIndex) + 'px,' + this.disY + 'px, 0)')
    this.target.getBoundingClientRect().right >= this.$refs.imgList.offsetWidth && (this.target.style.transform = 'translate3d(' + this.clientW * (3 - this.startIndex) + 'px,' + this.disY + 'px, 0)')
    for (let i = 0; i < this.filesResults.length; i++) {
     // && this.moveY > this.$refs.imgItem[i].getBoundingClientRect().top && this.moveY < this.$refs.imgItem[i].getBoundingClientRect().top + this.targetW
     if (this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW && (i !== this.startIndex)) {
      if (i > this.targetIndex && this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW) {
       if (this.$refs.imgItem[i].style.transform) {
        if (this.$refs.imgItem[i].style.transform === 'translate3d(0px, 0px, 0px)') {
         this.$refs.imgItem[i].style.transform = 'translate3d(' + (-this.clientW) + 'px, 0, 0)'
         this.targetIndex = i
        } else {
         this.$refs.imgItem[i].style.transform = 'translate3d(0px, 0px, 0px)'
         this.targetIndex = i - 1
        }
       } else {
        this.$refs.imgItem[i].style.transform = 'translate3d(' + (-this.clientW) + 'px, 0, 0)'
        this.targetIndex = i
       }
      } else if (i < this.targetIndex && this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW) {
       if (this.$refs.imgItem[i].style.transform) {
        if (this.$refs.imgItem[i].style.transform === 'translate3d(0px, 0px, 0px)') {
         this.$refs.imgItem[i].style.transform = 'translate3d(' + (this.clientW) + 'px, 0, 0)'
         this.targetIndex = i
        } else {
         this.$refs.imgItem[i].style.transform = 'translate3d(0px, 0px, 0px)'
         this.targetIndex = i + 1
        }
       } else {
        this.$refs.imgItem[i].style.transform = 'translate3d(' + (this.clientW) + 'px, 0, 0)'
        this.targetIndex = i
       }
      } else {
       this.targetIndex > this.startIndex && (this.targetIndex = i - 1)
       this.targetIndex < this.startIndex && (this.targetIndex = i + 1)
      }
     }
    }
   }
  },
  touchend (e) {
   this.target.style.transform = 'translate3d(' + (this.targetIndex - this.startIndex) * (this.leftW + this.targetW) + 'px,' + this.targetY + 'px, 0)'
   let start = this.filesResults.splice(this.startIndex, 1)[0]
   this.filesResults.splice(this.targetIndex, 0, start)
   for (let i = 0; i < this.filesResults.length; i++) {
    this.$refs.imgItem[i].style.transform = 'none'
   }
  }
 }
}
</script>
<style lang="less">
 .imageUploaderPage{
  background: #f0f0f3;
  color: #a8a8a8;
  overflow: hidden;
  p{
    text-align: center;
    color: #a7a7a7;
    height: 4.07vw;
    line-height: 4.07vw;
    font-size: var(--mText);
    margin-bottom: var(--nText);
  }
  .imgList{
   padding: 2.78vw 0;
   font-size: 0;
   position: relative;
   .imgCoverItem{
    position: relative;
    width: 23.25vw;
    height: 23.25vw;
    border-radius: 1.11vw;
    display: inline-block;
    vertical-align: top;
    overflow: hidden;
    margin-left: 1.4vw;
    margin-bottom: 1.4vw;
   }
   .upLoadImageWrapper{
    position: relative;
    background: #e0e0e0;
    #upLoadImage{
     position: absolute;
     outline: none;
     z-index: 1;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
     opacity: 0;
    }
   }
  }
 }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。 

Javascript 相关文章推荐
javascript 数据类型转换(parseInt,parseFloat)
Jul 20 Javascript
关于用Jquery的height()、width()计算动态插入的IMG标签的宽高的问题
Dec 08 Javascript
js获取多个tagname的节点数组
Sep 22 Javascript
node.js中的favicon.ico请求问题处理
Dec 15 Javascript
教你使用javascript简单写一个页面模板引擎
May 05 Javascript
js按条件生成随机json:randomjson实现方法
Apr 07 Javascript
JavaScript实现无穷滚动加载数据
May 06 Javascript
vue+vuex+axios实现登录、注册页权限拦截
Mar 09 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
Sep 04 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
Jan 08 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
Dec 04 Javascript
如何在Express4.x中愉快地使用async的方法
Nov 18 Javascript
vue和H5 draggable实现拖拽并替换效果
Jul 29 #Javascript
vue同个按钮控制展开和折叠同个事件操作
Jul 29 #Javascript
JavaScript编写开发动态时钟
Jul 29 #Javascript
js编写简易的计算器
Jul 29 #Javascript
从0到1学习JavaScript编写贪吃蛇游戏
Jul 28 #Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
Jul 28 #Javascript
Node.js 深度调试方法解析
Jul 28 #Javascript
You might like
PHP 设计模式之观察者模式介绍
2012/02/22 PHP
有关PHP中MVC的开发经验分享
2012/05/17 PHP
PHP Session 变量的使用方法详解与实例代码
2013/09/11 PHP
PHP进程同步代码实例
2015/02/12 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
2016/10/08 PHP
PHP实现会员账号单唯一登录的方法分析
2019/03/07 PHP
JQuery 选项卡效果(JS与HTML的分离)
2010/04/01 Javascript
JavaScript 创建运动框架的实现代码
2013/05/08 Javascript
jquery控制display属性为none或block
2014/03/31 Javascript
JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码
2015/09/15 Javascript
JS实现iframe自适应高度的方法(兼容IE与FireFox)
2016/06/24 Javascript
微信小程序-小说阅读小程序实例(demo)
2017/01/12 Javascript
jquery,js简单实现类似Angular.js双向绑定
2017/01/13 Javascript
JS中cookie的使用及缺点讲解
2017/05/13 Javascript
详解angular中的作用域及继承
2017/05/31 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
2018/08/07 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
2019/03/06 Javascript
详解JSON和JSONP劫持以及解决方法
2019/03/08 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
PHP webshell检查工具 python实现代码
2009/09/15 Python
TensorFlow实现RNN循环神经网络
2018/02/28 Python
pyspark 读取csv文件创建DataFrame的两种方法
2018/06/07 Python
python 日志 logging模块详细解析
2020/03/31 Python
使用matplotlib动态刷新指定曲线实例
2020/04/23 Python
全球速卖通巴西站点:Aliexpress巴西
2016/08/24 全球购物
捐书寄语赠言
2014/01/18 职场文书
建议书的格式
2014/05/12 职场文书
不忘国耻振兴中华演讲稿
2014/05/14 职场文书
授权委托书协议书
2014/10/16 职场文书
2014年公务员工作总结
2014/11/18 职场文书
齐云山导游词
2015/02/06 职场文书
2015年学校财务工作总结
2015/05/19 职场文书
2016年“11.11”光棍节活动总结
2016/04/05 职场文书
Python机器学习之PCA降维算法详解
2021/05/19 Python
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis