1.HTML部分页面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } .box { 300px; height: 500px; border: 1px solid red; margin: 50px auto; overflow: hidden; position: relative; } .scroll { 20px; height: 530px; background-color: #ccc; position: absolute; top: 0; right: 0; } .bar { 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; }