随心所欲的滚动条,远离产品汪(二)
还记得上周咱们说的“随心所欲滚动条,远离产品汪”一文吗?当中介绍了自定义滚动条的基本原理与实现方法,在自定义滚动条实现后,可以通过对滚动条的上下拖动来控制内容区的显示,使用过的朋友会发现,如果对篇幅较长的内容来说,不停的拖动滚动条来查看内容,还是比较麻烦的,于是本文在上篇代码的基础上添加了滚轮事件并处理了相应的兼容问题。
本文内容
1、原理结构图
2、滚轮事件及兼容问题概要
3、具体实现步骤
4、小结
原理结构图
为了方便大家熟悉理解,希望大家能够回顾下上篇“随心所欲滚动条,远离产品汪(一)”,本文继续使用了上篇文章的原理结构图来辅助理解。
滚轮事件及兼容问题概要
在鼠标上,除了点击、拖拽等事件,当然也少不了滚轮事件了,但是比较有意思的一点是,平常大家碰到兼容问题首先想到了IE这个万年背锅侠,但是这次还真不是,火狐别树一帜的凑了一回热闹。
1.在滚轮事件中,火狐的的滚动事件是DOMMouseScroll,而其它浏览器是mousewheel,这一点是要仔细留意的。
2.在事件对象的兼容中。谷歌及主流浏览器的事件对象为参数e,而ie事件对象是window.event。
3.当滚动鼠标的时候,火狐浏览器通过检测datail的正负号就可以确定, 而其它浏览器IE、谷歌通过检测wheelDelta正负来确定。
具体实现步骤
滚动事件的添加原理其实与实现自定义滚动条的原理基本一致,只是多了滚轮滚动方向的判断及滚动值的获取。
首先,我们需要明白我们的滚轮是作用在谁的身上,根据实际需求来进行事件绑定,当我们鼠标移入可视区时,会触发滚轮事件,在移出可视区时则清除滚轮事件,接下来进行具体代码操作。
ps:此处为了方便理解使用jQuery来实现,记得引入呦。
较之上篇的实现代码,本篇中增加了两个变量。
1.通过设置变量Judge来判断滚轮的滚动方向,当Judge为ture时,滚轮向上滚动,当Judge为false时,滚轮向下滚动。
2.设置变量scrY来存储当前的滚动值,用来计算滚动块的scrollTop值。
步骤一:给可视区A绑定事件
var srcY = 0;
$('#cn').hover(function(e){ // 移入可视区A
$('#cn').on('mousewheel DOMMouseScroll', function(e) {
e = e.originalEvent || window.event.originalEvent; //绑定事件对象
scrollFunc(e); //执行scrollFunc(),判断滚动方向
var c = $('#cn').height() - $('#bx').height();
if (Judge) { // 当滚动向上滚动时,scrY递减
scrY--;
}else{
scrY++;// 当滚动向下滚动时,scrY递增
}
if (scrY <= 0) { //向上滚动的最大值
scrY = 0;
}
if (scrY >= c) {//向下滚动的最大值
scrY = c;
};
bx.scrollTop = scrY*10; //为防止滚轮滚动速度过慢,所以乘10增加滚轮滚动速度
sc.style.top =bx.scrollTop*bxHeight/cnHeight + "px";//与滚动条绑定
})
}, function(){//鼠标移出可视区A
//移除滚动事件
$('#cn').off('mousewheel DOMMouseScroll');
})
步骤二:判断滚轮滚动方向
var Judge = true;
function scrollFunc(e){//判断滚动方向
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
Judge = true;
}
if (e.wheelDelta < 0) {
//当滑轮向下滚动时
Judge = false;
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
Judge = false;
}
if (e.detail< 0) { //当滑轮向下滚动时
Judge = true;
}
}
}
完整实现代码
完整的实现代码在之前实现滚动条的基础代码上添加,并未做调整,大家可以很轻易的分清区别之处,方便大家理解,之后可以根据自己实际需求在这基础下进行代码优化与封装。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>自定义滚动条(2)</title>
<style type="text/css">
.wrap {
width: 200px;
height: 150px;
margin: 0 auto;
}
.con {
float: left;
overflow: hidden;
width: 180px;
height: 150px;
background: #39f;
}
.con p {
margin: 0;
color: #fff;
text-align: center;
line-height: 20px;
font-size: 14px;
}
.boxscr {
float: right;
position: relative;
width: 20px;
height: 150px;
background: #d9ecff;
}
.scr {
position: absolute;
width: 20px;
border-radius: 10px;
background: #c6ccff;
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrap">
<div class="con" id = "bx">
<p id="cn">
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
HTML5学堂-自定义滚动条
</p>
</div>
<div class="boxscr" id = "bs">
<div class="scr" id = "sc"></div>
</div>
</div>
<script src="jquery.js" type="text/javascript"></script>
<script>
var bx = document.getElementById("bx"),
cn = document.getElementById("cn")
bs = document.getElementById("bs"),
sc = document.getElementById("sc"),
oldY = 0, // 鼠标初次点击的Y轴坐标
newY = 0, // 鼠标拖动时的Y轴坐标
nowY = 0, // 鼠标拖动时滚动条C距父级顶部的高度
maxY = 0, // 拖动的最大极限值
nowDisY = 0, // 点击滚动条C时距父级顶部的高度
judge = 0, // 判断鼠标滚轮的方向
scrY = 0; // 滚轮滚动距离
bxHeight = bx.clientHeight, // 可视区A高度
bsHeight = bs.clientHeight, // 滚动区D高度
cnHeight = cn.offsetHeight; // 滚动块B的高度
// 根据滚动块B实际内容高度控制滚动条C的高度
scHeight = bxHeight/cnHeight * bxHeight;
sc.style.height = scHeight + "px";
// 当滚动块B实际高度小于可视区时,滚动条隐藏
if (cnHeight < bxHeight) {
bs.style.display = "none";
};
sc.onmousedown = function(e) {
oldY = e.clientY;
nowDisY = sc.offsetTop; // 当前的滚动条C的top值
e.preventDefault();
document.onmousemove = function(e) {
newY = e.clientY;
nowY = nowDisY + newY - oldY; // 拖动后的滚动条C的top值
maxY = bsHeight - scHeight; // 设置滚动条top极限值
if (nowY <= 0) {
nowY = 0;
};
if (nowY >= maxY) {
nowY = maxY;
};
bx.scrollTop = nowY/maxY * (cnHeight - bxHeight); // 设置滚动块B的scrollTop值
sc.style.top = nowY + "px";
}
}
document.onmouseup = function() {
document.onmousemove = null;
}
$('#cn').hover(function(e){ // 移入可视区A
$('#cn').on('mousewheel DOMMouseScroll', function(e) {
e = e.originalEvent || window.event.originalEvent; //绑定事件对象
scrollFunc(e); //判断滚动方向
var c = $('#cn').height() - $('#bx').height();
if (Judge) {
scrY--;
}else{
scrY++;
}
if (scrY <= 0) {
scrY = 0;
}
if (scrY >= c) {
scrY = c;
};
bx.scrollTop = scrY*10;
sc.style.top =bx.scrollTop*bxHeight/cnHeight + "px";
})
}, function(){ //鼠标移出可视区A
//移除滚动事件
$('#cn').off('mousewheel DOMMouseScroll');
})
//判断滚动方向
function scrollFunc(e){
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
Judge = true;
}
if (e.wheelDelta < 0) {
//当滑轮向下滚动时
Judge = false;
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
Judge = false;
}
if (e.detail< 0) { //当滑轮向下滚动时
Judge = true;
}
}
}
</script>
</body>
</html>
实现效果:
小结
到此为止,自定义滚动条的实现已基本完成,其中主要掌握滚动位置的偏移方式及相似比计算便可迎刃而解,同时滚轮事件的兼容问题也是不可忽视的,虽然麻烦了一丢丢,但是只要理清思路,解决起来还是简单的。
本文系HTML5学堂独家内容,转载请在文章开头显眼处注明作者和出处“HTML5学堂(http://www.h5course.com/)”
- spring boot 实现mysql读写分离
- spring boot集成druid连接池
- spring boot整合dubbox进行服务拆分
- Spring Cloud中如何保证各个微服务之间调用的安全性
- Spring Boot Actuator监控页面报错解决
- Spring Cloud中如何优雅的使用Feign调用接口
- Spring Cloud Eureka 集群高可用
- Spring Cloud Eureka 增加权限认证
- Spring Cloud Eureka 初探
- 房价网是怎么使用分布式作业框架elastic-job
- Spring Cloud Sleuth Zipkin 展示追踪数据
- Spring cloud Zuul Filter 使用小经验
- Spring Cloud Eureka REST 接口
- Spring Cloud Eureka 控制台快速查看Swagger API文档
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Git 技术篇-GitHub绑定本地Git,实例演示。实现代码云寄存
- Android 天气APP(十三)仿微信弹窗(右上角加号点击弹窗效果)、自定义背景图片、UI优化调整
- Python 微信机器人:识别消息来源于群聊还是个人
- Android 对接极光推送
- Pytho 技术篇-whl库安装失败经验总结
- VBS 脚本语言-利用vbs调用ie浏览器访问百度查天气实例演示
- vbs控制电脑说话,vbs获取时间,vbs小程序
- Android 天气APP(十四)修复UI显示异常、优化业务代码逻辑、增加详情天气显示
- Android 天气APP(十五)增加城市搜索、历史搜索记录
- python 微信机器人-如何调用机器人的api,调用图灵机器人接口演示。调用机器人原理,图灵机器人注册。
- Python 技术篇-如何查看python库包含什么方法,python库有哪些用法,python库的属性。
- Android Studio 安装配置教程 - MacOS(详细版)
- Android 天气APP(十六)热门城市 - 海外城市
- Android 天气APP(十七)热门城市 - 国内城市
- Python 技术篇-PIL库安装及截图功能演示