js 封装公共方法 拖动元素进行上下排序 返回排序结果

效果图 拖动元素进行上下排序 并且回调返回排序结果数组

 

 

 

1.common.js进行封装

// 拖动排序封装
//dom:父节点ID名称(必传)
//callback:回调函数,返回排序结果(选传)
const drag = function(dom, callback) { let node = document.querySelector(`#${dom}`); let draging = null; let nodeName = null;//元素标签名字 let Capitalize = null;//元素标签大写 //使用事件委托,将li的事件委托给ul node.ondragstart = function(event) { // console.log("start"); if (event.target.draggable) { // 开始拖动添加样式 高亮当前 event.target.classList.add('dragSelect') if(!nodeName){ Capitalize = event.target.nodeName nodeName = event.target.nodeName.toLowerCase()//转小写 // console.log(Capitalize,nodeName) } //firefox设置了setData后元素才能拖动!!!! event.dataTransfer.setData("te", event.target.innerText); //不能使用text,firefox会打开新tab //event.dataTransfer.setData("self", event.target); draging = event.target; // 切换动画 let target = event.target; let targetRect = target.getBoundingClientRect(); let dragingRect = draging.getBoundingClientRect(); let targetAfter = target.getBoundingClientRect(); let dragingAfter = draging.getBoundingClientRect(); target.style.transition = 'none'; target.style.transform = 'translate3d(' + (targetRect.left - targetAfter.left) + 'px,' + (targetRect.top - targetAfter.top) + 'px,0)' target.offsetWidth; //触发重绘 target.style.transition = 'all 300ms'; target.style.transform = 'translate3d(0,0,0)'; } else { console.log('当前元素不可拖动,需要设置:draggable="true"') return } } // 结束 node.ondragend = function(event) { // console.log(event.target.dataset, 'end') // 结束拖动 删除class 移除高亮 event.target.classList.remove('dragSelect') node.getElementsByTagName(nodeName) // 拖动后的 排序结果 let sort = [] for (let i = 0; i < node.getElementsByTagName(nodeName).length; i++) { if(node.getElementsByTagName(nodeName)[i].dataset.index){ sort.push(Number(node.getElementsByTagName(nodeName)[i].dataset.index)) } // else { // console.error(`拖动的元素必须绑定:data-index='xx' 为唯一标识`) // break // } } // 回调 函数 if(callback){ callback(sort) } } node.ondragover = function(event) { // console.log("onDrop over"); event.preventDefault(); let target = event.target; //因为dragover会发生在父级id上,所以要判断是不是 nodeName储存的标签名字 if (target.nodeName === Capitalize && target !== draging && event.target.draggable) { if (_index(draging) < _index(target)) { target.parentNode.insertBefore(draging, target.nextSibling); } else { target.parentNode.insertBefore(draging, target); } } } //获取元素在父元素中的index function _index(el) { let index = 0; if (!el || !el.parentNode) { return -1; } while (el && (el = el.previousElementSibling)) { index++; } return index; } } export default {drag};

2.设置拖动添加的选中样式

.dragSelect{
  background-color: #333333 !important;
  color: #FFFFFF !important;
}

3.vue页面引入文件调用方法

<div id="container">
      <div class="ele " draggable="true" :data-index='i' v-for="i in 10" :key="i">
        <div>{{i}}</div>
      </div>
</div>

import common from '@/utils/common.js'

 

mounted(){
 common.drag('container', function(res) {
        console.log(res,'==')//每次拖动排序结束 都返回排序结果数组
 })
}


<style scoped="scoped">

#container {
list-style: none;
margin: 200px;
font-size: 0;
width: 100%;
}

.ele {
font-size: 16px;
width: 100%;
height: 40px;
border: 1px solid #999;
background: #FFFFFF;
margin: 2px 0;
border-radius: 10px;
padding-left: 10px;
color: white;
cursor: move;
color: black;
}

</style>

 

 我是马丁的车夫,欢迎转发收藏!

posted on 2021-08-09 14:18  马丁的车夫  阅读(204)  评论(0编辑  收藏  举报