效果示例图
代码实例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.scrollWheel-wrap {
position: relative;
overflow: hidden;
box-sizing: border-box;
max-width: 100%;
height: 325px;
outline: 0;
direction: ltr;
user-select: none;
margin-top: 100px;
}
.scrollWheel-container {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
box-sizing: border-box;
scroll-behavior: unset;
margin-top: 20px;
}
.scrollWheel {
display: flex;
flex-direction: row;
}
.scrollWheel-itemBox {
display: flex;
flex-direction: row;
position: relative;
}
.scrollWheel-item {
border: 1px solid black;
width: 258px;
height: 280px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.dataTime {
position: absolute;
top: -13px;
left: 16px;
background-color: #000000;
padding: 3px 5px;
color: #fff;
font-size: 14px;
z-index: 1;
opacity: 1;
}
.scrollWheel-bar {
max-width: 1000px;
width: 94%;
position: absolute;
bottom: 3px;
z-index: 50;
height: 5px;
border-radius: 10px;
background: rgba(0, 0, 0, .1);
left: 50%;
transform: translateX(-50%);
cursor: pointer;
}
.scrollWheel-barBox {
width: 100%;
position: relative;
overflow: hidden;
height: 100%;
max-width: 100%;
outline: 0;
direction: ltr;
}
.wheel-barLine {
position: absolute;
left: 0px;
width: 50px;
background: #171717;
height: 100%;
margin: 0;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="scrollWheel-wrap" id="scrollWheelWrap">
<div class="scrollWheel-container">
<div class="scrollWheel" id="scrollWheel">
<div class="scrollWheel-itemBox mulDataTime">
<div class="dataTime">2022-02-28</div>
<div class="scrollWheel-item">-1</div>
</div>
<div class="scrollWheel-itemBox mulDataTime">
<div class="dataTime">2022-03-28</div>
<div class="scrollWheel-item">2</div>
</div>
<div class="scrollWheel-itemBox mulDataTime">
<div class="dataTime">2022-04-28</div>
<div class="scrollWheel-item">4</div>
</div>
<div class="scrollWheel-itemBox mulDataTime">
<div class="dataTime">2022-06-28</div>
<div class="scrollWheel-item">12</div>
<div class="scrollWheel-item">13</div>
<div class="scrollWheel-item">14</div>
<div class="scrollWheel-item">15</div>
<div class="scrollWheel-item">16</div>
<div class="scrollWheel-item">17</div>
</div>
<div class="scrollWheel-itemBox mulDataTime">
<div class="dataTime">2022-08-28</div>
<div class="scrollWheel-item">18</div>
<div class="scrollWheel-item">19</div>
</div>
<div class="scrollWheel-itemBox">
<div class="dataTime">2022-12-28</div>
<div class="scrollWheel-item">20</div>
</div>
</div>
</div>
<div class="scrollWheel-bar">
<div class="scrollWheel-barBox">
<div class="wheel-barLine"></div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
initWheel();
window.addEventListener('resize', initWheel, false)
function initWheel() {
const doms = {
scrollBox: document.querySelector("#scrollWheelWrap"),
scrollCon: document.querySelector("#scrollWheel"),
childrenEl: document.querySelectorAll(".scrollWheel-item"),
childrenElWidth: document.querySelector(".scrollWheel-item").getBoundingClientRect().width, //获取元素的宽度
parentEl: document.querySelector(".scrollWheel-container"), //外层可以滚动盒子元素
scrollWheelBar: document.querySelector(".scrollWheel-bar"), //滚动条盒子
scrollWheelLine: document.querySelector(".wheel-barLine"), //滚动条
scrollWheelBox: document.querySelector(".scrollWheel-barBox"),
}
const clientWidth = document.body.clientWidth; //获取当前可视窗口的宽度
const scroolBarBound = doms.scrollWheelBar.getBoundingClientRect();
//把滚动条盒子均等分
const scrollWheelLineWidth = (scroolBarBound.width / doms.childrenEl.length);
//计算滚动条的宽度
doms.scrollWheelLine.style.width = scrollWheelLineWidth + 'px';
//设置滚动内容的宽度
const wheelContainerWidth = doms.childrenEl.length * doms.childrenElWidth;
doms.parentEl.style.width = wheelContainerWidth + 'px';
doms.scrollCon.style.width = wheelContainerWidth + 'px';
//设置滚动内容距离左边的距离
doms.parentEl.style.paddingLeft = scroolBarBound.left + 'px';
doms.parentEl.style.left = 0 + 'px';
//设置滚动条line在滚动条盒子中位置
doms.scrollWheelLine.style.left = 0 + 'px';
//内容区域滚动的区间值
const wheelDistance = (wheelContainerWidth - clientWidth + scroolBarBound.left * 2) / (doms.childrenEl.length);
if (wheelDistance < 0) {
doms.scrollWheelBar.style.display = "none"
}else{
doms.scrollWheelBar.style.display = "block"
}
const parentDisX = wheelContainerWidth - scroolBarBound.width;
const childrenDisX = scroolBarBound.width - scrollWheelLineWidth;
const addEvent = (function(window, undefined) {
const _event = function(event) {
event.preventDefault();
let type = event.type;
if (type === 'DOMMouseScroll' || type === 'mousewheel') {
event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0);
}
if (event.srcElement && !event.target) {
event.target = event.srcElement;
}
if (!event.preventDefault && event.returnValue !== undefined) {
event.preventDefault = function() {
event.returnValue = false;
}
}
return event;
};
if (window.addEventListener) {
return function(el, type, fn, capture) {
if (type === 'mousewheel' && document.mozFullScreen !== undefined) {
type = "DOMMouseScroll";
}
el.addEventListener(type, function(event) {
event.preventDefault();
fn.call(this, _event(event));
}, capture || false);
}
} else if (window.attachEvent) {
return function(el, type, fn, capture) {
el.attachEvent("on" + type, function(event) {
event.preventDefault();
event = event || window.event;
fn.call(el, _event(event));
});
}
}
})(window);
//监听鼠标滚动事件
addEvent(doms.scrollBox, "mousewheel", function(event) {
let left = Math.abs(doms.parentEl.style.left.split("px")[0]); //获取当前滚动区域距离左侧的距离
if (wheelDistance <= 0) {
return false
}
if (event.delta < 0) {
//滚轮向下滚动
left = left + wheelDistance;
if (left >= parentDisX) {
left = parentDisX
}
doms.scrollWheelLine.style.left = ((left * childrenDisX) / parentDisX) + 'px';
doms.parentEl.style.left = '-' + left + 'px'
} else {
//滚轮向上滚动
left = left - wheelDistance;
if (left <= 0) {
left = 0;
}
doms.scrollWheelLine.style.left = ((left * childrenDisX) / parentDisX) + 'px';
doms.parentEl.style.left = '-' + left + 'px'
}
obseverTitile();
});
//给滚动条添加点击触发事件
doms.scrollWheelBox.addEventListener("click", (e) => {
const clientX = e.clientX;
let offsetX = clientX - scroolBarBound.left;
let subscript = Math.ceil(offsetX / scrollWheelLineWidth);
if (subscript >= doms.childrenEl.length) {
subscript = doms.childrenEl.length;
}
//设置滚动内容的位置
doms.parentEl.style.left = '-' + (parentDisX * (subscript - 1) * scrollWheelLineWidth) /
childrenDisX + 'px'
//设置滚动条的位置
doms.scrollWheelLine.style.left = (subscript - 1) * scrollWheelLineWidth + 'px';
obseverTitile();
})
//给滚动条添加鼠标拖动触发事件
doms.scrollWheelBox.onmousedown = (e) => {
let clientX = e.clientX - scroolBarBound.left;
let left = Math.abs(doms.scrollWheelLine.style.left.split("px")[0]); //获取当前滚动区域距离左侧的距离
let disX = 0;
//鼠标移动
window.onmousemove = (e) => {
let moveX = (e.clientX - scroolBarBound.left) - clientX;
if (moveX > 0) {
//鼠标往右移动
disX = moveX + left;
if (disX >= childrenDisX) {
disX = childrenDisX;
}
doms.parentEl.style.left = '-' + (parentDisX / childrenDisX) * disX + 'px'
doms.scrollWheelLine.style.left = disX + 'px'
} else {
disX = left - Math.abs(moveX);
if (disX <= 0) {
disX = 0;
}
doms.parentEl.style.left = '-' + (parentDisX / childrenDisX) * disX + 'px'
doms.scrollWheelLine.style.left = disX + 'px'
}
obseverTitile();
}
//鼠标离开
window.onmouseup = (e) => {
window.onmousemove = null;
window.onmouseup = null;
}
}
//监听头部信息
function obseverTitile() {
document.querySelectorAll(".mulDataTime").forEach((item) => {
const itemBound = item.getBoundingClientRect();
const titleItem = item.querySelector('.dataTime');
//每个区间标题移动的最大距离
const max = itemBound.width - 16 - titleItem.getBoundingClientRect().width;
const childrenCount = item.querySelectorAll(".scrollWheel-item").length;
console.log("[]", childrenCount)
if (childrenCount >= 2) {
if (itemBound.left <= scroolBarBound.left) {
if (itemBound.left > 0) {
let moveX = scroolBarBound.left - itemBound.left;
if (moveX < 160) {
moveX = 16;
}
titleItem.style.left = moveX + 'px';
} else {
let moveX = scroolBarBound.left + Math.abs(itemBound.left);
if (moveX >= max) {
moveX = max
}
titleItem.style.left = moveX + 'px';
}
}
}
})
}
}
</script>
</html>