js 横向滚动 list 菜单
要达到横向的 tab 使其左右滑动,常见的应该是 flex 布局了,我们先展示 dom 结构,如下
<ul class='tabs'> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> <li class='tab-list'>web前端</li> </ul>
然后使用 flex 样式
.tabs{ width: 100%; overflow-x: scroll; display: -webkit-box; display: flex; -webkit-flex-wrap:nowrap; flex-wrap:nowrap; -webkit-justify-content:space-between; justify-content:space-between; } .tab-list{ padding: 0 10px; text-align: center; -webkit-flex:1 0 auto; flex:1 0 auto; }
但是,flex在 ios 上的兼容问题,很是麻烦,不得已,考虑一下方案,还是刚刚的 dom ,样式不同
.tabs{ width: 100%; display: inline; white-space: nowrap; float: left; overflow-x: scroll; overflow-y: hidden; } .tab-list{ display:inline-block; padding: 0 10px; text-align: center; }
做到这些还只是停留在排版上,我们需要给 list 增加 js 方法,主动控制 list 的滚动。为方便操作,引入jquery
// 参数 n 代表需要跳转的元素的序号,从 0 开始 function scrollX (n){ let ele = $('.tab-list').eq(n), // 当前操作元素 e_width = ele.outerWidth(), // 元素占位宽度 ul = $('.tabs'), // 父元素 w_width = ul.outerWidth(), // 父元素宽度,即滚动的框的宽度 scroll_width = ul.scrollLeft() // 滚动条卷去宽度 let _x = ele.position().left // 相对父元素偏移量,需给父元素添加定位 position // 尾部隐藏时,需滚动距离 = 当前操作元素在父元素中偏移量 + 元素占位宽度 - 父元素宽度 + 滚动条卷去宽度 let offset_left = _x + e_width - w_width + scroll_width if( _x > w_width-e_width){ // 尾部被遮挡 ul.animate({scrollLeft: offset_left}, 200) }else if( _x <0){ // 头部被遮挡时,比较简单,直接控制滚动条位置为 : // 滚动条当前位置 - 操作元素在父元素中偏移量(此时为负) ul.animate({scrollLeft: scroll_width + _x }, 200) } // // 给选中元素添加样式 // ele.siblings().removeClass('active') ele.addClass('active') }
文末贴上整个 demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=2.0, user-scalable=no, width=device-width"> <title>scroll-list</title> <script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <style> *{ margin: 0; padding: 0; box-sizing: border-box; } body{ background-color: #f9f9f9; } ul,li{ list-style: none; } .wrap{ width: 320px; height: 480px; box-shadow: 0 2px 15px #ccc; margin: 50px auto; overflow: hidden; background-color: #fff;} .tabs{ width: 100%; overflow-x: scroll; display: -webkit-box; display: flex; -webkit-flex-wrap:nowrap; flex-wrap:nowrap; -webkit-justify-content:space-between; justify-content:space-between; border-bottom: 1px solid #dedede; position: relative; } .tab-list{ -webkit-flex:1 0 auto; flex:1 0 auto; padding: 10px 10px; text-align: center; } .tab-list.active{ color: red; } .settle{ padding: 20px; margin-top: 60px } .settle button{ background-color: #fff; padding: 6px 10px; border: 1px solid #dedede; outline: none; } </style> </head> <body> <div class="wrap"> <!-- start --> <ul class='tabs'> <li class='tab-list active'>web前端</li> <li class='tab-list'>HTML5</li> <li class='tab-list'>CSS3</li> <li class='tab-list'>ES6</li> <li class='tab-list'>Javascript</li> <li class='tab-list'>Pmomise</li> <li class='tab-list'>Vue</li> <li class='tab-list'>React</li> </ul> <!-- end --> <div class="settle"> <button onclick='scrollX (6)'>选择倒数第二个元素</button> <button onclick='scrollX (7)'>选择最后一个元素</button> <br><br> <button onclick='scrollX (0)'>选择第一个元素</button> <button onclick='scrollX (1)'>选择第二个元素</button> </div> </div> </body> <script> function scrollX (n){ let ele = $('.tab-list').eq(n), // 当前操作元素 e_width = ele.outerWidth(), // 元素占位宽度 ul = $('.tabs'), // 父元素 w_width = ul.outerWidth(), // 父元素宽度,即滚动的框的宽度 scroll_width = ul.scrollLeft() // 滚动条卷去宽度 let _x = ele.position().left // 相对父元素偏移量,需给父元素添加定位 position // 尾部隐藏时,需滚动距离 = 当前操作元素在父元素中偏移量 + 元素占位宽度 - 父元素宽度 + 滚动条卷去宽度 let offset_left = _x + e_width - w_width + scroll_width if( _x > w_width-e_width){ // 尾部被遮挡 ul.animate({scrollLeft: offset_left}, 200) }else if( _x <0){ // 头部被遮挡时,比较简单,直接控制滚动条位置为 : // 滚动条当前位置 - 操作元素在父元素中偏移量(此时为负) ul.animate({scrollLeft: scroll_width + _x }, 200) } ele.siblings().removeClass('active') ele.addClass('active') } </script> </html>