前言
甲方爸爸要求的太多了!!!在此强烈谴责!!!(只能在这里谴责了)。
需求: 在左侧显示文本内容,如果有高亮的文本,要在右侧的滚动条对应的位置展示高亮颜色。
**思路:**先实现滚动条样式以及功能,在滚动条内添加对应的div,需要遍历两次,第一次遍历的是文本高亮的行数;第二次遍历的是滚动条的对应行数的div,并给div上颜色。(如果有更好的办法,请私信我,或者评论区评论一下,谢谢~)
下面的代码仅仅实现滚动条功能,高亮还有添加,不过自己可以设置滚动条和滑块的样式,应付一般的需求,应该够了。后续会完善高亮部分
一、实现html 和css样式
先把样式搞出来
<template>
<div class="scrollbar">
<div class="scrollbar-content">
<ul class="box" id="box">
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>21111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>33333</li>
/**其他文本**/
</ul>
</div>
<div class='scrollbar-bar' id="scrollbar-bar" :style="{height:scrollbarHeight+'px'}">
<div class="scrollbar-thumb" id="scrollbar-thumb"></div>
</div>
</div>
二、js部分
现在来用js操作DOM节点
代码如下(示例):
//data内容
data(){
return {
scrollbarHeight:0,//滚动条的高度
contentHeight:0,//内容的高度
}
},
//methods内容:
//设置滚轮的高度
setScrollHeight(){
// 获取文本的高度
let totalHeight = 0
let listItems = document.querySelectorAll('li')
listItems.forEach(element => {
totalHeight += element.offsetHeight
});
this.contentHeight = totalHeight
// 设置滚轮的高度
let height = document.querySelector('.scrollbar-thumb')
height.style.height = 400 / totalHeight * 400 + 'px'
// 设置滚动条高度
let divTarget = document.querySelector('.scrollbar-content')
this.scrollbarHeight = divTarget.offsetHeight
},
// 设置滚动条滑动事件
scrollBarEvent(){
let _this = this
// 获取要绑定事件的 div 元素
let scrollContainer = document.getElementById('scrollbar-bar');//滚动条容器
let scrollHandle = document.querySelector('#scrollbar-thumb');//滑块
let textBox = document.getElementById('box')//文本节点
//移动事件
window.addEventListener('wheel',function(event){
const delta = event.deltaY; // 获取鼠标滚轮的滚动距离
const currentPosition = parseInt(scrollHandle.style.top) || 1; // 获取当前span的top值,默认为1px
// 确保span元素不超出container的范围
let maxTop = scrollContainer.clientHeight - scrollHandle.clientHeight;
let newPosition = currentPosition + delta; // 计算新的位置
newPosition = Math.min(Math.max(newPosition,0),maxTop)
scrollHandle.style.top = newPosition + 'px'; // 更新top值
// 计算文本内容的偏移量
let barSpeed = newPosition / _this.scrollbarHeight
let distance = _this.contentHeight * barSpeed
textBox.style.top = -distance + 'px'; // 更新文本内容的展示位置
})
},
更新内容,完善后续功能。
三、完整代码(后续补充,已完结)
<template>
<div class="scrollbar">
<div class="scrollbar-content">
<ul class="box" id="box">
<li :class="item%2===0?'li-background':''" v-for="item in 53" :key="item" :id="item">{{ item }}</li>
</ul>
</div>
<!-- 滚动条 -->
<div class='scrollbar-bar' id="scrollbar-bar" :style="{ height:scrollbarHeight + 'px'}">
<div class="scrollbar-thumb" id="scrollbar-thumb"></div>
</div>
<!-- 滚动条高亮展示区域 -->
<div id="container-light" class="container-color" :style="{ height:scrollbarHeight + 'px'}">
<div
style="height:2px;"
:class="item%2===0?'li-background':''"
v-for="item in list" :key="item"
>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
scrollbarHeight:0,//滚动条的高度
contentHeight:0,//内容的高度
list:53,
scrollContainer:null,//滚动条容器
scrollHandle:null,//滑块
textBox:null,//文本节点
}
},
mounted(){
this.setScrollHeight()
this.scrollBarEvent()
this.scrollClickEvent()
},
methods:{
/**
* 初始化数据
*/
setScrollHeight(){
// 获取文本的高度
let totalHeight = 0
let listItems = document.querySelectorAll('li')
listItems.forEach(element => {
totalHeight += element.offsetHeight
});
this.contentHeight = totalHeight
// 设置滚轮的高度
let height = document.querySelector('.scrollbar-thumb')
height.style.height = 400 / totalHeight * 400 + 'px'
// 设置滚动条高度
let divTarget = document.querySelector('.scrollbar-content')
this.scrollbarHeight = divTarget.offsetHeight
},
/**
* 设置滚动条滑动事件
*/
scrollBarEvent(){
// 获取要绑定事件的 div 元素
this.scrollContainer = document.getElementById('scrollbar-bar');//滚动条容器
this.scrollHandle = document.querySelector('#scrollbar-thumb');//滑块
this.textBox = document.getElementById('box')//文本节点
//滑轮滚动监听事件
window.addEventListener('wheel',this.removeEntity)
},
/**
* 滚动条点击事件
*/
scrollClickEvent(){
let _this = this
let scrollContainer = document.getElementById('container-light');//滚动条容器
let topDistance = 0
scrollContainer.addEventListener('click',e=>{
topDistance = _this.scrollHandle.getBoundingClientRect()
_this.scrollBarRemove({ deltaY: e.clientY })
})
},
/**
* 滚轮滚动回调事件
* @param event 位置信息
*/
removeEntity(event){
const delta = event.deltaY; // 获取鼠标滚轮的滚动距离
const currentPosition = parseInt(this.scrollHandle.style.top) || 1; // 获取当前span的top值,默认为50px
// 确保span元素不超出container的范围
let maxTop = this.scrollContainer.clientHeight - this.scrollHandle.clientHeight;
let newPosition = currentPosition + ( delta ); // 计算新的位置
newPosition = Math.min(Math.max(newPosition,0),maxTop)
this.scrollHandle.style.top = newPosition + 'px'; // 更新top值
// 计算文本内容的偏移量
let barSpeed = newPosition / this.scrollbarHeight
let distance = this.contentHeight * barSpeed
this.textBox.style.top = -distance + 'px'; // 更新文本内容的展示位置
},
/**
* 单击滚动条,滑块定位到当前位置,文本按比例定位到所在位置
* @param event 位置
*/
scrollBarRemove(event){
// 滚动条高度
let scrollBar = Number(this.scrollHandle.style.height.split('px')[0])
let top = event.deltaY - scrollBar / 2
let height = event.deltaY + scrollBar
if (height > this.scrollbarHeight) {
this.scrollHandle.style.top = this.scrollbarHeight - scrollBar + 'px'
this.textBox.style.top = -this.contentHeight + 420 + 'px'; //这里420是文本的高度,根据自身的需求,应设置为动态的。
}else if(event.deltaY < scrollBar / 2){
this.scrollHandle.style.top = 0 + 'px'
this.textBox.style.top = 0 + 'px';
}else{
this.scrollHandle.style.top = top + 'px'
let barSpeed = top / this.scrollbarHeight
let distance = this.contentHeight * barSpeed
this.textBox.style.top = -distance + 'px';
}
}
}
}
</script>
<style scope>
.scrollbar{
height: 400px;
border: black 2px solid;
}
.scrollbar-content{
height:100%;
border: red 1px solid;
overflow: hidden;
}
.scrollbar-bar{
height: 100%;
width: 20px;
background-color: #fff;
position: absolute;
top: 0;
right: 0;
}
.scrollbar-thumb{
height: 50px;
width: 100%;
background-color: rgba(162, 161, 163, 0.5);
border: 1px solid rgba(162, 161, 163, 0.2);
position: absolute;
top: 0;
right: 0px;
transition: all 0.5s linear;
}
.box{
position: relative;
top: 0;
right: 0;
}
.container-color{
height: 100%;
width: 20px;
position: absolute;
top: 0;
right: 0px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.li-background{
background-color: yellow;
}
</style>
效果图
没有点击前
点击后
四、更新代码(方法二)
新的思路:新建一个div,div里面是高亮条,让div的长度和原生滚动条长度一样,在使用绝对定位放到滚动条上面,使两者重合,滚动条设置在最上面,然后再设置滚动条背景色是透明的,滑块设置半透明,就可以达到上述图片的效果了
完结撒花花花~
总结
多读书,多看报,少吃零食,多睡觉。