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-事件冒泡、鼠标跟随、键盘跟随、键盘提交
- javascript访问事件对象(鼠标、键盘)
- js事件应用--基础(事件对象、鼠标事件、键盘事件)
- Js学习---妙味课堂3-1 (事件对象和事件冒泡)--- 获取鼠标+键盘事件
- javascript事件列表大全解说,点击事件,双击事件,触发事件,键盘事件,鼠标移...
- javascript基础——鼠标事件,系统对话框等
- JavaScript和JQuery的鼠标mouse事件冒泡处理
- javascript之键盘与鼠标事件
- javascript 中响应鼠标和键盘事件
- 用 javascript 获取当页面上鼠标(光标)位置 和 触发事件的对象 的方法
- Java基础--Java---IO流------GUI(布局)、Frame、事件监听机制、窗体事件、Action事件、鼠标事件、对话框Dialog、键盘事件、菜单
- 妙味4:鼠标、键盘事件对象兼容,阻止事件对象的默认行为
- 用 javascript 获取当页面上鼠标(光标)位置 和 触发事件的对象 的方法
- javascript事件处理中Event对象(键盘事件和鼠标事件)实例
- javascript的鼠标键盘事件
- javascript事件列表大全解说,点击事件,双击事件,触发事件,键盘事件,鼠标移...
- 事件对象,阻止冒泡,键盘事件
- JavaScript相关-基础语法,常用对象和简单事件
- JavaScript实现禁用键盘和鼠标的点击事件