事件的组成
- 事件源:谁触发的事件
- 事件类型:触发了什么事件
- 事件处理程序:事件触发以后做什么
事件对象
当事件被触发后,用来描述事件信息的对象,例如鼠标点击事件
<body>
<div class="box"
style="
width: 100px;
height: 100px;
background-color: chartreuse;
margin: 200px auto;
text-align: center;
border-radius: 50%;
"
>hello</div>
<script>
// 获取元素
let box=document.querySelector('.box')
// 绑定点击事件,DOM2级
box.addEventListener('click',clickHandler)
function clickHandler(event){
console.log(event);
}
</script>
执行结果如下:
可以看到,事件对象有很多属性,今天,我们只介绍与坐标相关的属性.
事件对象的各种坐标
| 属性名 | 解释 |
|---|---|
| clentX | 事件触发时鼠标光标距离浏览器窗口左边的距离 |
| clentY | 事件触发时鼠标光标距离浏览器窗口上边的距离 |
| offsetX | 事件触发时鼠标光标距离事件源左边的距离 |
| offsetY | 事件触发时鼠标光标距离事件源上边的距离 |
| pageX | 事件触发时鼠标光标距离文档窗口左边的距离 |
| pageY | 事件触发时鼠标光标距离文档窗口上边的距离 |
| screenX | 事件触发时鼠标光标距离屏幕左边的距离 |
| screenY | 事件触发时鼠标光标距离屏幕上边的距离 |
可以看出,以X结尾的,是距离某某坐标原点左边的的距离,以Y结尾的,是距离某某坐标原点上边的距离.当鼠标点击上图小绿块时,点击事件被触发,可以试着运行以下代码打印各个坐标值
<body>
<div class="box"
style="
width: 100px;
height: 100px;
background-color: chartreuse;
margin: 200px auto;
text-align: center;
line-height: 100px;
border-radius: 50%;
"
>hello</div>
<script>
// 获取元素
let box=document.querySelector('.box')
// 绑定点击事件
box.addEventListener('click',clickHandler)
function clickHandler(event){
//console.log(event);
let ox=event.offsetX
let oy=event.offsetY
console.log('ox:',ox,'oy:',oy);
let px=event.pageX
let py=event.pageY
console.log('px:',px,'py:',py);
let sx=event.screenX
let sy=event.screenY
console.log('sx:',sx,'sy:',sy);
let cx=event.clientX
let cy=event.clientY
console.log('cx:',cx,'cy:',cy);
}
</script>
</body>
- 可以看到,当浏览器窗口缩放时,screen与client大小不再相等,offsetX的取值范围为(0,事件源的宽),offsetY的取值范围(0,事件源的高)
- 当浏览器窗口没有滚动条时,浏览器窗口与文档窗口重合,pageX与clientX相等,pageX与clientY相等;如果出现下拉滚动条并向下拉动滚动条,文档窗口向上滚动,如果出现左右滑动的滚动条并向右拉动滚动条,文档窗口向左滚动,在文档窗口滚动的情况下,pageX>=clientX, pageY>=clientY
随堂测试
鼠标拖拽练习:鼠标按下,色块跟随鼠标移动,鼠标松开,色块不再跟随鼠标移动;附加练习:实现拖拽轨迹的回放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
p {
margin: 0;
padding: 0;
width: 200px;
height: 100px;
background-color: blueviolet;
position: absolute;
top: 200px;
left: 500px;
}
</style>
</head>
<body>
<p><a href="#none">点击回放拖动轨迹</a></p>
<script>
// 1.获取元素
var p = document.querySelector('p');
var a = document.querySelector('p a');
// console.log(a);
// 获取元素的宽、高
var width = p.offsetWidth;
var height = p.offsetHeight;
// console.log(width,height);
// 获取可视区宽、高
var vw = window.innerWidth;
var vh = window.innerHeight;
// 元素不能超过文档可视区域,给元素设置定位范围
var maxTop = vh - height;
var maxLeft = vw - width;
// 2.给按下鼠标事件设置监听器
p.addEventListener('mousedown', mousedownHandler);
var ox;
var oy;
var tempPosition=[];//存放元素实时定位数据
function mousedownHandler(eve) {
// 2.1获取鼠标点击位置相对于元素坐标原点的坐标
ox = eve.offsetX;
oy = eve.offsetY;
// console.log(ox,oy);
// 3.元素跟着鼠标移动而移动,移动范围为整个文档区域
document.addEventListener('mousemove', mousemoveHandler);
}
p.onclick=function(event){
console.log(event);
}
function mousemoveHandler(e) {
// 3.1获取鼠标点击位置相对于文档坐标原点的坐标
console.log(e);
var px = e.pageX;
var py = e.pageY;
// console.log(dx,dy);
// 3.2元素跟着鼠标移动而移动,给元素定位
var t = py - oy;//top
var l = px - ox;//left
// 设置定位边界
if (t < 0) t = 0;
if (l < 0) l = 0;
if (t > maxTop) t = maxTop;
if (l > maxLeft) l = maxLeft;
// 定位
p.style.top = t + 'px';
p.style.left = l + 'px';
//记录元素移动轨迹
tempTop = p.offsetTop;
tempLeft = p.offsetLeft;
console.log(tempLeft,tempTop);
tempPosition.push({left:tempLeft,top:tempTop});
console.log(tempPosition);
a.addEventListener('click',trackPlayback);
}
function trackPlayback(){
// console.log(tempPosition);
// 通过记录的移动轨迹数据,进行回放
// 获取回放的第一个位置数据的索引
var index=tempPosition.length-1;
var playback=setInterval(function(){
if(index<=0){
clearInterval(playback);
return;
}
p.style.left=tempPosition[index--].left+'px';
p.style.top=tempPosition[index--].top+'px';
},30);
}
// 4.鼠标抬起时,元素不再跟着鼠标移动而移动
document.onmouseup = function () {
// 移除鼠标移动事件监听器
document.removeEventListener('mousemove', mousemoveHandler);
}
</script>
</body>
</html>