自定义滚动条 两版本

重点

版本一

1.鼠标事件 (鼠标按下->鼠标移动->鼠标抬起)
2.滚动条的高度计算
3.滚动条的上下移动范围设置
4.滚动条的移动设置
5.阻止默认事件
6.计算和设置文字的移动距离

版本二

1.增加了滚动等功能
2.事件的兼容问题解决

项目代码

版本一

Css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
* {
padding: 0;
margin: 0;
}

.wrap {
width: 200px;
height: 400px;
border: 1px solid black;
position: relative;
top: 100px;
left: 100px;
overflow: hidden;
}

.con {
padding: 5px 16px 5px 5px;
font-size: 25px;
position: relative;
font-size: 14px;
}

.gdt {
width: 15px;
height: 100%;
background: #ccc;
position: absolute;
right: 0;
top: 0;
}

.gd {
width: 15px;
background-color: red;
position: absolute;
}

Html

1
2
3
4
5
6
7
8
9
10
11
<div class="wrap">
<div class="con">
start------
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内
内容自己增加
------end
</div>
<div class="gdt">
<div class="gd"></div>
</div>
</div>

Js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
window.onload = () => {
// 获取元素
// 外部div框架
let wrap = document.querySelector(".wrap");
// 文字div
let con = document.querySelector(".con");
// 滚动条div--容器
let gdt = document.querySelector(".gdt");
// 滚动条
let gd = document.querySelector(".gd");

// 设置滚动条高度
// 滚动条/装滚动条的高=框架的高/文字的高
// 滚动条=装滚动条的高*框架的高/文字的高
let height = gdt.offsetHeight * wrap.offsetHeight / con.offsetHeight;
if (height < 30) {
height = 30;
}
gd.style.height = height + "px";

// 移动滚动条
gd.onmousedown = (e) => {
let spaceY = e.clientY - gd.offsetTop;
document.onmousemove = (e) => {
let y = e.clientY - spaceY;
y = y < 0 ? y = 0 : y;
y = y > gdt.offsetHeight - gd.offsetHeight ? y = gdt.offsetHeight - gd.offsetHeight : y;
gd.style.top = y + "px";
//设置鼠标移动的时候,文字不被选中

window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

// 滚动条移动的距离/文字的距离=滚动最大的移动距离/文字最大的移动距离
// 文字的移动距离 = 滚动的移动距离*文字的最大移动距离/滚动条的最大移动距离
let moveY = y * (con.offsetHeight - wrap.offsetHeight) / (gdt.offsetHeight - gd.offsetHeight);
// 设置文字的div距离
con.style.marginTop = -moveY + "px";
}
}

document.onmouseup = () => {
document.onmousemove = null;
}

}

版本二

Css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.wrap{
width: 200px;
height: 300px;
border:5px solid black;
position: relative;
overflow: hidden;
}
.con{
/*width: 185px;*/
padding-right: 15px;
font-size: 25px;
position: relative;
}
.scroll{
width: 15px;
height: 100%;
background: #ccc;
position: absolute;
right: 0;
top: 0;
}
.scrollbar{
width: 15px;
background: red;
height: 50px;
position: absolute;
}

Html

1
2
3
4
5
6
7
8
9
10
<div class="wrap">
<div class="con">
start------
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
------end
</div>
<div class="scroll">
<div class="scrollbar"></div>
</div>
</div>

Js

外部引入的js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function mousewheel(obj,callback) {
true//判断是否火狐浏览器
trueif (navigator.userAgent.indexOf("Firefox")>-1) {
truetrueobj.addEventListener("DOMMouseScroll",fn);//火狐滚轮事件
true}else{
truetrueobj.addEventListener("mousewheel",fn);//非火狐滚轮事件
true}
truefunction fn(e) {
truetruevar e = e || window.event;
truetrue//火狐 detail 上-3 下3
truetrue//非火狐 wheelDelta 上120 下-120
truetrue// false:下 true:上
truetrueif (e.detail) {
truetruetrue//e.detail<0判断往上还是往下滚动小于0是上
truetruetruecallback.call(obj,e,e.detail<0);
truetrue}else{
truetruetrue//e.wheelDelta>0判断往上还是往下滚动大于0是上
truetruetruecallback.call(obj,e,e.wheelDelta>0);
truetrue}
truetrue//阻止默认事件
truetruee.preventDefault ? e.preventDefault() : (e.returnValue = false);
true}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
var wrap=document.querySelector(".wrap");
var con=document.querySelector(".con");
var scroll=document.querySelector(".scroll");
var scrollbar=document.querySelector(".scrollbar");

//计算滚动条的高度
console.log(wrap.clientHeight);
console.log(con.offsetHeight);
var barH = wrap.clientHeight/con.offsetHeight*scroll.offsetHeight;
if (barH<50) {barH=50}
scrollbar.style.height = barH + "px";


var bol=false;
var dy=0;
scrollbar.onmousedown = function (e) {
truebol = true;//设置可以移动
truedy = e.clientY-offsetFn(scrollbar).top;//计算鼠标和滚动条的位置差
true
true//阻止事件冒泡
trueevent.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
true//阻止默认事件
trueevent.preventDefault ? event.preventDefault() : (event.returnValue = false);
}
scroll.onmousedown = function (e) {
truevar y = e.clientY-scrollbar.offsetHeight/2-13;
truemove(y);
}
document.onmousemove = function (e) {
trueif (bol) {//判断是否可以移动
truetruevar y = e.clientY-wrap.offsetTop-5-dy;
truetruemove(y)
true}
}
document.onmouseup = function () {
truebol = false;//设置不可以移动
}

//移动滚动条和内容的函数
function move(y) {
true//判断不可以超过父级框
trueif(y<0){y=0}
trueelse if (y>scroll.offsetHeight-scrollbar.offsetHeight) {
truetruey=scroll.offsetHeight-scrollbar.offsetHeight;
true}
truescrollbar.style.top = y + "px";//设置滚动条位置

true// 内容可移动距离
truevar conDy = con.offsetHeight-wrap.clientHeight;
true// 滚动条可移动距离
truevar scrollDy = scroll.offsetHeight-scrollbar.offsetHeight;
truevar scale = conDy/scrollDy;//计算比例
true//设置内容位置
truecon.style.top = -y*scale + "px";
}

// 滚轮事件
mousewheel(wrap,function (e,bol) {
trueif (bol) {//判断往上滚还是往下滚
truetruey = scrollbar.offsetTop-10;
true}else{
truetruey = scrollbar.offsetTop+10;
true}
truemove(y);//调用移动滚动条和内容的函数
})
//键盘控制滚动条移动
document.onkeydown = function (e) {
true// console.log(e.keyCode)
trueif (e.keyCode==38) {//键盘上
truetruey = scrollbar.offsetTop-10;
true}else if(e.keyCode==40){//键盘下
truetruey = scrollbar.offsetTop+10;
true}
truemove(y);//调用移动滚动条和内容的函数
}


function offsetFn(obj) {
truevar l = obj.offsetLeft;//获取自己的left
truevar t = obj.offsetTop;//获取自己的top
trueobj = obj.offsetParent;//获取定位父级元素
truewhile(obj){//判断有没有定位父级元素
truetrue//加上定位父级的定位的left和top
truetruel += obj.offsetLeft + parseInt(getStyle(obj,"borderLeftWidth"));
truetruet += obj.offsetTop + parseInt(getStyle(obj,"borderTopWidth"));
truetrueobj = obj.offsetParent;//继续找定位父级
true}
truereturn {"left":l,"top":t};
}
//获取计算后的样式
function getStyle(obj,attr) {
trueif (obj.currentStyle) {
truetruereturn obj.currentStyle[attr];//IE获取方法
true}else{
truetruereturn getComputedStyle(obj,null)[attr];//非IE取方法
true}
}
-------------本文结束感谢您的阅读-------------
0%