几行代码实现仿淘宝金刚位

1,273 阅读2分钟

话不多说,直接上图。

image.png

金刚位是指在网页或 APP 界面上,非常非常常用的一种布局方式,通常是由多个图标和文字组成的矩形区域,用于展示常用功能、推荐商品等。它可以使页面更加直观、易用和美观,同时也可以提高用户的使用频率和购买转化率。

今天将使用css和js实现原生资源位滚动。别问我为什么不用现成的组件,偌大的库硬是没找到于是纯手写图一乐。

结构分析

两部分:资源位 + 滚动条

image.png

css实现资源位

在实际项目开发中,不可能将资源位设置一个固定的宽度,因为项目需求的迭代,随时都有可能新增一个入口作为新功能展示。

image.png

所以将使用两两一对的方式结合展示,新的入口可以随时接入现有的金刚位结构,只需要后端在接口中返回新的img与title,前端直接展示,不需要开发这个需求;省时省力一举两得。

 <div class="jgw-container">
        <div class="jgw-row">
            <div class="jgw-item">
                <img src="https://img.alicdn.com/tfs/TB1z5vSv3vD8KJjy0FlXXagBFXa-120-120.png" class="jgw-icon">
                <div class="jgw-title">1淘宝</div>
            </div>
            <div class="jgw-item">
                <img src="https://img.alicdn.com/tfs/TB1z5vSv3vD8KJjy0FlXXagBFXa-120-120.png" class="jgw-icon">
                <div class="jgw-title">2天猫</div>
            </div>
            <div class="jgw-item">
                <img src="https://img.alicdn.com/tfs/TB1z5vSv3vD8KJjy0FlXXagBFXa-120-120.png" class="jgw-icon">
                <div class="jgw-title">3聚划算</div>
            </div>
            .....
            .....
        </div>
    </div>
    <div class="lineContainer">
        <div class="redLine"></div>
    </div>

为了实现竖直换行的效果,务必将每一个金刚位的item设置宽度,在与container的高度进行碰撞时以便发生换行,使用overflow-x: auto;实现x方向的滚动条

        .jgw-container {
            display: flex;
            flex-direction: column;
            background-color: #f2f2f2;
            padding: 10px;
            height: 350px;
            overflow-x: auto;
        }

image.png

但是,原生的滚动条特别丑,于是将他隐藏起来,使用一个冷门css属性:

        .jgw-container::-webkit-scrollbar {
            display: none;
        }

image.png 就实现了大致的效果。

再使用js原生监听事件,拿到scroll的left值,以等比缩小赋值给红色线的left实现同步的滚动。(如果在react中就使用ref挂载到dom上拿到这些属性)

        const jgw_container = document.querySelector('.jgw-container')
        const jgw_row = document.querySelector('.jgw-row')
        const redLine = document.querySelector('.redLine')
        jgw_container.addEventListener('scroll',()=>{
            redLine.style.left = `${jgw_container.scrollLeft/10}px`
        })

效果:

动画.gif

最后想问下大家有什么好的优化机制吗?尝试过节流,但是节流之后就无法实现丝滑的滑动了,这样实现太草率了,监听事件removeEventListener,还有什么其他吗?