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技术-屏蔽类
Aug 15 Javascript
javascript使用正则表达式实现去掉空格之后的字符
Feb 15 Javascript
js实时获取并显示当前时间的方法
Jul 31 Javascript
EasyUI中的dataGrid的行内编辑
Jun 22 Javascript
详解微信小程序设置底部导航栏目方法
Jun 29 Javascript
jQuery实现的事件绑定功能基本示例
Oct 11 jQuery
vue中手机号,邮箱正则验证以及60s发送验证码的实例
Mar 16 Javascript
通过js示例讲解时间复杂度与空间复杂度
Aug 06 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
Sep 04 Javascript
vue将文件/图片批量打包下载zip的教程
Oct 21 Javascript
js简单粗暴的发布订阅示例代码
Jan 23 Javascript
深入了解Vue动态组件和异步组件
Jan 26 Vue.js
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下实现折线图效果的代码
2007/04/28 PHP
简化php模板页面中分页代码的解析
2009/02/06 PHP
php最简单的删除目录与文件实现方法
2014/11/28 PHP
PHP+APACHE实现网址伪静态
2015/02/22 PHP
php限制上传文件类型并保存上传文件的方法
2015/03/13 PHP
php array_merge函数使用需要注意的一个问题
2015/03/30 PHP
实例分析PHP中PHPMailer发邮件
2017/12/13 PHP
PHP实现简单计算器小程序
2020/08/28 PHP
扩展javascript的Date方法实现代码(prototype)
2010/11/20 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
JavaScript实现拼音排序的方法
2012/11/20 Javascript
jQuery仿Excel表格编辑功能的实现代码
2013/05/01 Javascript
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
使用AngularJS处理单选框和复选框的简单方法
2015/06/19 Javascript
javascript实现信息增删改查的方法
2015/07/25 Javascript
JavaScript prototype属性详解
2016/10/25 Javascript
如何在AngularJs中调用第三方插件库
2017/05/21 Javascript
vue路由懒加载的实现方法
2018/03/12 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
2020/03/09 Javascript
Python类和对象的定义与实际应用案例分析
2018/12/27 Python
python获取点击的坐标画图形的方法
2019/07/09 Python
python使用Pandas库提升项目的运行速度过程详解
2019/07/12 Python
Python 面向对象之类class和对象基本用法示例
2020/02/02 Python
Django DRF路由与扩展功能的实现
2020/06/03 Python
pytorch 常用函数 max ,eq说明
2020/06/28 Python
Django搭建项目实战与避坑细节详解
2020/12/06 Python
家用个人磨皮机:Trophy Skin
2017/03/30 全球购物
护理工作感言
2014/01/16 职场文书
研究生考核个人自我鉴定
2014/03/27 职场文书
民政局个人整改措施
2014/09/24 职场文书
入股合作协议书
2014/10/12 职场文书
2014年仓库管理员工作总结
2014/11/18 职场文书
2014年效能监察工作总结
2014/11/21 职场文书
六五普法学习心得体会
2016/01/21 职场文书