javascript动画系列第五篇——模拟滚动条

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript动画系列第五篇——模拟滚动条相关的知识,希望对你有一定的参考价值。

前面的话

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

 

原理介绍

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

<div id="box" style="height: 200px;width: 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;width: 16px;background-color:#555;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<script>
test.onmousedown = function(e){
    e = e || event;
    var that = this;
    var disY = e.clientY - this.offsetTop;
    document.onmousemove = function(e){
        e = e || event;
        var T = e.clientY - disY;
        if(T < 0){T = 0;}
        var TMax = parseInt(box.style.height) - that.offsetHeight;
        if(T > TMax){T = TMax;}
        that.style.top = T + px; 
    }
    document.onmouseup = function(){
        document.onmousemove = null;
        //释放全局捕获
        if(test.releaseCapture){test.releaseCapture();}
    }
    //IE8-浏览器阻止默认行为
    if(test.setCapture){test.setCapture();}
    //阻止默认行为
    return false;
}
</script>

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

<div id="box1" style="height: 200px;width: 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;width: 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;width: 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;width: 60px;background-color:#D62929;box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;position:absolute;"></div>
</div>
<script>
function scrollbar(obj,str){
    obj.onmousedown = function(e){
        e = e || event;
        var that = this;
        //x轴方向
        if(str == x){
            var disX = e.clientX - this.offsetLeft;
        //否则为y轴方向
        }else{
            var disY = e.clientY - this.offsetTop;
        }
        document.onmousemove = function(e){
            e = e || event;
            if(str == x){
                var L = e.clientX - disX;
                if(L < 0){L = 0;}
                var LMax = parseInt(obj.parentNode.style.width) - that.offsetWidth;
                if(L > LMax){L = LMax;}
                that.style.left = L + px; 
            }else{
                var T = e.clientY - disY;
                if(T < 0){T = 0;}
                var TMax = parseInt(obj.parentNode.style.height) - that.offsetHeight;
                if(T > TMax){T = TMax;}
                that.style.top = T + px; 
            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
            //释放全局捕获
            if(obj.releaseCapture){obj.releaseCapture();}
        }
        //IE8-浏览器阻止默认行为
        if(obj.setCapture){obj.setCapture();}
        //阻止默认行为
        return false;
    }    
}
scrollbar(test1);
scrollbar(test2,x)
</script>

应用

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

数字加减

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

滚动条已移动距离/滚动条可移动距离= 数字当前值/数字最大值
<div id="box" style="height: 16px;width: 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;width: 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 scrollbar(obj,str,max){
    obj.onmousedown = function(e){
        e = e || event;
        var that = this;
        //比例系数
        var ratio;
        //x轴方向
        if(str == x){
            var disX = e.clientX - this.offsetLeft;
            ratio = max/(this.parentNode.offsetWidth - this.offsetWidth);
        //否则为y轴方向
        }else{
            var disY = e.clientY - this.offsetTop;
            ratio =max/(this.parentNode.offsetHeight - this.offsetHeight);
        }
        document.onmousemove = function(e){
            e = e || event;
            if(str == x){
                var L = e.clientX - disX;
                if(L < 0){L = 0;}
                var LMax = parseInt(obj.parentNode.style.width) - that.offsetWidth;
                if(L > LMax){L = LMax;}
                that.style.left = L + px; 
                result.innerhtml = Math.round(ratio * L);
            }else{
                var T = e.clientY - disY;
                if(T < 0){T = 0;}
                var TMax = parseInt(obj.parentNode.style.height) - that.offsetHeight;
                if(T > TMax){T = TMax;}
                that.style.top = T + px; 
                result.innerHTML = Math.round(ratio * T); 
            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
            //释放全局捕获
            if(obj.releaseCapture){obj.releaseCapture();}
        }
        //IE8-浏览器阻止默认行为
        if(obj.setCapture){obj.setCapture();}
        //阻止默认行为
        return false;
    }    
}
scrollbar(test,x,100);
</script>

元素尺寸

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

滚动条已移动距离/滚动条可移动距离= 元素当前宽度/元素最大宽度
<div id="box" style="height: 16px;width: 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;width: 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="width: 1px;height: 50px;background-color:pink;display:inline-block;"></span>
<script>
function scrollbar(obj,str,max){
    obj.onmousedown = function(e){
        e = e || event;
        var that = this;
        //比例系数
        var ratio;
        //x轴方向
        if(str == x){
            var disX = e.clientX - this.offsetLeft;
            ratio = max/(this.parentNode.offsetWidth - this.offsetWidth);
        //否则为y轴方向
        }else{
            var disY = e.clientY - this.offsetTop;
            ratio =max/(this.parentNode.offsetHeight - this.offsetHeight);
        }
        document.onmousemove = function(e){
            e = e || event;
            if(str == x){
                var L = e.clientX - disX;
                if(L < 0){L = 0;}
                var LMax = parseInt(obj.parentNode.style.width) - that.offsetWidth;
                if(L > LMax){L = LMax;}
                that.style.left = L + px; 
                result.style.width = Math.round(ratio * L) + px;
            }else{
                var T = e.clientY - disY;
                if(T < 0){T = 0;}
                var TMax = parseInt(obj.parentNode.style.height) - that.offsetHeight;
                if(T > TMax){T = TMax;}
                that.style.top = T + px; 
                result.style.width = Math.round(ratio * T) + px; 
            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
            //释放全局捕获
            if(obj.releaseCapture){obj.releaseCapture();}
        }
        //IE8-浏览器阻止默认行为
        if(obj.setCapture){obj.setCapture();}
        //阻止默认行为
        return false;
    }    
}
scrollbar(test,x,100);
</script>

内容滚动

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

滚动条已移动距离/滚动条可移动距离= 内容已移动距离/内容可移动距离
<div id="box" style="height: 200px;width: 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;width: 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="width: 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 scrollbar(obj,str){
    var max = result.offsetHeight - resultIn.offsetHeight;
    obj.onmousedown = function(e){
        e = e || event;
        var that = this;
        //比例系数
        var ratio;
        //x轴方向
        if(str == x){
            var disX = e.clientX - this.offsetLeft;
            ratio = max/(this.parentNode.offsetWidth - this.offsetWidth);
        //否则为y轴方向
        }else{
            var disY = e.clientY - this.offsetTop;
            ratio =max/(this.parentNode.offsetHeight - this.offsetHeight);
        }
        document.onmousemove = function(e){
            e = e || event;
            if(str == x){
                var L = e.clientX - disX;
                if(L < 0){L = 0;}
                var LMax = parseInt(obj.parentNode.style.width) - that.offsetWidth;
                if(L > LMax){L = LMax;}
                that.style.left = L + px; 
                resultIn.style.top = Math.round(ratio * L) + px;
            }else{
                var T = e.clientY - disY;
                if(T < 0){T = 0;}
                var TMax = parseInt(obj.parentNode.style.height) - that.offsetHeight;
                if(T > TMax){T = TMax;}
                that.style.top = T + px; 
                resultIn.style.top = Math.round(ratio * T) + px;
            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
            //释放全局捕获
            if(obj.releaseCapture){obj.releaseCapture();}
        }
        //IE8-浏览器阻止默认行为
        if(obj.setCapture){obj.setCapture();}
        //阻止默认行为
        return false;
    }    
}
scrollbar(test,y);
</script>

以上是关于javascript动画系列第五篇——模拟滚动条的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 系列教程 5:动画

深入理解脚本化CSS系列第五篇——动态样式

第五篇 jQuery特效与动画

Python 学习日记第五篇 -- collections系列

第五篇Camunda系列-任务分配

前端工程师技能之photoshop巧用系列第五篇——雪碧图