指令
Vue.directive('drag', {
// 钩子函数,被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。
inserted: (el, binding, vnode, oldVnode) => {
console.log(el, binding, vnode, oldVnode)
let drag = el; // 要拖拽的元素
// let wrapper = el.parentElement;
let dragImg = document.createElement("span"); // 拖拽图标
let X = 0;
drag.draggable = "true" // 使元素可直接拖拽
drag.style.width = "max-content" // 使元素充满容器
drag.appendChild(dragImg) // 添加拖拽图标,不添加则默认显示拖拽元素
// 给元素添加父元素
let wrapper = document.createElement('div');// 新建父元素
wrapper.className = 'scroll-middle'; // 这个类是自定义的滚动条类
wrapper.style.overflowX = "auto";
wrapper.style.overflowY = "hidden";
// 将父元素添加进去
drag.parentNode.replaceChild(wrapper, drag);// 获取子元素原来的父元素并将新父元素代替子元素
wrapper.appendChild(drag);// 在新父元素下添加原来的子元素
drag.ondragstart = function (e) {
e = e || window.event;
X = e.offsetX;
e.dataTransfer.setDragImage(dragImg, 0, 0); //setDragImage(imgElement, x, y)
};
drag.ondrag = function (e) {
if (drag.clientWidth > wrapper.clientWidth) {
e = e || window.event;
if (
0 <= wrapper.scrollLeft &&
wrapper.scrollLeft <= wrapper.scrollWidth &&
e.clientX != 0
) {
// console.log("拖拽中", e, wrapper.scrollLeft + (X - e.offsetX));
// wrapper.scrollTo(wrapper.scrollLeft + (X - e.offsetX), 0); // 两种皆可
wrapper.scrollLeft = wrapper.scrollLeft + (X - e.offsetX)
}
}
};
// drag.ondragend = function (e) {
// console.log("拖拽结束", e);
// };
}
// },
// // 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
// bind(binding,) {
// console.log('bind');
// },
// // 所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。
// // 转载请注明出处:https://blog.csdn.net/GeniusXYT/article/details/114372452
// // 指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
// update() {
// console.log('update');
// },
// // 所在组件的 VNode 及其孩子的 VNode 全部更新时调用。
// componentUpdated() {
// console.log('componentUpdated');
// },
// // 只调用一次,指令与元素解绑时调用。
// unbind() {
// console.log('unbind');
// }
})
Vue文件
<template>
<div v-drag>
<span v-for="(s, i) in list" :key="i">{{ s }}</span>
</div>
</template>
<script>
export default {
data() {
return {
list: [
"富强",
"民主",
"文明",
"和谐",
"自由",
"平等",
"公正",
"法治",
"爱国",
"敬业",
"诚信",
"友善",
],
};
},
};
</script>
<style scoped>
span {
background-color: aliceblue;
margin: 1vw;
font-size: 4vw;
color: rgb(53, 48, 48);
}
</style>