网页开发中经常需要使用鼠标滚轮事件。Chrome 和 IE 各版本浏览器都支持 onmousewheel 事件,表示鼠
标滚轮滚动事件。但是火狐浏览器不支持这个事件,它支持的是自己的 DOMMouseScroll 事件。给一个盒子添
加鼠标滚动事件代码如下:
//除了火狐之外这样添加监听:
box.onmousewheel = mousewheelhandler;
//火狐特有,必须用 DOM2 级的方法添加监听
box.addEventListener("DOMMouseScroll",mousewheelhandler,true);
function mousewheelhandler(){
box.innerHTML = "你滚动了滚轮";
}
鼠标滚轮事件的 event 对象有一个属性 wheelDelta,火狐浏览器提供的是 event.detail 属性。这个数值
可以反映鼠标滚动的方向和速度。一般浏览器是靠 120 或-120 表示向上或向下滚动鼠标滚轮;火狐浏览器是靠
-3 和 3 表示向上或向下滚动鼠标滚轮。即不仅数值不同,而且正负性也有区别。
为了兼容所有浏览器,我们书写了下面的事件监听函数,它产生的方向被统一到 1 和-1,鼠标滚轮向上滚
动产生 1,向下滚动产生-1。
function mousewheelhandler(event){
//进行方向的检测,由于火狐和大家不一样,我们用 if 语句分开判断
if(event.wheelDelta){
var direction = event.wheelDelta > 0 ? 1 : -1;
}else{
var direction = event.detail > 0 ? -1 : 1;
}
box.innerHTML = direction;
}
滚动条的实现原理
在网页开发时,一些展示信息的盒子经常由于内容过长而需要使用滚动条。为了页面美观,往往人们不使用
CSS 提供的滚动条功能,而是用拖拽技术模拟滚动条。
滚动条的实现原理不难,使用拖拽的原理使用滑块能够被鼠标拖拽。当滑块移动一定的位置的时候,让文字
盒子向相反的方向按比例移动。比例如何计算?
首先我们应该设置滑块高度,很明显滑块高度和盒子高度的比,应该等于盒子高度和内容原本高度的比。而
当滑块移动 1px 的时候,内容盒子也要按照这个比例进行反方向移动。
案例代码
案例完整代码如下(我们省略了 CSS 代码,请同学们看随书案例):
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div class="news" id="news">
<div class="bar">
<b id="barb"></b>
</div>
<div class="content" id="contentBox">
内容
</div>
</div>
<script type="text/javascript">
var barb = document.getElementById("barb");
var contentBox = document.getElementById("contentBox");
var news = document.getElementById("news");
//要得到 news 的净位置
var newsJingTop = getAllY(news);
//得到内容盒子的计算后的高度
var contentBoxHeight = parseInt(contentBox.clientHeight);
//计算比例,盒子高度除以内容
var rate = 240 / contentBoxHeight;
//如果内容比盒子小的话,此时比例大于 1
if(rate > 1){
barb.style.display = "none";
}
//设置滑块 barb 的高度,此时滑块的高度要按比例设置
var barbheight = 240 * rate;
barb.style.height = barbheight + "px";
//公共信号量,不管是滑块还是滚轮,都在操作他们两个数值
var contentBoxTop = 0;
var barbTop = 0;
//滑块的拖拽
//在滑块中按下的时候
barb.onmousedown = function(event){
//误差
var dy = event.offsetY;
//注册移动事件
document.onmousemove = function(event){
//barb 此时的坐标
var y = event.pageY - newsJingTop - dy;
//验收
if(y < 0){
y = 0;
}else if(y > 240 - barbheight){
y = 240 - barbheight;
}
//滑块的移动
//改变信号量
barbTop = y;
contentBoxTop = -y / rate;
barb.style.top = barbTop + "px";
//内容的移动
contentBox.style.top = contentBoxTop + "px";
return false;
}
return false;
}
document.onmouseup = function(){
document.onmousemove = null;
}
//滚轮的事件
news.onmousewheel = mousewheelhandler;
news.addEventListener("DOMMouseScroll", mousewheelhandler, true);
function mousewheelhandler(event){
event = event || window.event;
//阻止默认事件
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = true;
}
//统一 API,滚动向上 1,滚动向下-1
if(event.wheelDelta){
var direction = event.wheelDelta > 0 ? 1 : -1;
}else{
var direction = event.detail > 0 ? -1 : 1;
}
//改变信号量。滚轮下滚(-1),期望内容上移,所以内容减小过程。
contentBoxTop += direction * 20;
//验收
if(contentBoxTop > 0){
contentBoxTop = 0;
}else if(contentBoxTop < 240 - contentBoxHeight){
contentBoxTop = 240 - contentBoxHeight
}
//我们把 contentBoxTop 当做主信号量,而 barbTop 一定随时和 contentBoxTop 有比例关系!
barbTop = -contentBoxTop * rate;
//反应到盒子上
contentBox.style.top = contentBoxTop + "px";
barb.style.top = barbTop + "px";
}
//得到净位置函数
function getAllY(o){
var allY = o.offsetTop; //累加器
//一层一层迭代上去,记得补边框
while(o = o.offsetParent){
allY += o.offsetTop + parseInt(getComputedStyle(o)["border-top-width"]);
}
return allY;
}
</script>
</body>
</html>
本章作业
1. 什么是事件冒泡和事件捕获?
2. 什么是事件委托?什么时候需要使用事件委托?
3. 什么是事件对象?如何组织事件继续传播?
4. 鼠标的位置有哪些?在纸上画出示意图。
5. 制作购物商城放大镜效果。
6. 制作拖拽效果。