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 相关文章推荐
jquery 插件开发备注
Aug 27 Javascript
全面理解面向对象的 JavaScript(来自ibm)
Nov 10 Javascript
js 数值转换为3位逗号分隔的示例代码
Feb 19 Javascript
jQuery根据用户电脑是mac还是pc加载对应样式的方法
Jun 26 Javascript
Javascript操作表单实例讲解(下)
Jun 20 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
Nov 02 Javascript
JS使用ActiveXObject实现用户提交表单时屏蔽敏感词功能
Jun 20 Javascript
Angular中的$watch、$watchGroup、$watchCollection
Jun 25 Javascript
JS实现用特殊符号替换字符串的中间部分区域的实例代码
Jul 24 Javascript
解决Layui中templet中a的onclick参数传递的问题
Sep 20 Javascript
layui时间控件选择时间范围的实现方法
Sep 28 Javascript
Vue数字输入框组件使用方法详解
Feb 10 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设计模式之单例模式使用示例
2014/01/20 PHP
xss防御之php利用httponly防xss攻击
2014/03/21 PHP
php之Smarty模板使用方法示例详解
2014/07/08 PHP
ThinkPHP3.2.3数据库设置新特性
2015/03/05 PHP
php自动更新版权信息显示的方法
2015/06/19 PHP
php查询内存信息操作示例
2019/05/09 PHP
用js+xml自动生成表格的东西
2006/12/21 Javascript
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
js动态添加onclick事件可传参数与不传参数
2014/07/29 Javascript
JQuery中serialize()、serializeArray()和param()方法示例介绍
2014/07/31 Javascript
你所未知的3种Node.js代码优化方式
2016/02/25 Javascript
详解VueJs中的V-bind指令
2018/05/03 Javascript
VUE中v-on:click事件中获取当前dom元素的代码
2018/08/22 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
vue项目每30秒刷新1次接口的实现方法
2018/12/04 Javascript
vue与django集成打包的实现方法
2019/11/11 Javascript
浅谈Vue 自动化部署打包上线
2020/06/14 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
python发送邮件的实例代码(支持html、图片、附件)
2013/03/04 Python
Python set集合类型操作总结
2014/11/07 Python
python批量添加zabbix Screens的两个脚本分享
2017/01/16 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
2019/06/17 Python
python替换字符串中的子串图文步骤
2019/06/19 Python
使用Python实现牛顿法求极值
2020/02/10 Python
Django添加bootstrap框架时无法加载静态文件的解决方式
2020/03/27 Python
如何基于Python实现word文档重新排版
2020/09/29 Python
焊接专业毕业生求职信
2013/10/01 职场文书
写好自荐信的要点
2013/11/06 职场文书
医院总经理岗位职责
2014/02/04 职场文书
答谢会策划方案
2014/05/12 职场文书
预备党员转正考核材料
2014/06/03 职场文书
党性分析自查总结
2014/10/14 职场文书
机关工会工作总结2015
2015/05/26 职场文书
Python实战之大鱼吃小鱼游戏的实现
2022/04/01 Python