自定义v-drag指令(横向拖拽滚动)

28 篇文章 1 订阅
1 篇文章 0 订阅

指令

        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>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值