网页开发中经常需要使用鼠标滚轮事件。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. 制作拖拽效果。