模拟滚动条效果

1.HTML部分页面
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 300px;
height: 500px;
border: 1px solid red;
margin: 50px auto;
overflow: hidden;
position: relative;
}
.scroll {
width: 20px;
height: 530px;
background-color: #ccc;
position: absolute;
top: 0;
right: 0;
}
.bar {
width: 20px;
background-color: red;
border-radius: 10px;
cursor: pointer;
position: absolute;
top: 0;
}
.content {
padding: 15px;
}
</style>
<script src="animate.js"></script>
<script>
window.onload = function () {
//需求:模拟滚动条,鼠标拖动滚动条,滚动条动,而且内容等比例联动。
//步骤:
//1.根据内容和盒子的比例确定bar的高。
//2.绑定事件(鼠标按下,然后移动)
//3.鼠标移动,bar联动
//4.内容等比例联动
//0.获取相关元素
var box = document.getElementById("box");
var content = box.children[0];
var scroll = box.children[1];
var bar = scroll.children[0];
//1.根据内容和盒子的比例确定bar的高。
//内容的高/盒子的高 = scroll的高/bar的高
//bar的高 = 盒子的高*scroll的高/内容的高
var barHeight = box.offsetHeight*scroll.offsetHeight/content.offsetHeight;
bar.style.height = barHeight + "px";
//2.绑定事件(鼠标按下,然后移动)
bar.onmousedown = function (event) {
event = event || window.event;
var pageyy = event.pageY || scroll().top + event.clientY;
var y = pageyy - bar.offsetTop;
//模拟拖拽案例
document.onmousemove = function (event) {
//新五步获取鼠标在页面的位置。
event = event || window.event;
var pagey = event.pageY || scroll().top + event.clientY;
//鼠标的位置-鼠标在盒子中的位置。
pagey = pagey - y;
//限制y的取值。大于0,小于scroll的高度-bar的高度
if(pagey<0){
pagey = 0;
}
if(pagey>scroll.offsetHeight-bar.offsetHeight){
pagey = scroll.offsetHeight-bar.offsetHeight;
}
//3.鼠标移动,bar联动
bar.style.top = pagey + "px";
//4.内容等比例联动
//高级比例: 内容走的距离/bar走的距离 = (内容的高-大盒子的高)/(scroll的高-bar的高)
var s = pagey *(content.offsetHeight-box.offsetHeight)/(scroll.offsetHeight-bar.offsetHeight);
//s赋值给content。通过marginTop负值移动content
content.style.marginTop = -s+"px";
//让被选文字清除。
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
//事件解绑
document.onmouseup = function () {
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div class="box" id="box">
<div class="content">
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
孩儿励志出湘关,学不成名终不还。<br>
埋骨何须桑梓地,人生无处不青山。<br>
-------------结束------------<br>
</div>
<div class="scroll">
<div class="bar"></div>
</div>
</div>
</body>
</html>
2.javascript部分
//缓动动画封装
function animate(ele,target) {
clearInterval(ele.timer);
ele.timer = setInterval(function () {
var step = (target-ele.offsetTop)/10;
step = step>0?Math.ceil(step):Math.floor(step);
ele.style.top = ele.offsetTop + step + "px";
console.log(1);
if(Math.abs(target-ele.offsetTop)<Math.abs(step)){
ele.style.top = target + "px";
clearInterval(ele.timer);
}
},25);
}
/**
* Created by andy on 2015/12/8.
*/
function scroll() { // 开始封装自己的scrollTop
if(window.pageYOffset != null) { // ie9+ 高版本浏览器
// 因为 window.pageYOffset 默认的是 0 所以这里需要判断
return {
left: window.pageXOffset,
top: window.pageYOffset
}
}
else if(document.compatMode === "CSS1Compat") { // 标准浏览器 来判断有没有声明DTD
return {
left: document.documentElement.scrollLeft,
top: document.documentElement.scrollTop
}
}
return { // 未声明 DTD
left: document.body.scrollLeft,
top: document.body.scrollTop
}
}
/**
* Created by Lenovo on 2016/9/2.
*/
/**
* 通过传递不同的参数获取不同的元素
* @param str
* @returns {*}
*/
function $(str){
var str1 = str.charAt(0);
if(str1==="#"){
return document.getElementById(str.slice(1));
}else if(str1 === "."){
return document.getElementsByClassName(str.slice(1));
}else{
return document.getElementsByTagName(str);
}
}
/**
* 功能:给定元素查找他的第一个元素子节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getFirstNode(ele){
var node = ele.firstElementChild || ele.firstChild;
return node;
}
/**
* 功能:给定元素查找他的最后一个元素子节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getLastNode(ele){
return ele.lastElementChild || ele.lastChild;
}
/**
* 功能:给定元素查找他的下一个元素兄弟节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getNextNode(ele){
return ele.nextElementSibling || ele.nextSibling;
}
/**
* 功能:给定元素查找他的上一个兄弟元素节点,并返回
* @param ele
* @returns {Element|*|Node}
*/
function getPrevNode(ele){
return ele.previousElementSibling || ele.previousSibling;
}
/**
* 功能:给定元素和索引值查找指定索引值的兄弟元素节点,并返回
* @param ele 元素节点
* @param index 索引值
* @returns {*|HTMLElement}
*/
function getEleOfIndex(ele,index){
return ele.parentNode.children[index];
}
/**
* 功能:给定元素查找他的所有兄弟元素,并返回数组
* @param ele
* @returns {Array}
*/
function getAllSiblings(ele){
//定义一个新数组,装所有的兄弟元素,将来返回
var newArr = [];
var arr = ele.parentNode.children;
for(var i=0;i<arr.length;i++){
//判断,如果不是传递过来的元素本身,那么添加到新数组中。
if(arr[i]!==ele){
newArr.push(arr[i]);
}
}
return newArr;
}

浙公网安备 33010602011771号