最近发现项目可能需要使用到滚动条,浏览器自动的滚动条不美观,所以就想到了使用js实现。
js代码如下:
function box_scroll() {
var args = arguments;
var parent = this;
/*左右滚动*/
this.lr = {
$scrollContainer: null,
$scrollContent: null,
$scrollbar: null,
containerWidth: null,
scrollWidth: null,
scrollbarWidth: null,
scroll: 0,
/**
* 鼠标滚轮事件
* @param e
* @returns {boolean}
*/
scrollFunction: function (e) {
var e = e || window.event;
var $scrollContainer = this.$scrollContainer,
$scrollContent = this.$scrollContent,
$scrollbar = this.$scrollbar,
containerWidth = this.containerWidth,
scrollWidth = this.scrollWidth,
scrollbarWidth = this.scrollbarWidth,
scroll = this.scroll;
//判断滚轮方向
var wheelValue = e.wheelDelta / 120 || -e.detail / 3;
var dir = wheelValue > 0 ? "up" : "down";
if (dir === "up") {
//内容容器右移
scroll += 80;
} else {
//内容容器左移
scroll -= 80;
}
//大于最大滚动的长度(scrollWidth - containerWidth)
if (Math.abs(scroll) > scrollWidth - containerWidth) {
//边界判定
scroll = -scrollWidth + containerWidth;
}
if (scroll > 0) {
//scroll 不能大于0,因为使用的是css的left
scroll = 0;
}
this.scroll = scroll;
$scrollContent.style.left = scroll + "px";
//距离比例
var proportion = Math.abs(scroll) / (scrollWidth - containerWidth);
//设置滚动条滑块移动的距离
if ($scrollbar) {
$scrollbar.style.left = proportion * (containerWidth - scrollbarWidth) + "px";
}
e.preventDefault();
return false;
},
/**
* 左右滚动
* @param {string|object} scrollContainer 最外层容器
* @param {string|object} scrollContent 内容容器部分
* @param {string|object} scrollbar 滚动条盒子
*/
run: function (scrollContainer, scrollContent, scrollbar) {
var args = arguments;
var $scrollContainer, $scrollContent, $scrollbar, reg = {isEle: /^\[object HTML\S+Element\]$/i};
var self = this;
//滚动的距离(内容容器 left)
var scroll = 0;
if (scrollContainer) {
(typeof scrollContainer === "string") && ($scrollContainer = document.getElementById(scrollContainer));
(reg.isEle.test(Object.prototype.toString.call(scrollContainer))) && ($scrollContainer = scrollContainer);
this.$scrollContainer = $scrollContainer;
}
if (scrollContent) {
(typeof scrollContent === "string") && ($scrollContent = document.getElementById(scrollContent));
(reg.isEle.test(Object.prototype.toString.call(scrollContent))) && ($scrollContent = scrollContent);
this.$scrollContent = $scrollContent;
}
if (scrollbar) {
(typeof scrollbar === "string") && ($scrollbar = document.getElementById(scrollbar));
(reg.isEle.test(Object.prototype.toString.call(scrollbar))) && ($scrollbar = scrollbar);
this.$scrollbar = $scrollbar;
}
//设置最外层容器的样式
$scrollContainer.style.position = "relative";
$scrollContainer.style.overflow = "hidden";
//设置内容容器的样式
$scrollContent.style.position = "absolute";
//内容容器的宽
var scrollWidth = $scrollContent.offsetWidth;
this.scrollWidth = scrollWidth;
//最外层容器的宽
var containerWidth = $scrollContainer.offsetWidth;
this.containerWidth = containerWidth;
if ($scrollbar) {
$scrollbar.style.width = (containerWidth * containerWidth) / scrollWidth + "px";
//滚动条的宽
var scrollbarWidth = $scrollbar.offsetWidth;
this.scrollbarWidth = scrollbarWidth;
if (scrollbarWidth >= containerWidth) {
$scrollbar.style.display = "none";
}
}
//滑块滚动部分
if ($scrollbar) {
$scrollbar.style.opacity = 0.7;
$scrollContainer.onmouseover = function () {
$scrollbar.style.opacity = 1;
};
$scrollContainer.onmouseout = function () {
$scrollbar.style.opacity = 0.7;
};
parent.is_mobile() && ($scrollbar.style.opacity = 0);
$scrollbar.onmousedown = function (e) {
var e = e || window.event;
var objX = this.offsetLeft;
var x = e.clientX;
var realX = x - objX;
var _this = this;
var scrollWidth = $scrollContent.offsetWidth;
document.onmousemove = function (e) {
var e = e || window.event;
var x1 = e.clientX;
var realX2 = x1 - realX;
if (realX2 < 0) {
realX2 = 0;
} else if (realX2 > containerWidth - scrollbarWidth) {
realX2 = containerWidth - scrollbarWidth;
}
_this.style.left = realX2 + "px";
$scrollContent.style.left = (self.scroll = -realX2 / (containerWidth - scrollbarWidth) * (scrollWidth - containerWidth)) + "px";
e.preventDefault();
return false;
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
};
}
this.mousewheel = function (e) {
self.scrollFunction(e);
};
if (document.addEventListener) {
$scrollContainer.addEventListener('DOMMouseScroll', this.mousewheel, false);
}
$scrollContainer.onmousewheel = this.mousewheel;
//移动端触摸滚动
(function () {
var x, y, begin_left;
$scrollContainer.addEventListener("touchstart", function (e) {
var e = e || window.event;
var touch = e.touches[0];
y = parseInt(touch.clientY);
x = parseInt(touch.clientX);
begin_left = $scrollContent.offsetLeft;
scrollWidth = $scrollContent.offsetWidth;
}, false);
$scrollContainer.addEventListener("touchmove", function (e) {
var e = e || window.event;
e.preventDefault();
var touch = e.touches[0];
y1 = parseInt(touch.clientY);
x1 = parseInt(touch.clientX);
$scrollContent.style.left = (self.scroll = begin_left + (x1 - x)) + "px";
if ($scrollContent.offsetLeft > 0) {
$scrollContent.style.left = 0;
self.scroll = 0;
} else if ($scrollContent.offsetLeft < -(scrollWidth - containerWidth)) {
$scrollContent.style.left = (self.scroll = -(scrollWidth - containerWidth)) + "px";
}
//距离比例
var proportion = Math.abs(self.scroll) / (scrollWidth - containerWidth);
//设置滚动条滑块移动的距离
if ($scrollbar) {
$scrollbar.style.left = proportion * (containerWidth - scrollbarWidth) + "px";
}
//触摸滑屏的时候显示滚动条
$scrollbar.style.opacity = 1;
}, false);
$scrollContainer.addEventListener("touchend", function (e) {
clearTimeout(self.IDD);
self.IDD = setTimeout(function () {
//手指离开屏幕的时候隐藏滚动条
$scrollbar.style.opacity = 0;
}, 800);
});
})();
}
};
/*上下滚动*/
this.tb = {
$scrollContainer: null,
$scrollContent: null,
$scrollbar: null,
containerHeight: null,
scrollHeight: null,
scrollbarHeight: null,
scroll: 0,
/**
* 鼠标滚轮事件
* @param e
* @returns {boolean}
*/
scrollFunction: function (e) {
var e = e || window.event;
//判断滚轮方向
var wheelValue = e.wheelDelta / 120 || -e.detail / 3;
var dir = wheelValue > 0 ? "up" : "down";
if (dir === "up") {
//内容容器下移
this.scroll += 80;
} else {
//内容容器上移
this.scroll -= 80;
}
//大于最大滚动的长度(scrollHeight - containerHeight)
if (Math.abs(this.scroll) > this.scrollHeight - this.containerHeight) {
//边界判定
this.scroll = -this.scrollHeight + this.containerHeight;
}
if (this.scroll > 0) {
//scroll 不能大于0,因为使用的是css的top
this.scroll = 0;
}
this.$scrollContent.style.top = this.scroll + "px";
//距离比例(滚动的距离与最大滚动距离的比例)
var proportion = Math.abs(this.scroll) / (this.scrollHeight - this.containerHeight);
//设置滚动条滑块移动的距离
if (this.$scrollbar) {
this.$scrollbar.style.top = proportion * (this.containerHeight - this.scrollbarHeight) + "px";
}
e.preventDefault();
return false;
},
/**
* 上下滚动
* @param {string|object} scrollContainer 最外层容器
* @param {string|object} scrollContent 内容容器
* @param {string|object} scrollbar 滚动条盒子
*/
run: function (scrollContainer, scrollContent, scrollbar) {
var args = arguments, reg = {isEle: /^\[object HTML\S+Element\]$/i}, self = this;
if (scrollContainer) {
(typeof scrollContainer === "string") && (this.$scrollContainer = document.getElementById(scrollContainer));
(reg.isEle.test(Object.prototype.toString.call(scrollContainer))) && (this.$scrollContainer = scrollContainer);
}
if (scrollContent) {
(typeof scrollContent === "string") && (this.$scrollContent = document.getElementById(scrollContent));
(reg.isEle.test(Object.prototype.toString.call(scrollContent))) && (this.$scrollContent = scrollContent);
}
if (scrollbar) {
(typeof scrollbar === "string") && (this.$scrollbar = document.getElementById(scrollbar));
(reg.isEle.test(Object.prototype.toString.call(scrollbar))) && (this.$scrollbar = scrollbar);
}
//设置最外层容器的样式
this.$scrollContainer.style.position = "relative";
this.$scrollContainer.style.overflow = "hidden";
//设置内容容器的样式
this.$scrollContent.style.position = "absolute";
//内容容器的高
this.scrollHeight = this.$scrollContent.offsetHeight;
//最外层容器的高
this.containerHeight = this.$scrollContainer.offsetHeight;
if (this.$scrollbar) {
this.$scrollbar.style.height = (this.containerHeight * this.containerHeight) / this.scrollHeight + "px";
//滚动条的高
this.scrollbarHeight = this.$scrollbar.offsetHeight;
if (this.scrollbarHeight >= this.containerHeight) {
this.$scrollbar.style.display = "none";
}
}
//滑块滚动部分
if (this.$scrollbar) {
this.$scrollbar.style.opacity = 0.7;
this.$scrollContainer.onmouseover = function () {
self.$scrollbar.style.opacity = 1;
};
this.$scrollContainer.onmouseout = function () {
self.$scrollbar.style.opacity = 0.7;
};
parent.is_mobile() && (this.$scrollbar.style.opacity = 0);
this.$scrollbar.onmousedown = function (e) {
var objY = this.offsetTop;
var e = e || window.event;
var y = e.clientY;
var realY = y - objY;
var _this = this;
self.scrollHeight = self.$scrollContent.offsetHeight;
document.onmousemove = function (e) {
var e = e || window.event;
var y1 = e.clientY;
var realY2 = y1 - realY;
if (realY2 < 0) {
realY2 = 0;
} else if (realY2 > self.containerHeight - self.scrollbarHeight) {
realY2 = self.containerHeight - self.scrollbarHeight;
}
_this.style.top = realY2 + "px";
self.$scrollContent.style.top = (self.scroll = -realY2 / (self.containerHeight - self.scrollbarHeight) * (self.scrollHeight - self.containerHeight)) + "px";
e.preventDefault();
return false;
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
};
}
this.mousewheel = function (e) {
self.scrollFunction(e);
};
if (document.addEventListener) {
this.$scrollContainer.addEventListener('DOMMouseScroll', this.mousewheel, false);
}
this.$scrollContainer.onmousewheel = this.mousewheel;
//移动端触摸滚动
(function () {
var x, y, begin_top;
self.$scrollContainer.addEventListener("touchstart", function (e) {
var e = e || window.event;
var touch = e.touches[0];
y = parseInt(touch.clientY);
begin_top = self.$scrollContent.offsetTop;
$scrollHeight = self.$scrollContent.offsetHeight;
}, false);
self.$scrollContainer.addEventListener("touchmove", function (e) {
var e = e || window.event;
e.preventDefault();
var touch = e.touches[0];
y1 = parseInt(touch.clientY);
self.$scrollContent.style.top = (self.scroll = begin_top + (y1 - y)) + "px";
if (self.$scrollContent.offsetTop > 0) {
self.$scrollContent.style.top = 0;
self.scroll = 0;
} else if (self.$scrollContent.offsetTop < -(self.scrollHeight - self.containerHeight)) {
self.$scrollContent.style.top = (self.scroll = -(self.scrollHeight - self.containerHeight)) + "px";
}
//距离比例
var proportion = Math.abs(self.scroll) / (self.scrollHeight - self.containerHeight);
//设置滚动条滑块移动的距离
if (self.$scrollbar) {
self.$scrollbar.style.top = proportion * (self.containerHeight - self.scrollbarHeight) + "px";
}
//触摸滑屏的时候显示滚动条
self.$scrollbar.style.opacity = 1;
}, false);
self.$scrollContainer.addEventListener("touchend", function (e) {
clearTimeout(self.IDD);
self.IDD = setTimeout(function () {
//手指离开屏幕的时候隐藏滚动条
self.$scrollbar.style.opacity = 0;
}, 500);
});
})();
}
};
}
box_scroll.prototype = {
getEle: function (select, parentEle, num) {
var reg = {
"is_ele": /^\[object HTML\S+Element\]$/i,
"id": /^#[A-Za-z_\-][A-Za-z_\-1-9]*$/,
"class": /^(\.[A-Za-z_\-][A-Za-z_\-1-9]*\s*)+$/,
"tagName": /^[A-Za-z_\-][A-Za-z_\-1-9]*$/,
};
if (!reg.is_ele.test(Object.prototype.toString.call(parentEle))) {
parentEle = document;
}
if (select) {
if (typeof select === "string") {
if (reg.id.test(select)) {
select = this.trim(this.trim(select), "#");
return document.getElementById(select);
}
if (reg.class.test(select)) {
var ele_list = parentEle.getElementsByTagName("*");
select = this.trim(select, "\\.");
var select_ele_list = [];
for (var i = 0, len = ele_list.length; i < len; i++) {
var class_attr_str = ele_list[i].getAttribute("class");
if (class_attr_str) {
var class_list = class_attr_str.split(/\s+/i);
if (this.in_array(select, class_list)) {
select_ele_list.push(ele_list[i]);
}
}
}
return typeof num === "number" && num > -1 ? select_ele_list[num] : select_ele_list;
}
if (reg.tagName.test(select)) {
var ele_list = parentEle.getElementsByTagName(this.trim(select));
return typeof num === "number" && num > -1 ? ele_list[num] : ele_list;
}
}
}
return false;
},
trim: function (str, preg) {
if (preg) {
preg = new RegExp("(^" + preg + "*|" + preg + "*$)", "ig");
}
(preg) || (preg = /(^[\s\t\r\n]*|[\s\t\r\n]*$)/ig);
return str.replace(preg, "");
},
ltrim: function (str, preg) {
if (preg) {
preg = new RegExp("(^" + preg + "*)", "ig");
}
(preg) || (preg = /(^[\s\t\r\n]*)/i);
return str.replace(preg, "");
},
rtrim: function (str, preg) {
if (preg) {
preg = new RegExp("(" + preg + "*$)", "ig");
}
(preg) || (preg = /([\s\t\r\n]*$)/i);
return str.replace(preg, "");
},
in_array: function (needle, haystack, argStrict) {
var key = "", strict = !!argStrict;
if (strict) {
for (key in haystack) {
if (haystack[key] === needle) {
return true
}
}
} else {
for (key in haystack) {
if (haystack[key] == needle) {
return true
}
}
}
return false;
},
is_mobile: function () {
if (window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
/* 移动端*/
return true;
} else {
/* PC端*/
return false;
}
},
};
/**
* 自定义滚动条
* @param {string|object} scrollContainer 最外层容器
* @param {string|object} scrollContent 内容容器部分
* @param {string|object} scrollbar 滚动条盒子
* @param {number|string|null|boolean} opt 选项
* @returns {box_scroll}
*/
function my_scroll(scrollContainer, scrollContent, scrollbar, opt) {
var sc = new box_scroll();
opt || (opt = 1);
//上下滚动
if (sc.in_array(opt, [1, "tb", "top_bottom"])) {
sc.tb.run(scrollContainer, scrollContent, scrollbar);
}
//左右滚动
if (sc.in_array(opt, [2, "lr", "left_right"])) {
sc.lr.run(scrollContainer, scrollContent, scrollbar);
}
return sc;
}
css 样式表代码如下:
@charset "UTF-8";
body .scroll_relative {
position: relative;
}
body .scroll_absolute {
position: absolute;
}
/*底部滚动条*/
body .scrollbar_bottom {
position: absolute;
left: 0;
bottom: 0;
display: block;
width: 40px;
height: 5px;
background: gray;
border-radius: 2.5px 2.5px 2.5px 2.5px;
transition-property: background-color, opacity;
transition-duration: 0.3s;
transition-timing-function: ease-out;
transition-delay: 0s;
}
/*右边滚动条*/
body .scrollbar_right {
position: absolute;
top: 0;
right: 0;
display: block;
width: 5px;
height: 40px;
background: gray;
border-radius: 2.5px 2.5px 2.5px 2.5px;
transition-property: background-color, opacity;
transition-duration: 0.3s;
transition-timing-function: ease-out;
transition-delay: 0s;
}
/*最外层容器测试样式*/
body .container_scroll {
width: 200px;
height: 300px;
background: #f7f7f7;
overflow: hidden;
}
HTML代码如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link type="text/css" rel="stylesheet" href="./css/scroll.css">
<title>自定义滚动条展示</title>
</head>
<body>
<!--滚动条测试-->
<div id="container_tb" class="container_scroll">
<div id="content_tb" style="min-height: 700px;">
这个事件在标准下和IE下是有区别的。
firefox是按标准实现的,事件名为"DOMMouseScroll ",IE下采用的则是"mousewheel "。
当然一行代码就解决了兼容问题.
<br>
<br>
<br>
</div>
<i id="scrollbar_tb" class="scrollbar_right"></i>
</div>
<div id="container_lr_01" class="container_scroll" style="margin: 20px auto 0 auto;">
<div id="content_lr_01">
<p style="width: 1000px;">
CSS 动画属性
@keyframes 规定动画模式。
animation 设置所有动画属性的简写属性
animation-delay 规定动画开始的延迟。
animation-direction 规定动画是向前播放、向后播放还是交替播放。
animation-duration 规定动画完成一个周期应花费的时间。
animation-fill-mode 规定元素在不播放动画时的样式(在开始前、结束后,或两者同时)。
animation-iteration-count 规定动画应播放的次数。
animation-name 规定 @keyframes 动画的名称。
animation-play-state 规定动画是运行还是暂停。
animation-timing-function 规定动画的速度曲线。
<br>
-----------------------------------------------
<br>
animation 属性是一个简写属性,用于设置六个动画属性:
animation-name 规定需要绑定到选择器的 keyframe 名称
animation-duration 规定完成动画所花费的时间,以秒或毫秒计
animation-timing-function 规定动画的速度曲线。
animation-delay 规定在动画开始之前的延迟。
animation-iteration-count 规定动画应该播放的次数。
animation-direction 规定是否应该轮流反向播放动画。
</p>
</div>
<i id="scrollbar_lr_01" class="scrollbar_bottom"></i>
</div>
<div id="container_lr_02" class="container_scroll" style="margin: 20px 0 0 0;">
<div id="content_lr_02">
<p style="width: 1000px;">
transition是CSS3新增的动画属性,可以实现属性的平滑过渡,大大提高用户体验,对于多个属性进行过渡的话很多人会这样写 .tr{ transition:all 1s}
</p>
</div>
<i id="scrollbar_lr_02" class="scrollbar_bottom"></i>
</div>
<script type="text/javascript" src="./js/scroll.js"></script>
<script type="text/javascript">
window.onload = function (e) {
my_scroll("container_tb", "content_tb", "scrollbar_tb", 1);
my_scroll("container_lr_01", "content_lr_01", "scrollbar_lr_01", 2);
my_scroll("container_lr_02", "content_lr_02", "scrollbar_lr_02", 2);
}
</script>
</body>
</html>
如图:
纵向
横向