一,鼠标手动触发事件
这类事件是我们最常用,也是动作交互的核心。
1.单击事件与双击事件
click事件的绑定:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.onclick=function(){
console.log(1);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.onclick=function(){
console.log(1);
};
</script>
</html>
监听后,我们的触发条件就是点击这个元素,每次点击都触发一次回调处理。我们按下后长按发现是不会输出内容的,只有在鼠标抬起后执行绑定函数,说明click事件的触发点在鼠标抬起后。
除了单击,我们在操作系统中还有双击事件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.ondblclick=function(){
console.log(1);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.ondblclick=function(){
console.log(1);
};
</script>
</html>
必须在较短时间点击2次才会触发。
2.鼠标组合事件
click事件我们设想一下其实一般包含三步操作,鼠标按下,移动(可有可无),抬起。
我们分别监听三个事件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.onmousedown=function(){
console.log(1);
};
ele1.onmousemove=function(){
console.log(2);
};
ele1.onmouseup=function(){
console.log(3);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1"></div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
ele1.onmousedown=function(){
console.log(1);
};
ele1.onmousemove=function(){
console.log(2);
};
ele1.onmouseup=function(){
console.log(3);
};
</script>
</html>
move事件只要移动就会触发,但是按下事件的下一次触发必须在抬起事件之后,也就是一次click完成之后。
我们按下后不动,保持长按其实只会触发一次按下事件。
3.单击事件的冒泡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1">
<div style="height:100px; width:100px; background:#000;" id="ele2">
</div>
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onclick=function(){
alert(2);
};
ele1.onclick=function(){
alert(1);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1">
<div style="height:100px; width:100px; background:#000;" id="ele2">
</div>
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onclick=function(){
alert(2);
};
ele1.onclick=function(){
alert(1);
};
</script>
</html>
先执行内部在执行外部,如果我们内部是让某个div显示,外部是让那个div隐藏,这样就发生了冲突,不能实现点击内部div去隐藏,我们可以利用事件对象去阻止冒泡:
ele2.onclick=function(event){
alert(2);
event.stopPropagation();
};
ele2.onclick=function(event){
alert(2);
event.stopPropagation();
};
点击内部div,事件执行后阻止往上查找父辈元素的绑定处理。
4.事件委托
委托的原理就是来自冒泡,还是上面的例子,我们在外部div里有3个div,其实点击三个内部div哪一个都会点击到外部div,所以我们就可以把每个内部div的事件绑定统一绑定到外部div上,然后利用标志区分去触发相应函数。
我们先看最普通的处理方式,分别绑定:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1">
<div style="height:30px; width:100px; background:#000;" id="ele2">
</div>
<div style="height:30px; width:100px; background:#399;" id="ele3">
</div>
<div style="height:30px; width:100px; background:#03F;" id="ele4">
</div>
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
var ele3=document.getElementById("ele3");
var ele4=document.getElementById("ele4");
ele2.onclick=function(event){
alert(2);
};
ele3.onclick=function(){
alert(3);
};
ele4.onclick=function(){
alert(4);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:100px; background:#0C3;" id="ele1">
<div style="height:30px; width:100px; background:#000;" id="ele2">
</div>
<div style="height:30px; width:100px; background:#399;" id="ele3">
</div>
<div style="height:30px; width:100px; background:#03F;" id="ele4">
</div>
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
var ele3=document.getElementById("ele3");
var ele4=document.getElementById("ele4");
ele2.onclick=function(event){
alert(2);
};
ele3.onclick=function(){
alert(3);
};
ele4.onclick=function(){
alert(4);
};
</script>
</html>
我们在使用委托的处理机制:
ele1.onclick=function(event){
var tar=event.target;
if(tar.id=="ele2"){
alert(2);
}else if(tar.id=="ele3"){
alert(3);
}else if(tar.id=="ele4"){
alert(4);
}else{
alert(1);
};
};
ele1.onclick=function(event){
var tar=event.target;
if(tar.id=="ele2"){
alert(2);
}else if(tar.id=="ele3"){
alert(3);
}else if(tar.id=="ele4"){
alert(4);
}else{
alert(1);
};
};
利用event.target获取最小触发元素,根据id的区别做了判断处理,是不是省去很多绑定事件的代码。
5.获取焦点和失去焦点
同click事件类似:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onfocus=function(event){
console.log(1);
};
ele2.onblur=function(event){
console.log(2);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onfocus=function(event){
console.log(1);
};
ele2.onblur=function(event){
console.log(2);
};
</script>
</html>
6.不是所有事件都可以冒泡
上面我们测试了获取焦点事件,我们看看可以冒泡吗?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onfocus=function(event){
console.log(1);
};
ele1.onfocus=function(event){
console.log(2);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onfocus=function(event){
console.log(1);
};
ele1.onfocus=function(event){
console.log(2);
};
</script>
</html>
是不是不会输出父元素的内容,因为父元素是不具备焦点事件的,
7.鼠标组合事件模拟拖拽实现
页面一个div可以拖拽移动,先说原理,我们会先按下(拖拽div),然后移动(拖拽div跟随),最后抬起(拖拽div静止)。
整个流程每次要发生在一套click的内部:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div id="drag" style="width:200px; height:200px; top:200px; left:400px; background:#990; position:absolute; padding:100px;">
登录<input type="text" /><br/>
密码<input type="text" /><br/>
<input type="button" value="ok" />
</div>
</body>
<script type="text/javascript">
window.onload=function(){
var drag=document.getElementById("drag");
var isd=0;
var elex=0;
var eley=0;
drag.onmousedown=function(event){
isd=1;
elex=event.clientX-drag.offsetLeft;
eley=event.clientY-drag.offsetTop;
};
drag.onmousemove=function(event){
if(isd==1){
var evx=event.clientX;
var evy=event.clientY;
var cx=evx-elex;
var cy=evy-eley;
drag.style.left=cx+"px";
drag.style.top=cy+"px";
}else{}
};
drag.onmouseup=function(event){
isd=0;
};
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div id="drag" style="width:200px; height:200px; top:200px; left:400px; background:#990; position:absolute; padding:100px;">
登录<input type="text" /><br/>
密码<input type="text" /><br/>
<input type="button" value="ok" />
</div>
</body>
<script type="text/javascript">
window.onload=function(){
var drag=document.getElementById("drag");
var isd=0;
var elex=0;
var eley=0;
drag.onmousedown=function(event){
isd=1;
elex=event.clientX-drag.offsetLeft;
eley=event.clientY-drag.offsetTop;
};
drag.onmousemove=function(event){
if(isd==1){
var evx=event.clientX;
var evy=event.clientY;
var cx=evx-elex;
var cy=evy-eley;
drag.style.left=cx+"px";
drag.style.top=cy+"px";
}else{}
};
drag.onmouseup=function(event){
isd=0;
};
};
</script>
</html>
慢慢的拖动好像没问题,但是我们快速移动鼠标,鼠标脱离拖拽体,就出现问题了,在移入就粘连了,我们的问题就是把move和up事件也绑定在了拖拽体上,我们修改对象,绑定到html对象上:
window.onload=function(){
var drag=document.getElementById("drag");
var isd=0;
var elex=0;
var eley=0;
drag.onmousedown=function(event){
isd=1;
elex=event.clientX-drag.offsetLeft;
eley=event.clientY-drag.offsetTop;
};
document.documentElement.onmousemove=function(event){
if(isd==1){
var evx=event.clientX;
var evy=event.clientY;
var cx=evx-elex;
var cy=evy-eley;
drag.style.left=cx+"px";
drag.style.top=cy+"px";
}else{}
};
document.documentElement.onmouseup=function(event){
isd=0;
};
};
window.onload=function(){
var drag=document.getElementById("drag");
var isd=0;
var elex=0;
var eley=0;
drag.onmousedown=function(event){
isd=1;
elex=event.clientX-drag.offsetLeft;
eley=event.clientY-drag.offsetTop;
};
document.documentElement.onmousemove=function(event){
if(isd==1){
var evx=event.clientX;
var evy=event.clientY;
var cx=evx-elex;
var cy=evy-eley;
drag.style.left=cx+"px";
drag.style.top=cy+"px";
}else{}
};
document.documentElement.onmouseup=function(event){
isd=0;
};
};
用金星老师话说配合姿势,这就是完美!在组合处理中选择正确的绑定元素至关重要。
二,键盘触发事件
主要输入设备除了鼠标还有就是键盘。
键盘有啥?按下,长按,抬起,我们分别绑定:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1" contenteditable="true">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onkeydown=function(event){
console.log(1);
};
ele2.onkeypress=function(event){
console.log(2);
};
ele2.onkeyup=function(event){
console.log(3);
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
</head>
<body>
<div style="height:100px; width:200px; background:#0C3;" id="ele1" contenteditable="true">
<input type="text" id="ele2" >
</div>
</body>
<script type="text/javascript">
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onkeydown=function(event){
console.log(1);
};
ele2.onkeypress=function(event){
console.log(2);
};
ele2.onkeyup=function(event){
console.log(3);
};
</script>
</html>
按下事件的每次触发也是在本次抬起结束后。
三,异步事件
这个名字是我自己起的,原因就是这些事件的触发要经过一段时间,去判断某个状态是否达到。
1.load载入完成事件
我们在看别人的js是这样的:
window.onload=function(){
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onkeydown=function(event){
console.log(1);
};
ele2.onkeypress=function(event){
console.log(2);
};
ele2.onkeyup=function(event){
console.log(3);
};
};
window.onload=function(){
var ele1=document.getElementById("ele1");
var ele2=document.getElementById("ele2");
ele2.onkeydown=function(event){
console.log(1);
};
ele2.onkeypress=function(event){
console.log(2);
};
ele2.onkeyup=function(event){
console.log(3);
};
};
加入load事件,那么里面的程序就会在页面html加载完执行,避免无结构先发生处理。
load的重要在图片处理上是非常的重要,现在css3盛行,我们会加入很多动画处理,动画处理会用到很多图片,假如用到了4张,如果图片没加载完,我们动画执行了,客户怎么看?这时候我们就要对5张图都进行load完成判断,确定4张ok才去引入动画css是不是。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.box{width: 900px;margin: 0 auto;}
.box img{ width: 200px;height: 200px;margin: 10px;border: 1px solid #000;}
</style>
</head>
<body>
<div class="box">
<img src="http://fe.topit.me/e/53/65/11639567172a86553eo.jpg" class="readyimg ready1">
<img src="http://www.pp3.cn/uploads/allimg/111116/1102135I3-12.jpg" class="readyimg ready2">
<img src="http://i5.topit.me/5/d1/9b/1132725126ff69bd15o.jpg" class="readyimg ready3">
<img src="http://f9.topit.me/9/31/41/113272518184741319o.jpg" class="readyimg ready4">
</div>
</body>
<script type="text/javascript">
var imgo=document.querySelectorAll(".readyimg");
var imglen=imgo.length;
var isimg=[];
for(var i=0;i<imglen;i++){
isimg[i]=0;
};
for(var i=0;i<imglen;i++){
(function(i){
imgo[i].onload=function(){
isimg[i]=1;
ifready();
};
})(i);
};
function ifready(){
if(isready()==1){
alert('图片全部加载完!当前放入处理代码')
}else{
};
};
function isready(){
var res=1;
for(var i=0;i<imglen;i++){
if(isimg[i]==0){
res=0;
}else{};
};
return res;
};
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js</title>
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
ul{ list-style:none;}
/*demo*/
.box{width: 900px;margin: 0 auto;}
.box img{ width: 200px;height: 200px;margin: 10px;border: 1px solid #000;}
</style>
</head>
<body>
<div class="box">
<img src="http://fe.topit.me/e/53/65/11639567172a86553eo.jpg" class="readyimg ready1">
<img src="http://www.pp3.cn/uploads/allimg/111116/1102135I3-12.jpg" class="readyimg ready2">
<img src="http://i5.topit.me/5/d1/9b/1132725126ff69bd15o.jpg" class="readyimg ready3">
<img src="http://f9.topit.me/9/31/41/113272518184741319o.jpg" class="readyimg ready4">
</div>
</body>
<script type="text/javascript">
var imgo=document.querySelectorAll(".readyimg");
var imglen=imgo.length;
var isimg=[];
for(var i=0;i<imglen;i++){
isimg[i]=0;
};
for(var i=0;i<imglen;i++){
(function(i){
imgo[i].onload=function(){
isimg[i]=1;
ifready();
};
})(i);
};
function ifready(){
if(isready()==1){
alert('图片全部加载完!当前放入处理代码')
}else{
};
};
function isready(){
var res=1;
for(var i=0;i<imglen;i++){
if(isimg[i]==0){
res=0;
}else{};
};
return res;
};
</script>
</html>
只有在4张图被载入完才会执行处理,我们每次测试ctrl+f5可以测试。
2.ajax事件
xmlhttp.onreadystatechange
四,其他事件
上面都是最常用事件,js为我们的交互提供的事件是非常多的,移动端的touch事件,音视频的播放事件,卸载事件,关闭窗口事件等等等。