LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

JS 实现横向排列的页面元素左右拖拽

admin
2025年7月1日 16:20 本文热度 43

在前端开发中,页面中的数据元素横向排列是一种很常见的ui设计,比如首页面中的产品列表,tab标签页的标题等。

当列表元素数量过多的时候,横向排列不下,就会出现横向滚动条,或者让列表元素换行的情况。

今天我们介绍一种可以让列表元素左右拖拽的实现方案,以避免出现横向滚动条,和换行的情况。

最为演示示例,我们假定页面中有一个 div 作为数据显示的容器(container),container 内有一个子元素(div),子元素的宽度大于container,我们设置container 的css 样式:overflow: hidden; 如下图:

现在,我们在子元素中添加数据列表:

实现代码:

HTML

<div class="container">    <div class="data-list">        <div class="data-item">数据项 1</div>        <div class="data-item">数据项 2</div>        <div class="data-item">数据项 3</div>        <div class="data-item">数据项 4</div>        <div class="data-item">数据项 5</div>        <div class="data-item">数据项 6</div>        <div class="data-item">数据项 7</div>        <div class="data-item">数据项 8</div>        <div class="data-item">数据项 9</div>        <div class="data-item">数据项 10</div>    </div></div>

CSS

.container {    height100vh;    width600px;    background-color#fff;    border1px solid #ddd;    overflow: hidden;}.data-list {    height100px;    width2090px;}.data-item {    float: left;    height100%;    width200px;    background-color#eee;    text-align: center;    line-height100px;    user-select: none;}.data-item + .data-item {    margin-left10px;}

接下来,我们给子元素(data-list)添加拖动事件。我们先前写过一篇关于拖动div的文章(JS 实现 div 自由拖拽),大家有兴趣的可以看一下。在那片文章中实现的是鼠标自由拖拽div,本章中只需要左右拖动。另外,为了多演示一种拖动方式,本章中我们使用 transform 方式来实现。如下 JS 代码:

var el = document.querySelector('.data-list');el.addEventListener('mousedown', drag);var offset=0;function drag(e){    var startX = e.clientX;    var mousemove=(evt)=>{        let x=evt.clientX;        offset += x - startX;        //给元素设置位移        setPosition(offset);        startX=x; //更新鼠标位置    };    var mouseup=(evt)=>{        document.removeEventListener('mousemove', mousemove);        document.removeEventListener('mouseup', mouseup);    };    document.addEventListener('mousemove', mousemove);    document.addEventListener('mouseup', mouseup);}//给元素设置 transform 位移function setPosition(ofs){    el.style.transform='translateX('+ofs+'px)';}

至此,子元素就实现了左右拖动:

不过还有个问题,就是在子元素可以被无限横向拖拽,甚至可以被拖到视窗范围之外。所以我们还需要在结束拖拽的时候,也就是 mouseup 事件中,检查一下子元素的位置,如果子元素的最左侧与容器的最左侧有间距,或者子元素的最右侧与容器的最右侧有间距,就重新调整子元素的偏移量。

为此,我们添加一个 checkPosition 的函数:

function checkPosition(){    if(offset>0){        this.setPosition(0);        return;    }    //最大偏移量:子元素的宽度 与 父元素宽度 的差值    var maxOffset=el.offsetWidth - el.parentNode.offsetWidth;    if(Math.abs(offset)>maxOffset){        setPosition(-maxOffset);    }}

同时,修改一下setPosition 函数,以更新偏移量:

//给元素设置 transform 位移function setPosition(ofs){    el.style.transform='translateX('+ofs+'px)';    offset=ofs;}

然后在mouseUp事件中,调用 checkPosition

var mouseup=(evt)=>{    checkPosition();    document.removeEventListener('mousemove', mousemove);    document.removeEventListener('mouseup', mouseup);};

这样当子元素被拖到视窗之外时,会自动“复位”:

为了让子元素在“复位”的时候,更平滑一些,我们还可以再做一些改进,就是给子元素添加动画(transition)。但是我们不希望在拖动的过程中启用动画,而是在拖拽结束,让子元素恢复位置的时候再启用动画,所以我们在 mouseup 事件中添加 transition 样式,而在 mousedown 事件的时候,取消 transition 样式。如下:

var offset=0;function drag(e){    //取消动画    el.style.transition='';    var startX = e.clientX;function checkPosition(){    //添加动画    el.style.transition='transform 0.3s';    if(offset>0){        this.setPosition(0);        return;    …}

完整代码如下:

<!DOCTYPE html><html lang="zh"><head>  	<meta charset="utf-8">  	<title>DIV 拖拽</title>  	<style>        .container {            height100vh;            width600px;            background-color#fff;            border1px solid #ddd;            overflow: hidden;        }        .data-list {            height100px;            width2090px;        }        .data-item {            float: left;            height100%;            width200px;            background-color#eee;            text-align: center;            line-height100px;            user-select: none;        }        .data-item + .data-item {            margin-left10px;        }    </style>    </style></head><body>    <div class="container">        <div class="data-list">            <div class="data-item">数据项 1</div>            <div class="data-item">数据项 2</div>            <div class="data-item">数据项 3</div>            <div class="data-item">数据项 4</div>            <div class="data-item">数据项 5</div>            <div class="data-item">数据项 6</div>            <div class="data-item">数据项 7</div>            <div class="data-item">数据项 8</div>            <div class="data-item">数据项 9</div>            <div class="data-item">数据项 10</div>        </div>    </div><script>    var el = document.querySelector('.data-list');    el.addEventListener('mousedown', drag);    var offset=0;    function drag(e){        el.style.transition='';        var startX = e.clientX;        var mousemove=(evt)=>{            let x=evt.clientX;            offset += x - startX;            //给元素设置位移            setPosition(offset);            startX=x; //更新鼠标位置        };        var mouseup=(evt)=>{            checkPosition();            document.removeEventListener('mousemove', mousemove);            document.removeEventListener('mouseup', mouseup);        };        document.addEventListener('mousemove', mousemove);        document.addEventListener('mouseup', mouseup);    }    //给元素设置 transform 位移    function setPosition(ofs){        el.style.transform='translateX('+ofs+'px)';        offset=ofs;    }    function checkPosition(){        el.style.transition='transform 0.3s';        if(offset>0){            this.setPosition(0);            return;        }        //最大偏移量:子元素的宽度 与 父元素的宽度 的差值        var maxOffset=el.offsetWidth - el.parentNode.offsetWidth;        if(Math.abs(offset)>maxOffset){            setPosition(-maxOffset);        }    }</script></body></html>


该文章在 2025/7/1 21:09:46 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved