感谢本文参考地址:https://www.jb51.net/article/255385.htm
怕原链接失效,将代码拷贝(如有侵权,请联系删除,感谢!!)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div> 3 <ul> 4 <li 5 class="libox" 6 v-for="(item, index) in list" 7 :key="index" 8 :id="'card' + (index + 1)" 9 > 10 <div 11 @touchstart="touchstart($event, item)" 12 @touchmove="touchMove($event, item)" 13 @touchend="touchEnd($event, item)" 14 v-show="item.name !== selectItem.name" 15 > 16 {{item.name}} 17 <svg class="icon svg-icon" aria-hidden="true"> 18 <use :xlink:href="item.icon" rel="external nofollow" ></use> 19 </svg> 20 </div> 21 </li> 22 <li v-show="selectItem.name" class="selectBox" ref="selectBox"> 23 {{selectItem.name}} 24 <svg class="icon svg-icon" aria-hidden="true"> 25 <use :xlink:href="selectItem.icon" rel="external nofollow" ></use> 26 </svg> 27 </li> 28 </ul> 29 </div> 30 </template> 31 32 <script> 33 34 export default { 35 data() { 36 return { 37 // 列表数据 38 list: [ 39 { name: '1', selected: true, icon: '#icon-mianxingbenzivg' }, 40 { name: '2', selected: true, icon: '#icon-mianxingchizi' }, 41 { name: '3', selected: true, icon: '#icon-mianxingdiannao' }, 42 { name: '4', selected: true, icon: '#icon-mianxingdayinji' }, 43 { name: '5', selected: true, icon: '#icon-mianxingdingshuqi' }, 44 { name: '6', selected: true, icon: '#icon-mianxingheiban' }, 45 { name: '7', selected: true, icon: '#icon-mianxinggangbi' }, 46 { name: '8', selected: true, icon: '#icon-mianxingboshimao' }, 47 { name: '9', selected: true, icon: '#icon-mianxingjisuanqi' }, 48 { name: '10', selected: true, icon: '#icon-mianxinghuaxue' }, 49 { name: '11', selected: true, icon: '#icon-mianxingqianbi' }, 50 { name: '12', selected: true, icon: '#icon-mianxingshubao' }, 51 { name: '13', selected: true, icon: '#icon-mianxingshuicaibi' }, 52 { name: '14', selected: true, icon: '#icon-mianxingtushu' }, 53 ], 54 // 选中元素内容 55 selectItem: {}, 56 timeOutEvent: 0, 57 oldNodePos: { 58 x: 0, 59 y: 0, 60 }, 61 oldMousePos: { 62 x: 0, 63 y: 0 64 }, 65 oldIndex: 0, 66 // 长按标识 67 longClick: 0 68 }; 69 }, 70 watch: { 71 oldIndex(newVal) { 72 const oldIndex = this.list.findIndex(r=> r.name === this.selectItem.name); 73 this.list.splice(oldIndex, 1); 74 this.list.splice(newVal, 0, this.selectItem); 75 } 76 }, 77 methods: { 78 touchstart(ev, item) { 79 this.longClick = 0; 80 const that = this; 81 const selectDom = ev.currentTarget; // div元素 82 this.timeOutEvent = setTimeout(() => { 83 that.longClick = 1; 84 that.selectItem = item; 85 // 元素初始位置 86 that.oldNodePos = { 87 x: selectDom.offsetLeft, 88 y: selectDom.offsetTop 89 }; 90 // 鼠标原始位置 91 that.oldMousePos = { 92 x: ev.touches[0].pageX, 93 y: ev.touches[0].pageY 94 }; 95 const lefts = that.oldMousePos.x - that.oldNodePos.x; // x轴偏移量 96 const tops = that.oldMousePos.y - that.oldNodePos.y; // y轴偏移量 97 const { pageX, pageY } = ev.touches[0]; // 手指位置 98 that.$refs.selectBox.style.left = `${pageX - lefts}px`; 99 that.$refs.selectBox.style.top = `${pageY - tops}px`; 100 }, 500); 101 }, 102 touchMove(ev) { 103 clearTimeout(this.timeOutEvent); 104 const selectDom = ev.currentTarget.parentNode; // li元素 105 if (this.longClick === 1) { 106 const lefts = this.oldMousePos.x - this.oldNodePos.x; // x轴偏移量 107 const tops = this.oldMousePos.y - this.oldNodePos.y; // y轴偏移量 108 const { pageX, pageY } = ev.touches[0]; // 手指位置 109 this.$refs.selectBox.style.left = `${pageX - lefts}px`; 110 this.$refs.selectBox.style.top = `${pageY - tops}px`; 111 this.cardIndex(selectDom, pageX, pageY); 112 } 113 }, 114 touchEnd() { 115 clearTimeout(this.timeOutEvent); 116 this.selectItem = {}; 117 }, 118 /** 119 * 计算当前移动卡片位于卡片的哪一行哪一列 120 */ 121 cardIndex(selDom, moveleft, movetop) { 122 const liWid = selDom.clientWidth; 123 const liHei = selDom.clientHeight; 124 const newWidthNum = Math.ceil((moveleft / liWid)); // 哪一列 125 const newHeightNum = Math.ceil((movetop / liHei)); // 哪一行 126 const newPositionNum = (newHeightNum - 1) * 4 + newWidthNum; 127 if (this.oldIndex !== newPositionNum - 1) { 128 if (newPositionNum <= this.list.length) { 129 this.oldIndex = newPositionNum - 1; 130 } else { 131 this.oldIndex = this.list.length - 1; 132 } 133 } 134 } 135 } 136 } 137 </script> 138 139 <style lang="scss" scoped> 140 @mixin myFlexCenter{ 141 display: flex; 142 justify-content: center; 143 align-items: center; 144 } 145 ul { 146 width: 100%; 147 height: 100%; 148 display: flex; 149 flex-wrap: wrap; 150 position: relative; 151 overflow: hidden; 152 .libox { 153 width: 25%; 154 height: 100px; 155 border-right: 1px dashed #cccccc; 156 border-bottom: 1px dashed #cccccc; 157 box-sizing: border-box; 158 @include myFlexCenter; 159 >div { 160 width: calc(100% - 10px); 161 height: 75px; 162 border-radius: 18px; 163 @include myFlexCenter; 164 position: relative; 165 &::after { 166 content: ''; 167 width: 100%; 168 height: 100%; 169 background: rgba(255, 177, 177, 0.3); 170 position: absolute; 171 top: 0; 172 left: 0; 173 } 174 >svg { 175 width: 75px; 176 height: 75px; 177 } 178 } 179 } 180 .selectBox{ 181 position: absolute; 182 width: calc(25% - 10px); 183 height: 75px; 184 border-radius: 18px; 185 >svg { 186 width: 75px; 187 height: 75px; 188 } 189 background-color: rgba(0, 0, 0, 0.1); 190 color:white; 191 @include myFlexCenter; 192 -moz-user-select:none; /*火狐*/ 193 -webkit-user-select:none; /*webkit浏览器*/ 194 -ms-user-select:none; /*IE10*/ 195 -khtml-user-select:none; /*早期浏览器*/ 196 user-select:none; 197 } 198 } 199 </style>View Code
存在问题:只能放在卡片上方才能挪动其他卡片位置,未达到需要效果,所以进行了修改。
经实际测试后修改以下部分:
①将以下代码修改为:
1 const newHeightNum = Math.ceil((movetop / liHei)) - 1; // 哪一行
②因为项目未使用scss,所以将css改成如下:
1 <style scoped> 2 ul { 3 width: 100%; 4 height: 100%; 5 display: flex; 6 flex-wrap: wrap; 7 position: relative; 8 overflow: hidden; 9 } 10 .libox { 11 width: 25%; 12 height: 100px; 13 box-sizing: border-box; 14 display: flex; 15 justify-content: center; 16 align-items: center; 17 } 18 .libox div { 19 width: calc(100% - 10px); 20 height: 75px; 21 border-radius: 18px; 22 display: flex; 23 justify-content: center; 24 align-items: center; 25 flex-direction: column; 26 position: relative; 27 } 28 .selectBox{ 29 position: absolute; 30 width: calc(25% - 10px); 31 height: 75px; 32 border-radius: 18px; 33 background-color: inherit; 34 /* color:white; */ 35 display: flex; 36 flex-direction: column; 37 justify-content: center; 38 align-items: center; 39 user-select:none; 40 } 41 </style>
效果:
标签:VUE,const,touchstart,selected,height,touchend,icon,true,name From: https://www.cnblogs.com/jiangcaicai/p/16943724.html