javascript动画系列之模拟滚动条


Posted in Javascript onDecember 13, 2016

前面的话

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

原理介绍

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

<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 相关文章推荐
javascript 拖放效果实现代码
Jan 22 Javascript
JavaScript面向对象设计二 构造函数模式
Dec 20 Javascript
JS正则表达式大全(整理详细且实用)
Nov 14 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
Nov 21 Javascript
jQuery - css() 方法示例详解
Jan 16 Javascript
JavaScript改变CSS样式的方法汇总
May 07 Javascript
关于json字符串与实体之间的严格验证代码
Nov 10 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
Feb 16 Javascript
值得分享和收藏的xmlplus组件学习教程
May 05 Javascript
详解webpack自动生成html页面
Jun 29 Javascript
Javascript(es2016) import和require用法和区别详解
Aug 11 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
Sep 21 Javascript
js闭包用法实例详解
Dec 13 #Javascript
深入学习Bootstrap表单
Dec 13 #Javascript
ThinkJS中如何使用MongoDB的CURD操作
Dec 13 #Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 #Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
Dec 13 #Javascript
教大家轻松制作Bootstrap漂亮表格(table)
Dec 13 #Javascript
AngularJS自定义控件实例详解
Dec 13 #Javascript
You might like
PHP基础学习之流程控制的实现分析
2013/04/28 PHP
php静态文件返回304技巧分享
2015/01/06 PHP
php发送与接收流文件的方法
2015/02/11 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
PHP调试及性能分析工具Xdebug详解
2017/02/09 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
2018/03/31 PHP
PHP7新增函数
2021/03/09 PHP
ExtJS TabPanel beforeremove beforeclose使用说明
2010/03/31 Javascript
JQuery 自定义CircleAnimation,Animate方法学习笔记
2011/07/10 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
使用Node.js实现一个简单的FastCGI服务器实例
2014/06/09 Javascript
零基础搭建Node.js、Express、Ejs、Mongodb服务器及应用开发入门
2014/12/20 Javascript
浅谈javascript 迭代方法
2015/01/21 Javascript
JavaScript中isPrototypeOf函数作用和使用实例
2015/06/01 Javascript
JQuery标签页效果的两个实例讲解(4)
2015/09/17 Javascript
JS实现网页上随机产生超链接地址的方法
2015/11/09 Javascript
Webpack 实现 AngularJS 的延迟加载
2016/03/02 Javascript
jQuery与JavaScript节点创建方法的对比
2016/11/18 Javascript
VueJs路由跳转——vue-router的使用详解
2017/01/10 Javascript
Vue组件实例间的直接访问实现代码
2017/08/20 Javascript
浅谈JavaScript find 方法不支持IE的问题
2017/09/28 Javascript
Vuex中的Mutations的具体使用方法
2020/06/01 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
在Python的Django框架下使用django-tagging的教程
2015/05/30 Python
python检查序列seq是否含有aset中项的方法
2015/06/30 Python
详解python3中tkinter知识点
2018/06/21 Python
利用Python如何批量修改数据库执行Sql文件
2018/07/29 Python
利用python实现周期财务统计可视化
2019/08/25 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
HTML5 script元素async、defer异步加载使用介绍
2013/08/23 HTML / CSS
新加坡最受追捧的体验平台:Hapz
2018/01/01 全球购物
关于孝道的演讲稿
2014/05/21 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
老干部工作汇报材料
2014/10/28 职场文书
群众路线教育实践活动学习心得体会
2014/10/30 职场文书