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 相关文章推荐
flash 得到自身url参数的代码
Nov 15 Javascript
过虑特殊字符输入的js代码
Aug 05 Javascript
IE6、IE7中获取Button元素的值的bug说明
Aug 28 Javascript
jquery连缀语法如何实现
Nov 29 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
May 14 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
Jun 14 Javascript
关于页面刷新vuex数据消失问题解决方案
Jul 03 Javascript
基于jQuery解决ios10以上版本缩放问题
Nov 03 jQuery
vue初始化动画加载的实例
Sep 01 Javascript
关于js陀螺仪的理解分析
Apr 11 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
Mar 10 Javascript
详解JS预解析原理
Jun 16 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获取当前url路径的函数以及服务器变量
2013/06/29 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
php加密解密字符串示例
2016/10/13 PHP
遍历指定目录,并存储目录内所有文件属性信息的php代码
2016/10/28 PHP
php实现用户登陆简单实例
2017/04/04 PHP
基于ThinkPHP5框架使用QueryList爬取并存入mysql数据库操作示例
2019/05/25 PHP
NodeJS url验证(url-valid)的使用方法
2013/11/18 NodeJs
一个JavaScript的求爱小特效
2014/05/09 Javascript
js获取域名的方法
2015/01/27 Javascript
JavaScript实现LI列表数据绑定的方法
2015/08/04 Javascript
javascript实现2016新年版日历
2016/01/25 Javascript
一道常被人轻视的web前端常见面试题(JS)
2016/02/15 Javascript
一分钟理解js闭包
2016/05/04 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
2016/05/13 Javascript
jQuery利用sort对DOM元素进行排序操作
2016/11/07 Javascript
angularjs实现时间轴效果的示例代码
2017/11/29 Javascript
详解angular2如何手动点击特定元素上的点击事件
2018/10/16 Javascript
layui table数据修改的回显方法
2019/09/04 Javascript
javascript 对象 与 prototype 原型用法实例分析
2019/11/11 Javascript
Python3 伪装浏览器的方法示例
2017/11/23 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
Python中Subprocess的不同函数解析
2019/12/10 Python
canvas实现有递增动画的环形进度条的实现方法
2019/07/10 HTML / CSS
柏林通行证:Berlin Pass
2018/04/11 全球购物
ESDlife健康生活易:身体检查预订、搜寻及比较
2019/05/10 全球购物
字符串str除首尾字符外的其他字符按升序排列
2013/03/08 面试题
25道Java面试题集合
2013/05/21 面试题
车间副主任岗位职责
2013/12/24 职场文书
公司授权委托书
2014/04/04 职场文书
就业协议书范本
2014/04/11 职场文书
培训协议书范本
2014/04/22 职场文书
学校学习雷锋活动总结
2014/07/03 职场文书
门面房租房协议书
2014/08/20 职场文书
大连导游词
2015/02/12 职场文书
追悼会答谢词范文
2015/09/29 职场文书