模拟滚动条效果

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;
}

  

原文地址:https://www.cnblogs.com/sj1988/p/6624900.html