zoukankan      html  css  js  c++  java
  • javascript动画系列第五篇——模拟滚动条

    前面的话

      当元素内容溢出元素尺寸范围时,会出现滚动条。但由于滚动条在各浏览器下表现不同,兼容性不好。所以,模拟滚动条也是很常见的应用。本文将详细介绍滚动条模拟

    原理介绍

      滚动条模拟实际上和元素模拟拖拽类似。仅仅通过范围限定,使元素只可以在单一方向上拖拽

    <div id="box" style="height: 200px; 16px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
        <div id="test" style="height: 60px; 16px;background-color:#555;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <script>
    function addEvent(target,type,handler){
        if(target.addEventListener){
            target.addEventListener(type,handler,false);
        }else{
            target.attachEvent('on'+type,function(event){
                return handler.call(target,event);
            });
        }
    }
    (function(){
        var y0,y1,isMoving;
        var ele = document.getElementById('test');
    
        var mousedownHandler = function(e){
            e = e || event;
            y0 = ele.offsetTop;
            y1 = e.clientY;
            //按下鼠标时,表示正在运动
            isMoving = true;
        }
        var mousemoveHandler = function(e){
            //如果没有触发down事件,而直接触发move事件,则函数直接返回
            if(!isMoving){
                return;
            }
            e = e || event;
            var y2 = e.clientY;   
            var Y = y0 + (y2 - y1);
            if(Y < 0){Y = 0;}
            var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
            if(Y > YMax){Y = YMax;}
            ele.style.top = Y + 'px';
        }
        var mouseupHandler = function(e){
            //鼠标抬起时,表示停止运动
            isMoving = false;
            //释放全局捕获
            if(ele.releaseCapture){
                ele.releaseCapture();
            }   
        }
        var preventDefaultHandler = function(e){
            e = e || event;
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
            //IE8-浏览器阻止默认行为
            if(ele.setCapture){
                ele.setCapture();
            }
        }
        addEvent(ele,'mousedown',mousedownHandler);
        addEvent(ele,'mousedown',preventDefaultHandler);
        addEvent(document,'mousemove',mousemoveHandler);
        addEvent(document,'mouseup',mouseupHandler);
    
    })();
    </script>    

      通过将上面代码封装成函数,可以实现横向和纵向两种滚动条

    <div id="box1" style="height: 200px; 16px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
        <div id="test1" style="height: 60px; 16px;background-color:#555;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <div id="box2" style="height: 16px; 200px;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
        <div id="test2" style="height: 16px; 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <script>
    function addEvent(target,type,handler){
        if(target.addEventListener){
            target.addEventListener(type,handler,false);
        }else{
            target.attachEvent('on'+type,function(event){
                return handler.call(target,event);
            });
        }
    }
    function scrollbar(ele,str){
        var x0,x1,y0,y1,isMoving;
    
        var mousedownHandler = function(e){
            e = e || event;
            x0 = ele.offsetLeft;
            y0 = ele.offsetTop;
            x1 = e.clientX;
            y1 = e.clientY;
            //按下鼠标时,表示正在运动
            isMoving = true;
        }
        var mousemoveHandler = function(e){
            //如果没有触发down事件,而直接触发move事件,则函数直接返回
            if(!isMoving){
                return;
            }
            e = e || event;
            if(str == 'x'){
                var x2 = e.clientX;   
                var X = x0 + (x2 - x1);
                if(X < 0){X = 0;}
                var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
                if(X > XMax){X = XMax;}
                ele.style.left = X + 'px';    
            }else{
                var y2 = e.clientY;   
                var Y = y0 + (y2 - y1);
                if(Y < 0){Y = 0;}
                var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
                if(Y > YMax){Y = YMax;}
                ele.style.top = Y + 'px';            
            }
    
        }
        var mouseupHandler = function(e){
            //鼠标抬起时,表示停止运动
            isMoving = false;
            //释放全局捕获
            if(ele.releaseCapture){
                ele.releaseCapture();
            }   
        }
        var preventDefaultHandler = function(e){
            e = e || event;
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
            //IE8-浏览器阻止默认行为
            if(ele.setCapture){
                ele.setCapture();
            }
        }
        addEvent(ele,'mousedown',mousedownHandler);
        addEvent(ele,'mousedown',preventDefaultHandler);
        addEvent(document,'mousemove',mousemoveHandler);
        addEvent(document,'mouseup',mouseupHandler);
    
    };
    
    scrollbar(test1);
    scrollbar(test2,'x');
    </script>    

    应用

      下面来介绍通过滚动条实现的几个应用

    数字加减

      通过移动滚动条来实现数字的加减。比例关系为:

    滚动条已移动距离/滚动条可移动距离= 数字当前值/数字最大值
    <div id="box" style="height: 16px; 200px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
        <div id="test" style="height: 16px; 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <span id="result">0</span>
    <script>
    function addEvent(target,type,handler){
        if(target.addEventListener){
            target.addEventListener(type,handler,false);
        }else{
            target.attachEvent('on'+type,function(event){
                return handler.call(target,event);
            });
        }
    }
    function scrollbar(ele,str,max){
        var x0,x1,y0,y1,isMoving,radio;
    
        var mousedownHandler = function(e){
            e = e || event;
            x0 = ele.offsetLeft;
            y0 = ele.offsetTop;
            x1 = e.clientX;
            y1 = e.clientY;
            //按下鼠标时,表示正在运动
            isMoving = true;
            //x轴方向
            if(str == 'x'){
                ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
            //否则为y轴方向
            }else{
                var disY = e.clientY - ele.offsetTop;
                ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
            }
        }
        var mousemoveHandler = function(e){
            //如果没有触发down事件,而直接触发move事件,则函数直接返回
            if(!isMoving){
                return;
            }
            e = e || event;
            if(str == 'x'){
                var x2 = e.clientX;   
                var X = x0 + (x2 - x1);
                if(X < 0){X = 0;}
                var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
                if(X > XMax){X = XMax;}
                ele.style.left = X + 'px';    
                result.innerHTML = Math.round(ratio * X);
            }else{
                var y2 = e.clientY;   
                var Y = y0 + (y2 - y1);
                if(Y < 0){Y = 0;}
                var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
                if(Y > YMax){Y = YMax;}
                ele.style.top = Y + 'px';
                result.innerHTML = Math.round(ratio * Y);             
            }
    
        }
        var mouseupHandler = function(e){
            //鼠标抬起时,表示停止运动
            isMoving = false;
            //释放全局捕获
            if(ele.releaseCapture){
                ele.releaseCapture();
            }   
        }
        var preventDefaultHandler = function(e){
            e = e || event;
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
            //IE8-浏览器阻止默认行为
            if(ele.setCapture){
                ele.setCapture();
            }
        }
        addEvent(ele,'mousedown',mousedownHandler);
        addEvent(ele,'mousedown',preventDefaultHandler);
        addEvent(document,'mousemove',mousemoveHandler);
        addEvent(document,'mouseup',mouseupHandler);
    
    };
    
    scrollbar(test,'x',100);
    </script>    

    元素尺寸

      通过拖动滚动条来实现元素尺寸的变化,以改变元素宽度为例。比例关系为:

    滚动条已移动距离/滚动条可移动距离= 元素当前宽度/元素最大宽度
    <div id="box" style="height: 16px; 200px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;">
        <div id="test" style="height: 16px; 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <span id="result" style=" 1px;height: 50px;background-color:pink;display:inline-block;"></span>
    <script>
    function addEvent(target,type,handler){
        if(target.addEventListener){
            target.addEventListener(type,handler,false);
        }else{
            target.attachEvent('on'+type,function(event){
                return handler.call(target,event);
            });
        }
    }
    function scrollbar(ele,str,max){
        var x0,x1,y0,y1,isMoving,radio;
    
        var mousedownHandler = function(e){
            e = e || event;
            x0 = ele.offsetLeft;
            y0 = ele.offsetTop;
            x1 = e.clientX;
            y1 = e.clientY;
            //按下鼠标时,表示正在运动
            isMoving = true;
            //x轴方向
            if(str == 'x'){
                ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
            //否则为y轴方向
            }else{
                var disY = e.clientY - ele.offsetTop;
                ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
            }
        }
        var mousemoveHandler = function(e){
            //如果没有触发down事件,而直接触发move事件,则函数直接返回
            if(!isMoving){
                return;
            }
            e = e || event;
            if(str == 'x'){
                var x2 = e.clientX;   
                var X = x0 + (x2 - x1);
                if(X < 0){X = 0;}
                var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
                if(X > XMax){X = XMax;}
                ele.style.left = X + 'px';    
                result.style.width = Math.round(ratio * X) + 'px';
            }else{
                var y2 = e.clientY;   
                var Y = y0 + (y2 - y1);
                if(Y < 0){Y = 0;}
                var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
                if(Y > YMax){Y = YMax;}
                ele.style.top = Y + 'px';
                result.style.width = Math.round(ratio * Y) + 'px';             
            }
    
        }
        var mouseupHandler = function(e){
            //鼠标抬起时,表示停止运动
            isMoving = false;
            //释放全局捕获
            if(ele.releaseCapture){
                ele.releaseCapture();
            }   
        }
        var preventDefaultHandler = function(e){
            e = e || event;
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
            //IE8-浏览器阻止默认行为
            if(ele.setCapture){
                ele.setCapture();
            }
        }
        addEvent(ele,'mousedown',mousedownHandler);
        addEvent(ele,'mousedown',preventDefaultHandler);
        addEvent(document,'mousemove',mousemoveHandler);
        addEvent(document,'mouseup',mouseupHandler);
    
    };
    
    scrollbar(test,'x',100);
    </script>

    内容滚动

      通过拖动滚动条来实现内容滚动,比例关系为:

    滚动条已移动距离/滚动条可移动距离= 内容已移动距离/内容可移动距离
    <div id="box" style="height: 200px; 16px;display:inline-block;background-color:#F5F5F5;border-radius:10px;box-shadow:inset 0 0 6px rgba(0,0,0,0.3);position:relative;vertical-align:middle;">
        <div id="test" style="height: 60px; 16px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
    </div>
    <span id="result" style=" 100px;height: 200px;background-color:pink;display:inline-block;line-height:30px;vertical-align:middle;position:relative;overflow:hidden;"><div id="resultIn" style="position:absolute;top:0;">测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br>测试文字<br></div></span>
    <script>
    function addEvent(target,type,handler){
        if(target.addEventListener){
            target.addEventListener(type,handler,false);
        }else{
            target.attachEvent('on'+type,function(event){
                return handler.call(target,event);
            });
        }
    }
    function scrollbar(ele,str,max){
        var x0,x1,y0,y1,isMoving,radio;
        var max = result.offsetHeight - resultIn.offsetHeight;
        var mousedownHandler = function(e){
            e = e || event;
            x0 = ele.offsetLeft;
            y0 = ele.offsetTop;
            x1 = e.clientX;
            y1 = e.clientY;
            //按下鼠标时,表示正在运动
            isMoving = true;
            //x轴方向
            if(str == 'x'){
                ratio = max/(ele.parentNode.offsetWidth - ele.offsetWidth);
            //否则为y轴方向
            }else{
                var disY = e.clientY - ele.offsetTop;
                ratio =max/(ele.parentNode.offsetHeight - ele.offsetHeight);
            }
        }
        var mousemoveHandler = function(e){
            //如果没有触发down事件,而直接触发move事件,则函数直接返回
            if(!isMoving){
                return;
            }
            e = e || event;
            if(str == 'x'){
                var x2 = e.clientX;   
                var X = x0 + (x2 - x1);
                if(X < 0){X = 0;}
                var XMax = parseInt(ele.parentNode.clientWidth) - ele.offsetWidth;
                if(X > XMax){X = XMax;}
                ele.style.left = X + 'px';    
                resultIn.style.left = Math.round(ratio * X) + 'px';
            }else{
                var y2 = e.clientY;   
                var Y = y0 + (y2 - y1);
                if(Y < 0){Y = 0;}
                var YMax = parseInt(ele.parentNode.clientHeight) - ele.offsetHeight;
                if(Y > YMax){Y = YMax;}
                ele.style.top = Y + 'px';
                resultIn.style.top = Math.round(ratio * Y) + 'px';        
            }
    
        }
        var mouseupHandler = function(e){
            //鼠标抬起时,表示停止运动
            isMoving = false;
            //释放全局捕获
            if(ele.releaseCapture){
                ele.releaseCapture();
            }   
        }
        var preventDefaultHandler = function(e){
            e = e || event;
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
            //IE8-浏览器阻止默认行为
            if(ele.setCapture){
                ele.setCapture();
            }
        }
        addEvent(ele,'mousedown',mousedownHandler);
        addEvent(ele,'mousedown',preventDefaultHandler);
        addEvent(document,'mousemove',mousemoveHandler);
        addEvent(document,'mouseup',mouseupHandler);
    
    };
    
    scrollbar(test);
    </script>

  • 相关阅读:
    程序优化
    obsidium 重定位
    Obsidium V1.3.0.4 脱壳
    SEH 栈溢出
    DWORD SHOOT
    两种堆表学习
    修改网页转向
    WireShark过滤语法
    获取系统信息学习
    怎么在 渗透无键盘 查询机
  • 原文地址:https://www.cnblogs.com/xiaohuochai/p/5901426.html
Copyright © 2011-2022 走看看