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

×

目录

[1]原理介绍 [2]数字加减 [3]元素尺寸[4]内容滚动

前面的话

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

原理介绍

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

<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>
时间: 2024-09-29 18:04:47

javascript动画系列第五篇——模拟滚动条的相关文章

javascript动画系列第三篇——碰撞检测

前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多,接下来使用九宫格分析法 假设黄色元素要与红色元素进行碰撞.将红色元素所处的区域分为9部分,自身处于第9部分,周围还存在8个部分.只要黄色元素进入红色元素的第9部分,就算碰撞.否则,都算未碰撞 总共分为以下5种情况: 1.处于上侧未碰撞区域——1.2.3区域 2.处于右侧未碰撞区域——3.4.5区域

深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域

× 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已.但实际上,它们并不相同,却相互纠缠在一起.本文先用一张图开宗明义,然后进行术语的简单解释,最后根据图示内容进行详细说明 图示 查看大图 概念 [作用域] 作用域是一套规则,用于确定在何处以及如何查找标识符.关于LHS查询和RHS查询详见作用域系列第一篇内部原理. 作用域分

深入理解javascript作用域系列第五篇

前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已.但实际上,它们并不相同,却相互纠缠在一起.本文先用一张图开宗明义,然后进行术语的简单解释,最后根据图示内容进行详细说明 图示 查看大图 概念 [作用域] 作用域是一套规则,用于确定在何处以及如何查找标识符.关于LHS查询和RHS查询详见作用域系列第一篇内部原理. 作用域分为词法作用域和动态作用域.javascript使用词法作

javascript动画系列第四篇——拖拽改变元素大小

× 目录 [1]原理简介 [2]范围圈定 [3]大小改变[4]代码优化 前面的话 拖拽可以让元素移动,也可以改变元素大小.本文将详细介绍拖拽改变元素大小的效果实现 原理简介 拖拽让元素移动,是改变定位元素的left和top值实现的.而拖拽改变元素大小,则还需要改变元素的宽高 范围圈定 我们把改变元素大小的范围圈定在距离相应边10px的范围内 左侧边界L = obj.offsetLeft + 10 右侧边界R = obj.offsetLeft + obj.offsetWidth - 10 上侧边界

javascript动画系列第一篇——模拟拖拽

× 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容性问题,以及功能实现的方式,用的不是很广泛.javascript动画广泛使用的还是模拟拖拽.本文将详细介绍该内容 原理介绍 模拟拖拽最终效果和在桌面上移动文件夹的效果类似 鼠标按下时,拖拽开始.鼠标移动时,被拖拽元素跟着鼠标一起移动.鼠标抬起时,拖拽结束 所以,拖拽的重点是确定被拖拽元素是如何移动的

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

显示目录 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇--雪碧图 定义 css雪碧图(sprite)是一种网页图片应用处理方式,它允许将一个页面涉及到的所有零星图片都包含到一张大图中.使用雪碧图的处理方式可以实现两个优点: [1]减少http请求次数 [2]减少图片大小,提升网页加载速度 (多张图片加载速度小于拼合成的图片的加载速度) 凡事都不完美,实现优点的同时也带来了缺点,即提

深入理解javascript作用域系列第四篇——块作用域

× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的代码,比如块作用域.随着ES6的推广,块作用域也将用得越来越广泛.本文是深入理解javascript作用域系列第四篇——块作用域 let for (var i= 0; i<10; i++) { console.log(i); } 上面这段是很熟

深入理解javascript函数系列第三篇

前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数系列第三篇--属性和方法 属性 [length属性] 函数系列第二篇中介绍过,arguments对象的length属性表示实参个数,而函数的length属性则表示形参个数 function add(x,y){ console.log(arguments.length)//3 console.log(

深入理解javascript作用域系列第三篇

前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇--声明提升(hoisting) 变量声明提升 a = 2 ; var a; console.log( a ); 直觉上,会认为是undefined,因为var a声明在a = 2;之后,可能变量被重新赋值了,因为会被赋予默认值undefined.但是,真正的输出结果是2 console.log( a ) ; var a