Dom事件的三种绑定方式
1.事件
2. onclick, onblur, onfocus,
需求:请写出一个行为,样式,结构,相分离的页面。
JS, CSS, HTML,
示例1,行为结构样式粘到一起的页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div style="background-color:red;width:300px;height:400px;" onclick="t1();">sdf</div> <script> function t1(){ console.log('sdfdfs'); } </script> </body> </html>
如下为dom 0 的操作,是初级程序员的写法:(CSS剥离出来了,不过HTML和JS还是粘在一起的)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <div id="i1" onclick="t1();">sdf</div> <script> function t1(){ console.log('sdfdfs'); } </script> </body> </html>
高级写法是把 onclick="t1() 写到JS里面。
这样行为,样式,结构相分离,可以提高程序效率。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <div id="i1">sdf</div> <script> var mydiv=document.getElementById("i1"); //是一个DOM对象,所以可以给它加属性方法。 console.log(mydiv); mydiv.onclick=function(){ console.log("sdf"); } </script> </body> </html>
3.一个新的需求,鼠标移上去的时候,就变色;鼠标移走的时候,就恢复原色。类似于高亮显示的感觉。
如下是DOM 0 的写法,初级程序员的写法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <table border="1" width="300px"> <tr onmouseover="t1(0);" onmouseout="t2(0);"><td>1</td><td>2</td><td>3</td></tr> <tr onmouseover="t1(1);" onmouseout="t2(1);"><td>1</td><td>2</td><td>3</td></tr> <tr onmouseover="t1(2);" onmouseout="t2(2);"><td>1</td><td>2</td><td>3</td></tr> </table> <script> function t1(n){ var myTrs=document.getElementsByTagName("tr")[n]; //获得所有的tr标签 //console.log(myTrs); myTrs.style.backgroundColor="red"; } function t2(n){ var myTrs=document.getElementsByTagName("tr")[n]; myTrs.style.backgroundColor=""; } </script> </body> </html>
效果:
4. 看到了DOM0的弊端,重复代码太多。现在尝试把JS剥离出来。DOM1 的写法
程序1:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <table border="1" width="300px"> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> </table> <script> var myTrs=document.getElementsByTagName("tr"); //虽然写到了script中,但他们都还是全局变量 var len=myTrs.length; for(var=0;i<len;i++){
// i=0, i=1, i=2;有可能i已经增加到2了,但是才刚开始移动鼠标,所以不能用如下写法。 myTrs[i].onmouseover=function(){ myTrs[i].style.backgroundColor="red"; } } </script> </body> </html>
报错,无法执行;
程序改进:this:谁调用这个函数,this就指向谁。
剥离出来以后,代码更好看。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <table border="1" width="300px"> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> </table> <script> var myTrs=document.getElementsByTagName("tr"); var len=myTrs.length; for(i=0;i<len;i++){ myTrs[i].onmouseover=function(){ this.style.backgroundColor="red"; //谁调用这个函数,this就指向谁。 } myTrs[i].onmouseout=function(){ this.style.backgroundColor=""; } } </script> </body> </html>
5. 绑定事件有两种方式:
1)-直接标签绑定 onclick='xxx()'
2)-先获取dom对象,然后进行绑定
document.getElementById('xx').onclick
document.getElementById('xx').onfocus
3)-this, 指当前触发事件的标签。
A-第一种绑定方式中,如何使用this,this作为形式参数
<input type='button' onclick='ClickOn(this)'>
function ClickOn(self){
//self 就代指当前点击的标签
}
B-第二种绑定方式,不用写onclick了。
<input id='i1' type='button'>
document.getElementById('i1').onclick=function(){
this // 这里的this代指当前点击的标签
}
C-第三种绑定方式
mydiv.addEventListener('click',function(){console.log('aaa')},false);
this的第一种绑定方式可用于左侧菜单程序中。
把this函数用于左侧菜单程序。点菜单1,就可以获取到菜单1. 把this作为参数传入。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .hide{ display:none; } .item .header{ height:35px; background-color:blue; color:white; line-height:35px; } </style> </head> <body> <div style="height;48px"></div> <div style="width:300px"> <div class="item"> <div class="header" onclick="ChangeMenu(this);">菜单1</div> <div class="content"> <div>内容1.1</div> <div>内容1.2</div> <div>内容1.3</div> </div> </div> <div class="item"> <div class="header" onclick="ChangeMenu(this);">菜单2</div> <div class="content hide"> <div>内容2.1</div> <div>内容2.2</div> <div>内容2.3</div> </div> </div> <div class="item"> <div class="header" onclick="ChangeMenu(this);">菜单3</div> <div class="content hide"> <div>内容3.1</div> <div>内容3.2</div> <div>内容3.3</div> </div> </div> <div class="item"> <div class="header" onclick="ChangeMenu(this);">菜单4</div> <div class="content hide"> <div>内容4.1</div> <div>内容4.2</div> <div>内容4.3</div> </div> </div> </div> <script> function ChangeMenu(ths){ //this 代表的是全局对象,无法直接获取,需要把上面改成this //var current_header=document.getElementById(nid); var current_header=ths; var item_list=current_header.parentElement.parentElement.children; for(var i=0;i<item_list.length;i++){ var current_item=item_list[i]; current_item.children[1].classList.add('hide'); } current_header.nextElementSibling.classList.remove('hide'); } </script> </body> </html>
如果是2个table的情况,该如何写程序呢。要注意程序默认会给table自动加上thead, tbody 标签,所以找children的时候要注意层级。
作用域的必考点,经典示例:
6. Dom绑定事件的第三种方式
需求:能不能给 mydiv再绑定一个 onclick 事件,然后同样 console.log 出另外一些东西来。
可是再写一次mydiv.onclick 的话,会把前面的覆盖掉。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#i1{
background-color:red;width:300px;height:400px;
}
</style>
</head>
<body>
<div id="i1">sdf</div>
<script>
var mydiv=document.getElementById("i1");
//console.log(mydiv);
mydiv.onclick=function(){
console.log("sdf");
}
mydiv.onclick=function(){
console.log("sdf12345");
}
</script>
</body>
</html>
用 mydiv.addEventListener 来实现,称为dom2. 有3个参数。第1个click事件,第2个参数就是function, 第3个参数默认是false.false指的是冒泡模型,true是捕捉模型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i1{ background-color:red;width:300px;height:400px; } </style> </head> <body> <div id="i1">sdf</div> <script> var mydiv=document.getElementById("i1"); mydiv.addEventListener('click',function(){console.log('aaa')},false); mydiv.addEventListener('click',function(){console.log('bbb')},false); </script> </body> </html>
效果:
第3个参数默认是false.false指的是冒泡模型,true是捕捉模型. 图示中红的是捕捉,绿的是冒泡。
false, true 的实例效果探索
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> #main{ background-color:red; width:300px; height:400px; } #content{ background-color:pink; width:150px; height:200px; } </style> <body> <div id="main"> <div id="content"></div> </div> <script> var mymain=document.getElementById("main"); var mycontent=document.getElementById("content"); mymain.addEventListener("click",function(){console.log("main")},false); mycontent.addEventListener("click",function(){console.log("content")},false); </script> </body> </html>
false 效果,从下往上出来,所以是content先出来:
true效果,从上往下出来,所以是main先出来:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> #main{ background-color:red; width:300px; height:400px; } #content{ background-color:pink; width:150px; height:200px; } </style> <body> <div id="main"> <div id="content"></div> </div> <script> var mymain=document.getElementById("main"); var mycontent=document.getElementById("content"); mymain.addEventListener("click",function(){console.log("main")},true); mycontent.addEventListener("click",function(){console.log("content")},true); </script> </body> </html>
效果图: