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 相关文章推荐
jQuery 剧场版 你必须知道的javascript
May 27 Javascript
JavaScript 组件之旅(四):测试 JavaScript 组件
Oct 28 Javascript
jQuery 自动增长的文本输入框实现代码
Apr 02 Javascript
iframe窗口高度自适应的实现方法
Jan 08 Javascript
jQuery实现仿百度首页滑动伸缩展开的添加服务效果代码
Sep 09 Javascript
全面解析bootstrap格子布局
May 22 Javascript
AngularJS表单和输入验证实例
Nov 02 Javascript
Vue.js实现一个todo-list的上移下移删除功能
Jun 26 Javascript
如何利用@angular/cli V6.0直接开发PWA应用详解
May 06 Javascript
详解如何为你的angular app构建一个第三方库
Dec 07 Javascript
微信小程序如何实现全局重新加载
Jun 05 Javascript
JS中的const命令你真懂它吗
Mar 08 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初学者头疼问题总结
2006/07/08 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
2013/06/24 PHP
php循环table实现一行两列显示的方法
2015/06/04 PHP
Javascript学习笔记1 数据类型
2010/01/11 Javascript
浅谈Javascript Base64 加密解密
2014/12/28 Javascript
jQuery实用技巧必备(上)
2015/11/02 Javascript
如何在Linux上安装Node.js
2016/04/01 Javascript
微信小程序 LOL 英雄介绍开发实例
2016/09/30 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
Angular工具方法学习
2016/12/26 Javascript
利用jquery如何从json中读取数据追加到html中
2017/12/01 jQuery
VUE v-model表单数据双向绑定完整示例
2019/01/21 Javascript
小程序中英文混合排序问题解决
2019/08/02 Javascript
微信小程序拼接图片链接无底洞深入探究
2019/09/03 Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
2019/09/09 Javascript
vant IndexBar实现的城市列表的示例代码
2019/11/20 Javascript
高性能js数组去重(12种方法,史上最全)
2019/12/21 Javascript
jQuery实现简单评论功能
2020/08/19 jQuery
python数据结构之图深度优先和广度优先实例详解
2015/07/08 Python
Python cx_freeze打包工具处理问题思路及解决办法
2016/02/13 Python
django之状态保持-使用redis存储session的例子
2019/07/28 Python
Python调用shell命令常用方法(4种)
2020/05/11 Python
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
HMV日本官网:全球知名的音乐、DVD和电脑游戏零售巨头
2016/08/13 全球购物
韩国女装NO.1网店:STYLENANDA
2016/09/16 全球购物
HTC VIVE美国官网:VR虚拟现实眼镜
2018/02/13 全球购物
乌克兰机票、铁路和巴士票、酒店搜索、保险:Tickets.ua
2020/01/11 全球购物
体育教师工作总结的自我评价
2013/10/10 职场文书
学习委员自我鉴定
2014/01/13 职场文书
数学国培研修感言
2014/02/13 职场文书
青春演讲稿范文
2014/05/08 职场文书
银行进社区活动总结
2014/07/07 职场文书
五四青年节活动总结
2015/02/10 职场文书
2015年度招聘工作总结
2015/05/28 职场文书
忠诚教育学习心得体会
2016/01/23 职场文书
mysql insert 存在即不插入语法说明
2022/03/25 MySQL