原生JS案例(面向对象)——按住鼠标实现左右拖动列表

本文介绍了一种使用原生JavaScript实现的鼠标拖动列表的方法。通过记录鼠标相对于ul的坐标,并在鼠标移动时更新盒子的滚动距离,实现了列表的平滑拖动效果。适用于需要手动控制列表滚动的场景。

需求

鼠标在有色部分按下后, 可以对有颜色的部分进行左右拖拽

基本结构效果图

在这里插入图片描述

HTML页面

  • id为box的一个对象
    <div class="box" id="box">
        <ul class="ul-list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
        </ul>
    </div>
  • id为box1的一个对象
    <div class="box" id="box1">
        <ul class="ul-list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
        </ul>
    </div>

CSS样式

        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        .box {
            width: 400px;
            height: 200px;
            margin: 100px auto;
            position: relative;
            overflow: hidden;
        }

        .ul-list {
            width: 2000px;
            height: 200px;
            line-height: 200px;
            position: absolute;
            display: flex;
            background-color: red;
            box-sizing: border-box;
        }

        .ul-list li {
            text-align: center;
            width: 200px;
        }

        .ul-list li:nth-child(odd) {
            background-color: aqua;
        }

        .ul-list li:nth-child(even) {
            background-color: #008c07;
        }

实现思路

  1. 鼠标按下时, 记录鼠标相对于ul的坐标disX。注意:这里不能用e.offsetX, 因为e.offsetX获取到的是鼠标相对于li的坐标。而我们要获取的是离鼠标最近的有绝对定位的父元素ul, 也就是用e.layerX。
  2. 当鼠标移动时, 是在整个浏览器窗口移动, 所以给document绑定鼠标移动事件。
  3. 移动时,先求出移动后盒子离浏览器左边的距离(e.clientX - disX),再用移动前盒子离浏览器左边的距离(box.offsetLeft)减去移动后盒子离浏览器左边的距离(e.clientX - disX),并赋值给盒子的滚动距离(box.scrollLeft)
  4. 鼠标弹起时, 解除document的鼠标移动事件
    在这里插入图片描述

原生JS

class dragMove {
    constructor(selector) {
        // 获取dom元素
        this.box = document.querySelector(`#${selector}`);
        this.ulList = this.box.querySelector('ul');

        // 设置ul的宽度, ul的宽度跟随li的数量动态变化
        this.ulList.style.width = this.ulList.querySelector('li').offsetWidth * this.ulList.querySelectorAll('li').length + 'px';
    }
    init() {
        this.bindEvents()
    }
    bindEvents() {
        // 鼠标按下时
        this.ulList.onmousedown = e => {
            e = e || window.event;
            // e.offsetX获取到的是鼠标相对于li的坐标
            // e.layerX获取到的是鼠标相对于ul(最近的有绝对定位的元素)的坐标
            let disX = e.layerX;

            // 鼠标移动时
            document.onmousemove = e => {
                e = e || window.event;
                this.box.scrollLeft = this.box.offsetLeft - (e.clientX - disX);
            }

            // 鼠标弹起时
            document.onmouseup = () => {
                document.onmousemove = null;
            }

            // 取消默认行为
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                return false;
            }
        }
    }
}
// 创建新的对象并传参
(new dragMove('box')).init();
(new dragMove('box1')).init();

最终效果

在这里插入图片描述

实际应用

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端技术迷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值