您的位置:首页 > Web前端 > JavaScript

JavaScript事件基础(事件对象,键盘,鼠标,冒泡)

2017-05-08 17:05 691 查看

事件对象

什么是event对象和事件冒泡

获取事件的详细信息:鼠标位置,键盘按键

例子:获取鼠标位置:clientX

document的本质:document.childNodes[0].tagName

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
window.onload = function() {
document.body.onclick = function() {
alert('a');
};
};
</script>
</body>
</html>


点击网页,是没有反应的,因为body里面什么也没有啊,没有被撑开,但是如果把document.body.onclick 换成document.onclick,就可以了,因为document代表的是整个网页啊。

关于document

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function() {
alert(document.childNodes[0].tagName);
};
</script>
</head>
<body>
</body>
</html>


alert(document.childNodes[0].tagName);// !
alert(document.childNodes[1].tagName);// HTML


DOCUTYPE其实也是一个节点,而且,DOCUTYPE和HTML两个节点有个共同的父级,就是document,理解为整个网页!


所以,以后给整个页面加事件的时候,一定要给document加,而不是body

事件对象

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function() {
document.onclick = function() {
alert(event.clientX + ',' + event.clientY);
};
};
</script>
</head>
<body>
</body>
</html>


在FireFox中,不认识event,在浏览器中,事件函数都带有一个参数的,就是 事件对象,系统传来的。

最终的兼容方案:

var oEvent = ev||event;

window.onload = function() {
document.onclick = function(ev) {
var oEvent = ev || event;
alert(oEvent.clientX + ',' + oEvent.clientY);
};
};


事件流

事件冒泡

<!DOCTYPE html>
<html onclick="alert('html');">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
padding: 100px;
}
</style>
<script type="text/javascript">
window.onload = function() {
document.onclick = function() {

};
};
</script>
</head>
<body onclick="alert('body');">
<div style="background: yellow;" onclick="alert(this.style.background);">
<div style="background: green;" onclick="alert(this.style.background);">
<div style="background: red;" onclick="alert(this.style.background);"></div>
</div>
</div>
</body>
</html>


在红色块中点击一下,依次弹出:red -> green -> yellow -> body -> html

事件冒泡顺序:red div -> green div -> yellow div -> body -> html -> document

冒泡,有时候有些用途,但大多数会带来一些麻烦

比如:

页面上一个小按钮,点击一下,下面的灰色临时div出来,点击网页其他部分,灰色临时div消失。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 400px;
height: 300px;
background: #CCC;
display: none;
}
</style>
<script type="text/javascript">
window.onload = function() {
var oBtn = document.getElementById('btn1');
var oDiv = document.getElementById('div1');
oBtn.onclick = function() {
oDiv.style.display = 'block';
alert('按钮被点击');
};
document.onclick = function() {
oDiv.style.display = 'none';
alert('document被点击');
};
};
</script>
</head>
<body>
<input id="btn1" type="button" value="show" />
<div id="div1"></div>
</body>
</html>


这样,你会发现,点击按钮,灰色临时div根本不会出来!

原因很简单,当你点击按钮的时候,那一瞬间,灰色临时div的确出现了,但冒泡了,事件不仅点到btn上,但也冒泡到document上了,所以也就是给document也传了一个事件,那么立刻就又display:none了。

取消冒泡

oEvent.cancelBubble = true;


鼠标事件

clientX , clientY

onmusemove

灰色小div跟着鼠标到处跑

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 40px;
height: 40px;
background: #CCC;
position: absolute;
}
</style>
<script type="text/javascript">
document.onmousemove = function(ev) {
//灰色小div跟着鼠标到处跑
var oEvent = ev || event;
var oDiv = document.getElementById('div1');
oDiv.style.left = oEvent.clientX + 'px';
oDiv.style.top = oEvent.clientY + 'px';
};
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>


其实,这个程序有很大的漏洞,那就是不理解clientX和clientY,如果body给个高度,比如2000px,那么,灰色小块就会和鼠标脱离。clientX是鼠标位置在可视区到左边的距离,如果网页很大,根本不止一屏幕,那么可视区只是整个网页的一部分,这时候,可视区如果不是网页的最顶端部分,而是网页卷去了一部分,也就是scrollTop>0了,“==oDiv.style.top = oEvent.clientY + ‘px’;==”这句话就出问题了,top值这时候大于clientY了。也即是说,clientX 和 clientY是根据可视区定位的,但是,div可是根据body定位的(left,top)。

法则:

但凡是用到clientX,clientY的时候,一定用到scrollLeft,scrollTop,不然几乎是一定会出问题的.


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 40px;
height: 40px;
background: #CCC;
position: absolute;
}
</style>
<script type="text/javascript">
document.onmousemove = function(ev) {
var oEvent = ev || event;
var oDiv = document.getElementById('div1');

var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

oDiv.style.left = oEvent.clientX + 'px';
oDiv.style.top = oEvent.clientY + 'px';
};
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>


封装scrollTop和scrollLeft

因为经常用到,写起来麻烦,封装成库

function getPos(ev) {
var st = document.documentElement.scrollTop || document.body.scrollTop;
var sl = document.documentElement.scrollLeft || document.body.scrollLeft;
return {x:ev.clientX+sl, y:ev.clientY+st};
}


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 40px;
height: 40px;
background: #CCC;
position: absolute;
}
</style>
<script type="text/javascript">

function getPos(ev) { var st = document.documentElement.scrollTop || document.body.scrollTop; var sl = document.documentElement.scrollLeft || document.body.scrollLeft; return {x:ev.clientX+sl, y:ev.clientY+st}; }

document.onmousemove = function(ev) {
var oEvent = ev || event;
var oDiv = document.getElementById('div1');
var pos = getPos(oEvent);

oDiv.style.left = pos.x + 'px';
oDiv.style.top = pos.y + 'px';
};
</script>
</head>
<body style="height: 30000px">
<div id="div1"></div>
</body>
</html>


下面的功能是很多个div,跟在鼠标后面一大串

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 50px;
height: 50px;
background: red;
position: absolute;
left: 300px;
top: 200px;
}
img {
width: 100%;
height: 100%;
}
</style>
<script type="text/javascript">
function getPos(ev) { var st = document.documentElement.scrollTop || document.body.scrollTop; var sl = document.documentElement.scrollLeft || document.body.scrollLeft; return {x:ev.clientX+sl, y:ev.clientY+st}; }
var k = 0;
document.onmousemove = function(ev) {
k++;
var oEvent = ev || event;
var pos = getPos(oEvent);
var aDiv = document.getElementsByTagName('div');
var len = aDiv.length;

aDiv[0].style.left = pos.x + 'px';
aDiv[0].style.top = pos.y + 'px';

for (var i = len - 1; i > 0; i--) {
aDiv[i].style.left = aDiv[i - 1].offsetLeft + 'px';
aDiv[i].style.top = aDiv[i - 1].offsetTop + 'px';
}
};
</script>
</head>
<body>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>
<div><img src="http://pic.58pic.com/58pic/13/59/88/32W58PICQpk_1024.jpg"></div>

</body>
</html>


键盘事件,keyCode

onkeydown
onkeyup


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zns</title>
</head>
<body>
<script type="text/javascript">
document.onkeydown = function(ev) {
var oEvent = ev || event;
alert(oEvent.keyCode);
};
</script>
</body>
</html>


a:65  b:66 ......


要求:键盘控制div的移动

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zns</title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="div1"></div>
<script type="text/javascript">
var oDiv = document.getElementById('div1');
document.onkeydown = function(ev) {
var oEvent = ev || event;
var code = oEvent.keyCode;
switch(code) {
case 37:
oDiv.style.left = oDiv.offsetLeft - 5 + 'px';
break;
case 38:
oDiv.style.top = oDiv.offsetTop - 5 + 'px';
break;
case 39:
oDiv.style.left = oDiv.offsetLeft + 5 + 'px';
break;
case 40:
oDiv.style.top = oDiv.offsetTop + 5 + 'px';
break;
}
};
</script>
</body>
</html>


上面代码,满足了左键右键移动div的要求,但是,基于系统本身的特点(原因:系统要区分用户是否连续输入,第一个到第二个之间有一个停顿时间。比如,当你长按a的时候,屏幕上先是出现一个a,顿一下然后才出现第二个第三个一串a,这是系统为了考虑行动缓慢的老人,故意延迟一下时间,因为老人按的比较慢,避免出现一串a)但也同时造成了我们的困扰,你按一下左键,也是顿一下,这是不行的,如何解决??解决方案:先开一个定时器,让div一直处于(往4个方向)准备移动的状态(初始4个方向的值都是false,div就保持在原地不动),当按下某个方向键,这个方向的值就改变为true,div就会开始往这个方向移动,松开方向键,这个方向的值就改变为false , div就停止这个方向移动了

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zns</title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div id="div1"></div>
<script type="text/javascript">
var oDiv = document.getElementById('div1');

var key_left = false;
var key_right = false;
var key_bottom = false;
var key_top = false;
var timer = null;

setInterval(function() {
if(key_left) {
oDiv.style.left = oDiv.offsetLeft - 5 + 'px';
} else if(key_right) {
oDiv.style.left = oDiv.offsetLeft + 5 + 'px';
} else if(key_top) {
oDiv.style.top = oDiv.offsetTop - 5 + 'px';
} else if(key_bottom) {
oDiv.style.top = oDiv.offsetTop + 5 + 'px';
}
}, 50);

document.onkeydown = function(ev) {
var oEvent = ev || event;
var code = oEvent.keyCode;
switch(code) {
case 37:
key_left = true;
break;
case 38:
key_top = true;
break;
case 39:
key_right = true;
break;
case 40:
key_bottom = true;
break;
}
};

document.onkeyup = function(ev) {
var oEvent = ev || event;
var code = oEvent.keyCode;

switch(code) {
case 37:
key_left = false;
break;
case 38:
key_top = false;
break;
case 39:
key_right = false;
break;
case 40:
key_bottom = false;
break;
}
};
</script>
</body>
</html>


#### 需求:回车键按下,input框内的内容追加到textarea中

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zns</title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<input id="txt1" type="text" /><br>
<textarea id="txt2" rows="10" cols="40" style="margin-top: 10px;"></textarea>
<script type="text/javascript">
var oTxt1 = document.getElementById('txt1');
var oTxt2 = document.getElementById('txt2');
// oTxt1内写完时候,焦点在oTxt1内,这时候回车,keydown应该加在oTxt1上
oTxt1.onkeydown = function(ev) {
var oEvent = ev || event;
if(oEvent.keyCode == 13) {
oTxt2.value += oTxt1.value + '\n';
oTxt1.value = '';
}
};

</script>
</body>
</html>


需求:回车和Ctrol键同时按下才提交

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zns</title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<input id="txt1" type="text" /><br>
<textarea id="txt2" rows="10" cols="40" style="margin-top: 10px;"></textarea>
<script type="text/javascript">
var oTxt1 = document.getElementById('txt1');
var oTxt2 = document.getElementById('txt2');
// oTxt1内写完时候,焦点在oTxt1内,这时候回车,keydown应该加在oTxt1上
oTxt1.onkeydown = function(ev) {
var oEvent = ev || event;
if(oEvent.keyCode == 13 && oEvent.ctrlKey) {
oTxt2.value += oTxt1.value + '\n';
oTxt1.value = '';
}
};

</script>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript