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

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>


 

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