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字符串拼接的效率问题
Dec 25 Javascript
浅谈JavaScript之事件绑定
Jul 08 Javascript
JS小功能(offsetLeft实现图片滚动效果)实例代码
Nov 28 Javascript
5个JavaScript经典面试题
Oct 13 Javascript
javascript面向对象之访问对象属性的两种方式分析
Jan 13 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
Dec 24 Javascript
js 实现数值的千分位及保存小数方法(推荐)
Aug 01 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
Sep 18 Javascript
Vue从TodoList中学父子组件通信
Feb 05 Javascript
js实现网页同时进行多个倒计时功能
Feb 25 Javascript
Vue-CLI 项目在pycharm中配置方法
Aug 30 Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
Aug 19 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 session有效期问题
2009/04/26 PHP
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
2011/04/12 Javascript
javascript笔记 String类replace函数的一些事
2011/09/22 Javascript
精心挑选的15款优秀jQuery 本特效插件和教程
2012/08/06 Javascript
javascript计时器事件使用详解
2014/01/07 Javascript
鼠标左键单击冲突的问题解决方法(防止冒泡)
2014/05/14 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
DOM操作和jQuery实现选项移动操作的简单实例
2016/06/07 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
详解springmvc 接收json对象的两种方式
2016/12/06 Javascript
js事件冒泡与事件捕获详解
2017/02/20 Javascript
整理一些最近经常遇到的前端面试题
2017/04/25 Javascript
js设置随机切换背景图片的简单实例
2017/11/12 Javascript
深入理解JavaScript的值传递和引用传递
2018/10/24 Javascript
vue中v-for通过动态绑定class实现触发效果
2018/12/06 Javascript
[16:21]教你分分钟做大人:圣堂刺客
2014/12/03 DOTA
[42:24]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第三场 11.27
2020/12/01 DOTA
python通过scapy获取局域网所有主机mac地址示例
2014/05/04 Python
Python文件操作基本流程代码实例
2017/12/11 Python
Python 中的range(),以及列表切片方法
2018/07/02 Python
Python基于递归算法求最小公倍数和最大公约数示例
2018/07/27 Python
python开启摄像头以及深度学习实现目标检测方法
2018/08/03 Python
pandas 快速处理 date_time 日期格式方法
2018/11/12 Python
在linux系统下安装python librtmp包的实现方法
2019/07/22 Python
Python实现一个带权无回置随机抽选函数的方法
2019/07/24 Python
python输出数组中指定元素的所有索引示例
2019/12/06 Python
python删除文件、清空目录的实现方法
2020/09/23 Python
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
编码实现字符串转整型的函数
2012/06/02 面试题
个人求职简历的自我评价
2013/10/19 职场文书
商场促销活动方案
2014/02/08 职场文书
销售岗位职责范本
2014/06/12 职场文书
2014年学校安全工作总结
2014/11/13 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
vue3.0 数字翻牌组件的使用方法详解
2022/04/20 Vue.js