八、DOM三 -- DOM事件

一、事件绑定

1.1 HTML标签事件绑定

HTML标签内绑定事件,相当于在标签内执行一段代码:	
				<button onclick="show();print();alert('123')" id="btn1">html标签事件绑定</button>
			

	注意:
		1、通过HTML标签绑定事件函数,实质上就是在标签内运行多行JS代码。
		
		2、在标签内绑定事件函数,事件函数中的this指的是window对象。
		
		3、在标签内绑定事件函数,事件函数可以传入参数。
					可以传入任意参数。
					也可以传入this对象,代表当前标签对象。
			
1)通过HTML标签绑定事件函数,实质上就是在标签内运行多行JS代码

 <script>
 
            function show(){
                alert('456')
            }

            function show2(){
                alert('789')
            }

</script>

<body>
    
    <button onclick="alert('123');show();show2()"> 点我一下</button>
    
</body>

在这里插入图片描述

2)在标签内绑定事件函数,事件函数中的this指的是window对象
    <script>
                function show(){
                   console.log(this)
                }

    </script>
</head>
<body>
    
    <button onclick="show();"> 点我一下</button>
</body>    

在这里插入图片描述

3)在标签内绑定事件函数,事件函数可以传入任意参数,也可以传入this对象。
>>>>>> 可以给绑定的函数传入任意参数
 <script>
                function show(str){
                   console.log(str); 
                }

         

    </script>
</head>
<body>
    
    <button onclick="show('123');"> 传入字符串</button>

</body>

在这里插入图片描述

>>>>>> 可以给绑定的函数传入this对象,这里的this对象指的就是标签本身。
 <script>
              function show(obj){
                 console.log(obj); 
              }

    </script>
</head>
<body>    
    <button onclick="show(this);"> 传入this</button>
</body>

在这里插入图片描述

1.2 JS事件绑定

	
		1、绑定一个匿名函数
				    elem.onclick=function(){
				        alert("1")
				    }


		2、绑定一个已经声明的函数	
					function show(){
					  console.log('show');
					}
					
					//绑定一个已经声明的函数
				    elem.onclick=show;
	

	注意:		
		1JS事件绑定,事件函数中的this指的是绑定的对象。

		2、只能为一个事件绑定一个响应函数,不能绑定多个。
		   如果绑定多个,则后面绑定的响应函数会覆盖之前的响应函数。	
		
		3JS事件绑定,事件函数中的this指的是绑定的元素。
				
1)JS事件绑定

<body>
    
    <button > 绑定匿名函数</button>
    <button > 绑定已经声明的函数</button>
</body>
    <script>


            /** 绑定匿名函数*/
            var btn=document.getElementsByTagName("button")[0]
            btn.onclick=function(){
                alert("123")
            }

            /** 绑定已经声明的函数*/
            function show(){
                alert("123")
            }
            var btn1=document.getElementsByTagName("button")[1]
            btn1.onclick=show;
            

    </script>

在这里插入图片描述

2)只能为一个事件绑定一个响应函数,不能绑定多个。否则会覆盖
<body>
    
    <button> 点我一下</button>
    
</body>

<script>

    var btn=document.getElementsByTagName("button")[0];
    
    btn.onclick=function(){
        alert("0")
    }
    btn.onclick=function(){
        alert("1")
    }
	
	//会覆盖前面绑定的事件函数
    btn.onclick=function(){
        alert("2")
    }
</script>
   

在这里插入图片描述

3)JS事件绑定,事件函数中的this指的是绑定的元素

1.3 事件监听

	
	+++ IE8以上浏览器事件监听
	
				elem.addEventListener("click",function(){},false);
										第一个参数:事件的字符串, 不用on
										第二个参数:回调函数,当事件触发时会调用该回调函数
										第三个参数:默认为false,表示是否捕获阶段触发。
			
							1IE8以上浏览器支持
							
							2、可以同时为一个事件绑定多个响应函数。
				     		   当事件被触发时,响应函数将会按照绑定的顺序正序执行。
							
							3、事件函数中的this指的是元素本身


	+++ IE8以及以下浏览器事件监听
	
				elem.attachEvent("onclick",function(){});
										第一个参数:事件的字符串, 要on
										第二个参数:回调函数,当事件触发时会调用该回调函数
							
							1IE8以及以下浏览器支持
							
							2、可以同时为一个事件绑定多个响应函数。
				     		   当事件被触发时,响应函数将会按照绑定的顺序倒序执行。
							
							3、事件函数中的this指的是window。
				

	+++ 事件监听兼容性处理
	
			    function bind(obj,eventStr,calFun){
	                    if(obj.addEventListener){
	                        //兼容IE8以上浏览器
	                        obj.addEventListener(eventStr,calFun);
	                    }else{
	                        //兼容IE8以及以下浏览器
	                        obj.attachEvent("on"+eventStr,function(){
	
	                            //改变函数中的this对象
	                            calFun.apply(obj);
	                        })
	                    }
                 }

1)addEventListener事件监听
>>>>>> 可以绑定多个响应函数。按照顺序正序执行(仅支持IE8以上浏览器)

<body>    
    <button > 事件监听</button>
</body>
    <script>


            var btn=document.getElementsByTagName("button")[0]
           
            btn.addEventListener("click",function(){
                alert("123")
            })
            btn.addEventListener("click",function(){
                alert("456")
            })
            btn.addEventListener("click",function(){
                alert("789")
            })

    </script>
2)attachEvent事件监听
>>>>>> 可以绑定多个响应函数。按照顺序倒叙执行(仅支持IE8以及以下浏览器)

<body>
    
    <button > 事件监听</button>
</body>
    <script>


            var btn=document.getElementsByTagName("button")[0]
           
            btn.attachEvent("onclick",function(){
                alert("123")
            })
            btn.attachEvent("onclick",function(){
                alert("456")
            })
            btn.attachEvent("onclick",function(){
                alert("789")
            })


    </script>

在这里插入图片描述

3)监听事件兼容性处理
	
	如果事件监听要处理兼容性,
	则我们需要考虑:addEventListener和attachEvent的this指向问题。
					
					1、addEventListener中的this指的的元素本身
					2、attachEvent中的this指的是window对象。
			

		 function bind(obj,eventStr,calFun){
                    if(obj.addEventListener){
                        //兼容IE8以上浏览器
                        obj.addEventListener(eventStr,calFun);
                    }else{
                        //兼容IE8以及以下浏览器
                        obj.attachEvent("on"+eventStr,function(){

                            //改变函数中的this对象
                            calFun.apply(obj);
                        })
                    }
                }
>>>>>> 案例

<body>
    
    <button > 事件监听</button>
</body>
    <script>


            /** 事件监听兼容性处理*/
            function bind(obj,eventStr,calFun){
                    if(obj.addEventListener){
                        //兼容IE8以上浏览器
                        obj.addEventListener(eventStr,calFun);
                    }else{
                        //兼容IE8以及以下浏览器
                        obj.attachEvent("on"+eventStr,function(){

                            //改变函数中的this对象
                            calFun.apply(obj);
                        })
                    }
             }

             var btn=document.getElementsByTagName("button")[0]
            
             bind(btn,"click",function(){
                 alert("123")
             })

             bind(btn,"click",function(){
                 alert("456")
             })

             bind(btn,"click",function(){
                 alert("789")
             })


    </script>

二、事件对象


	事件对象(event)1) 在事件对象中封装了当前事件相关的一切信息。比如:鼠标的坐标、按键值等
		 
		  2)IE8以上浏览器
		  	    	 当事件回调函数被触发时,
		  	   		 浏览器每次都会将一个事件对象作为一个实参传递给回调函数。
		  	   		     
		  3)IE8以及以下浏览器
					 事件对象会被当作window的属性来保存。
		  
		  4) Event对象是在事件触发时就会存在的对象。
		     它有很多实现类,比如MouseEvent、FocusEvent等。我们可以访问event对象来访问事件相关的众多属性。	
		  
		  5) 事件对象和触发的事件有关系。事件对象类型不同,事件对象中的属性也有可能不同,
		  		比如点击事件click,则事件对象是 MouseEvent。该对象中无key、keyCode属性
		  		比如键盘事件keydown,则事件对象是 KeyboardEvent。该对象有key、keyCode属性。
				

1.1 事件对象的使用

1)在IE8以上浏览器,事件对象会被当做一个实参传入到事件回调函数中

当事件回调函数被触发时,浏览器会将一个事件对象作为实参传入回调函数中。由于arguments会接收所有的参数,我们打印arguments对象来查看传入的event对象。


         var box1=document.getElementById("box1")
         box1.onclick=function(){
             console.log(arguments[0])
         }
            

在这里插入图片描述


我们可以定义一个变量来接收传入的event对象


     var box1=document.getElementById("box1");
     box1.onclick=function(event){
            console.log(event)
     }
        

在这里插入图片描述

2)在IE8以及以下浏览器,事件对象会被当做window的属性来保存。

         var box1=document.getElementById("box1");
         box1.onclick=function(){
         	
         	//MouseEvent {isTrusted: true, screenX: 339, screenY: 517, clientX: 97, clientY: 32, …}
             console.log(window.event);
         }

3)事件对象的兼容性处理
	
	+++ 方式一:
			   var box1=document.getElementById("box1");
			   box1.onclick=function(event){
					
				   //兼容性处理	
			       if(!event){
			           event=window.event;
			       }
			
			       console.log(event)
			   }
	   
	
	+++ 方式二:
  				var box1=document.getElementById("box1");
                box1.onclick=function(event){
                
				    //兼容性处理	
                    event=event || window.event;

                    console.log(event)
                }	   
                

1.2 事件的坐标属性(通过事件对象获取触发事件时的鼠标的坐标)

获取触发事件的鼠标坐标,主要看坐标的原点在哪里

	
	+++ 获取鼠标相对于窗口的坐标
					
				event.clientX	
				event.clientY	
						获取鼠标相对于窗口的水平坐标、垂直坐标
					    (0,0)零点永远都在浏览器的左上端。
					    
								    注意:使用该属性来实现【DIV元素随鼠标移动】,
								         如果页面没有滚动条,则可以实现。
								         如果页面有滚动条,则实现不了。原因是通过该属性获取的坐标是相对于窗口,而不是页面。

		 
	 
	
	+++ 获取鼠标相对于页面的坐标
				
				方式一:	
						event.pageX
						event.pageY   
								获取鼠标相对于页面的水平坐标、垂直坐标。
								(0,0)零点永远都在页面的左上端。
								只支持IE8以上浏览器

				方式二:
						event.clientX	+ scrollLeft	 
						event.clientY	+ scrollTop 
								获取鼠标相对于页面的水平坐标、垂直坐标。
								兼容所有浏览器。
	 								
		 注意:这里隐藏了一个恒等式,即
					event.clientX + document.body.scrollLeft  = pageX
					event.clientY + document.body.scrollTop   = pageY



	
	+++ 获取鼠标相对于事件元素左上角的坐标
				
				event.offsetX
				event.offsetY
						获取鼠标相对于事件元素左上角的坐标
					    (0,0)零点永远都在事件元素的左上端。
			

1)获取鼠标相对于窗口的坐标

       //给文档绑定移动事件
       document.onmousemove=function(event){
			
		   //事件对象兼容性处理	
           event=event || window.event;
           
           //获取鼠标相对于窗口的水平坐标、垂直坐标
           console.log("x:"+event.clientX+"  ,y:"+ event.clientY);

       }

在这里插入图片描述

2)获取鼠标相对于页面的坐标
>>>>>> DIV元素随鼠标移动【使用pageX、pageY实现】【只支持IE8以上浏览器】
	
	pageX、pageY可以获取鼠标相对于页面的坐标,所以我们可以通过获取该值来设置元素的移动。
	不过,该属性只支持IE8以上浏览器。
	
<!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>

    <script>

            window.onload=function(){

                var box1=document.getElementById("box1");

                //给html标签绑定移动事件
                document.documentElement.onmousemove=function(event){

                    event=event || window.event;

                    var left=event.pageX;
                    var top=event.pageY ;

                    
                    // var left=event.clientX + document.body.scrollLeft;
                    // var top=event.clientY + document.body.scrollTop;

                    box1.style.left=left+"px";
                    box1.style.top=top+"px";

                }

            }

    </script>
</head>
<body>
    <div id="box1" style="width:100px;height:100px;border:1px solid red;position:absolute;"></div>
</body>
</html>

在这里插入图片描述

>>>>>> DIV元素随鼠标移动【兼容性处理,支持所有浏览器】
	
	我们使用clientX、clientY获取的坐标是鼠标相对于浏览器的坐标。
	而元素的左右定位是相对于页面的坐标。  
	这里隐藏了一个等式,即
						clientX+scrollLeft  = pageX
						clientY+scrollTop   = pageY
							
<!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>

    <script>

            window.onload=function(){

                var box1=document.getElementById("box1");

                //给html标签绑定移动事件
                document.documentElement.onmousemove=function(event){

                    event=event || window.event;
                    
                    var left=event.clientX + document.body.scrollLeft;
                    var top=event.clientY + document.body.scrollTop;

                    box1.style.left=left+"px";
                    box1.style.top=top+"px";

                }

            }

    </script>
</head>
<body>
    <div id="box1" style="width:100px;height:100px;border:1px solid red;position:absolute;"></div>
</body>
</html>

在这里插入图片描述

3)获取鼠标相对于事件元素左上角
				
				event.offsetX
				event.offsetY
						获取鼠标相对于事件元素左上角的坐标
					    (0,0)零点永远都在事件元素的左上端。
	
	

1.3 事件对象的键盘属性(按键事件对象)


	altKey		返回当事件被触发时,"ALT" 是否被按下。
	ctrlKey		返回当事件被触发时,"CTRL" 键是否被按下。
	metaKey		返回当事件被触发时,"meta" 键是否被按下。
	shiftKey	返回当事件被触发时,"SHIFT" 键是否被按下。
	
	button		返回当事件被触发时,哪个鼠标按钮被点击。


	key			返回按键在系统中默认的名称
	keyCode      返回按键在系统中的值。

>>>>>> 案例1
       
        
        document.onkeydown=function(event){

            if(event.altKey){
                alert("alt键被按下")
                return;
            }


            if(event.ctrlKey){
                alert("ctrl键被按下")
                return;
            }

            if(event.shiftKey){
                alert("shift键被按下")
                return;
            }


            if(event.metaKey){
                alert("meta键被按下")
                return;
            }
        }

>>>>>> 案例2:获取按键的名称和键值
<body>


    <input type="text"  id="btn" > 



    <script>

        var obj= document.getElementById("btn")
        obj.onkeydown=function(event){
            console.log(event.key,event.keyCode)
        }


    </script>
</body>

在这里插入图片描述

1.4 事件对象的target属性

	event.target
			获取当前获取触发事件的元素对象。
			
<body>


    <input type="text"  id="btn" > 


    <script>

        var obj= document.getElementById("btn")
        obj.onkeydown=function(event){
            console.log(event.target)
        }

    </script>

在这里插入图片描述

1.5 拖拽案例

1)案例1

缺点:拖拽元素时只能拖拽左上角

<!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>
        
        div{
            width:100px;
            height:100px;
            background-color: red;

            position: absolute;
        }

    </style>
</head>
<body>
    
    <div></div>
</body>

<script>

    
    var div=document.getElementsByTagName("div")[0];
    
    //给DIV添加鼠标按下事件
    div.onmousedown=function(){
        
        //鼠标按下时绑定鼠标移动事件
        document.onmousemove=function(event){
            event=event||window.event;

            //获取鼠标相对于页面的坐标
            var x=event.pageX;
            var y=event.pageY;

            div.style.left=x+"px";
            div.style.top=y+"px";
        }

        //鼠标按下时绑定鼠标抬起事件
        document.onmouseup=function(){
             //取消移动事件
             document.onmousemove=null;
            
            //取消鼠标抬起事件
            document.onmouseup=null;
        }
    }

</script>
</html>

在这里插入图片描述

2)案例2
<!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>
        
        div{
            width:100px;
            height:100px;
            background-color: red;

            position: absolute;
        }

    </style>
    

</head>
<body>
    
    <div></div>
</body>

<script>

    
    var div=document.getElementsByTagName("div")[0];
    
    //给DIV添加鼠标按下事件
    div.onmousedown=function(){
        
        //鼠标的相对于页面的坐标 - 元素的偏移量 
        var ox=event.pageX-div.offsetLeft;
        var oy=event.pageY-div.offsetTop;
        
        //鼠标按下时绑定鼠标移动事件
        document.onmousemove=function(event){
            
            event=event||window.event;

            //获取鼠标相对于页面的坐标
            var x=event.pageX-ox;
            var y=event.pageY-oy;

            div.style.left=x+"px";
            div.style.top=y+"px";
        }

        //鼠标按下时绑定鼠标抬起事件
        document.onmouseup=function(){
             //取消移动事件
             document.onmousemove=null;
            
            //取消鼠标抬起事件
            document.onmouseup=null;
        }


    }

</script>
</html>

在这里插入图片描述

3)案例3(基于案例2的封装)
<!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>
        
        *{
            margin:0px;
            padding:0px;
        }
       

        .dd{

            width:100px;
            height:100px;
            background-color: red;

            position: absolute;

        }

    </style>
    

</head>
<body>
    
    <div class="dd">box1</div>
    <div class="dd">box2</div>
    <div class="dd">box3</div>

</body>

<script>

    
    


    function drag(elem){
            
        //给DIV添加鼠标按下事件
            elem.onmousedown=function(){

                    
                    //鼠标的相对于页面的坐标 - 元素的偏移量 
                    var ox=event.pageX-elem.offsetLeft;
                    var oy=event.pageY-elem.offsetTop;


                    //给document添加一个鼠标移动事件
                    document.onmousemove=function(event){
                        
                        event=event||window.event;

                        //获取鼠标相对于页面的坐标
                        var x=event.pageX-ox;
                        var y=event.pageY-oy;

                        elem.style.left=x+"px";
                        elem.style.top=y+"px";
                    }

                    //给document添加一个鼠标抬起事件
                    document.onmouseup=function(){
                        //取消移动事件
                        document.onmousemove=null;
                        
                        //取消鼠标抬起事件
                        document.onmouseup=null;
                    }
                }
    }
    

    var box1=document.getElementsByClassName("dd")[0]
    drag(box1)


    var box2=document.getElementsByClassName("dd")[1]
    drag(box2)

    var box3=document.getElementsByClassName("dd")[2]
    drag(box3)

</script>
</html>

在这里插入图片描述

三、事件的冒泡

	
	+++ 事件冒泡
				1、所谓的冒泡指的就是事件触发会向上传导。
				   当后代的事件被触发时,其祖先相同的事件也会被触发。
				
				2、事件冒泡具有两面性。不能单纯的说好坏。
							
	
	+++ 阻止事件冒泡
	
				方式一:
				  box2.onclick=function(event){
				 
                            //取消冒泡
                            event=event || window.event;
                            event.cancelBubble=true; 

                            alert("我是box2的单击响应函数");
                    }	
                    
				方式二:
				  box2.onclick=function(event){
				 
                            //取消冒泡
                            event=event || window.event;
                           event.stopPropagation();

                            alert("我是box2的单击响应函数");
                    }	

                   		
                   	注意:阻止冒泡就是是阻止子元素的事件冒泡,
                   	     所以阻止冒泡要加在子元素绑定的事件函数中。



                   	    		
1)事件冒泡

所谓的事件冒泡指的就是当我点击box2时,触发了box2的点击事件。同时也触发了box2的祖先元素box1的相同事件。

<!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>

        .box1{
            width:500px;
            height:500px;
            background-color: red;
        }

        .box2{
            width:300px;
            height:300px;
            background-color: blue;
        }

     

    </style>

    <script>

            window.onload=function(){
                    var box1=document.getElementsByClassName("box1")[0];
                    var box2=document.getElementsByClassName("box2")[0];

                    box1.onclick=function(){
                        alert("我是box1的单击响应函数")
                    }

                    box2.onclick=function(){
                            alert("我是box2的单击响应函数");
                    }

              


            }

    </script>
</head>
<body>
    <div class="box1">
        <div  class="box2"></div>
    </div>
</body>
</html>

在这里插入图片描述

2)阻止事件冒泡

阻止事件冒泡指的是阻止后代元素box2的事件触发导致祖先元素box1的事件触发。此时点击后代元素box2,只会触发box2绑定的事件。

<!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>

        .box1{
            width:500px;
            height:500px;
            background-color: red;
        }

        .box2{
            width:300px;
            height:300px;
            background-color: blue;
        }

     

    </style>

    <script>

            window.onload=function(){
                    var box1=document.getElementsByClassName("box1")[0];
                    var box2=document.getElementsByClassName("box2")[0];

                    box1.onclick=function(){
                        alert("我是box1的单击响应函数")
                    }

                    box2.onclick=function(event){

                            //取消冒泡
                            event=event || window.event;
                            event.cancelBubble=true; 

                            alert("我是box2的单击响应函数");
                    }

              


            }

    </script>
</head>
<body>
    <div class="box1">
        <div  class="box2"></div>
    </div>
</body>
</html>

在这里插入图片描述

3)冒泡的意义

	1、元素不绑定事件函数也可以触发事件。
	   只不过是没有事件回调函数去处理。

	2、如果元素没有后代元素,那么元素的事件触发,就是本身的事件触发。
	   如果元素有后代元素,那么元素的事件触发,实质上可能是由于后代元素(鼠标指向的后代元素)的事件触发冒泡所致。

>>>>>> 以【DIV元素随鼠标移动】案例为例
	
	给document对象绑定鼠标移动事件回调函数。
	
	当鼠标移动到红色盒子上时,document对象的移动事件回调函数也被调用。
	实质上是由于红色盒子的鼠标移动事件冒泡,从而触发了document的鼠标移动事件。
	
	如果我们阻止红色盒子的事件冒泡,
	那么就会出现鼠标在红色盒子上移动,不会触发document的鼠标移动事件。
	
<!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>

        *{
            margin:0px;
            padding:0px;
        }

        .box1{
            width:500px;
            height:500px;
            background-color: red;
        }

        .box2{
            width:100px;
            height:100px;
            background-color: blue;
            position: absolute;
        }

     

    </style>

    <script>

            window.onload=function(){
                  
                    var box2=document.getElementsByClassName("box2")[0];

                    //给document对象绑定鼠标移动事件回调函数
                    document.onmousemove=function(event){
                        
                        //兼容性处理
                        event=event||window.event;

                        var left=event.clientX + document.body.scrollLeft;
                        var top=event.clientY + document.body.scrollTop;

                        box2.style.left=left+"px";
                        box2.style.top=top+"px";
                    }

                    //阻止box1的鼠标移动事件冒泡
                    var box1=document.getElementsByClassName("box1")[0];
                    box1.onmousemove=function(event){

                            event=event||window.event;
                            event.cancelBubble=true; 
                    }
      
            }

    </script>
</head>
<body>
   
    <div class="box1"></div>
    <div class="box2"></div>

</body>
</html>

在这里插入图片描述

四、事件的委派

	
	+++ 事件委派
			1、事件委派利用了事件冒泡机制。通过祖先元素的绑定的事件函数来处理后代元素的事件。
			
			2、通过事件委派可以减少事件绑定的次数。只绑定一次,即可应用到多个元素上。提高运行的效率。
			
			3、将事件统一绑定给元素的共同的祖先元素,后代元素的事件触发,通过冒泡,就会导致祖先元素的事件也会被触发。
			   这样就可以通过祖先元素的事件函数来处理事件。
			
			【所谓的事件委派机制,我的理解更像是一种编程方式。】

	
	+++ 事件委派的实现
			1、将事件统一绑定给元素的共同的祖先元素。
			2、在事件函数中通过event.target来访问触发事件的实际对象。
						(实际对象指的就是鼠标指向的对象。由于该对象的事件触发,并向上冒泡,从而导致祖先元素的事件触发)
					  		
					        ul.onclick=function(event){
					
					            event=event||window.event;
					            console.log(event.target)
					            
					            //通过event.target来访问触发事件的实际对象
					            alert(event.target.innerHTML)
					        }
		
1)事件委派的来源

	for循环给元素绑定事件函数,绑定次数过多,会造成资源的浪费。
	

给a标签设置点击事件。只能重复绑定。并且只能为已有的a标签设置事件。对于新增加的a标签,只能再次添加才可以。


<body>
    
    <button> 添加超链接</button>
    <ul>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
    </ul>
</body>

<script>


        //点击按钮,新增li标签
        var btn=document.getElementsByTagName("button")[0];
        var ul=document.getElementsByTagName("ul")[0];
        
        btn.onclick=function(){

            var li=document.createElement("li");
            li.innerHTML='<a href="javascript:;">百度</a>';

            ul.appendChild(li);
        }


        //给a标签添加事件
        var aElems=document.querySelectorAll("ul li a");
        for(var i=0;i<aElems.length;i++){
            aElems[i].onclick=function(){
                alert("123");
            }
        }

</script>
</html>

在这里插入图片描述

2)事件委派

	1、给元素的共同的祖先元素绑定一个事件,
	  当触发子元素的事件时,通过冒泡就会触发祖先元素的事件函数。通过祖先元素的事件函数来进行处理。
	
	2、在事件函数我们可以通过event.target来操作触发事件实际的对象。
	
>>>>>> 事件委派
<body>
    
    <button> 添加超链接</button>
    <ul>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
    </ul>
</body>

<script>

        //事件委派
        var ul=document.querySelectorAll("ul")[0];
        ul.onclick=function(event){

            event=event||window.event;
            console.log(event.target)
            
            //我们可以通过event.target来访问触发事件的实际对象
            alert(event.target.innerHTML)
        }

</script>

在这里插入图片描述

>>>>>> 解析
	
	a标签的点击事件被触发,通过冒泡从而导致祖先元素ul的点击事件被触发。
	我们在ul绑定的点击事件中,
	可以通过event.target来访问触发事件的实际对象(就是鼠标指向的对象)。
	
3)事件委派案例
<!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>
</head>
<body>
    
    <button> 添加超链接</button>
    <ul>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
        <li><a href="javascript:;">百度</a></li>
    </ul>
</body>

<script>
		
		//事件委派机制
		//给a标签共同的祖先元素绑定事件
		//当触发a标签的点击事件时,通过冒泡就会触发祖先元素的事件函数。
		//我们通过祖先元素的事件函数来相应处理。
        var ul=document.querySelectorAll("ul")[0];
        ul.onclick=function(event){

            event=event||window.event;
            console.log(event.target)
            
            //通过event.target来访问触发事件的实际对象
            alert(event.target.innerHTML)
        }


        //点击按钮,新增li标签
        var btn=document.getElementsByTagName("button")[0];
        var ul=document.getElementsByTagName("ul")[0];
        
        btn.onclick=function(){

            var li=document.createElement("li");
            li.innerHTML='<a href="javascript:;">百度</a>';

            ul.appendChild(li);
        }

</script>
</html>

在这里插入图片描述

五、事件的传播

4.1 事件的传播方式

	
	关于事件的传播,微软公司和网景公司有不同的理解。
	
	1) 微软公司认为事件应该由内向外传播。
	   		当事件触发时,先触发当前元素(鼠标指向的元素)的事件,
	   		然后在向当前元素的祖先元素传播。也就说事件在冒泡阶段执行。

	   
	2) 网景公司认为事件应该由外向内传播。
	   		当事件触发时,先触发当前元素(鼠标指向的元素)的最外层的祖先元素的事件,
	   		然后在向内传播给后代元素。
		
		

	3) W3C综合了两家公司方案。将事件传播分为三个阶段。
					
		1、捕获阶段
				在捕获阶段时,从最外层的祖先元素向目标元素进行事件的捕获,
				但是默认此时不触发事件。
				
		2、目标阶段
				事件捕获到目标元素,这是就是目标阶段。
				捕获结束开始在目标元素上触发事件。
		
		3、冒泡阶段
				事件触发由目标元素向它的祖先元素传递。
	
	【由外向内捕获,由内向外触发。默认情况下在目标阶段触发事件,然后向外冒泡。】	
		

4.2 手动设置事件触发的阶段

	
	我们可以通过addEventListener的第三个参数来设置事件触发的阶段。
	
	1) 如果我们希望事件触发在捕获阶段,则
				elem.addEventListener("click",function(){},true);

	2) 如果我们希望事件触发在目标阶段(默认就是),则
				elem.addEventListener("click",function(){});  //可不传。第三个参数默认为false
				elem.addEventListener("click",function(){},false);
	
>>>>>> 设置事件触发在捕获阶段
		
		点击box3,首先进入捕获阶段,从box3的祖先元素开始捕获。
		由于设置了捕获阶段触发事件,所以先触发box3的祖先元素的box1的事件,然后box2事件,box3事件。
		
<!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>

        .box1{
            width:500px;
            height: 500px;
            background-color: red;
        }

        .box2{
            width:400px;
            height: 400px;
            background-color: blue;
        }

        .box3{
            width:300px;
            height: 300px;
            background-color: pink;
        }

    </style>
</head>
<body>

    <div class="box1">
        <div class="box2">
            <div class="box3"></div>
        </div>
    </div>

</body>
    <script>


            var divs=document.getElementsByTagName("div");
            
            var box1=divs[0];
            var box2=divs[1];
            var box3=divs[2];

             box1.addEventListener("click",function(){
                 alert("我是box1")
             },true)

             box2.addEventListener("click",function(){
                 alert("我是box2")
             },true)

             box3.addEventListener("click",function(){
                 alert("我是box3")
             },true)

    </script>

<script>

 

 
</script>
</html>

在这里插入图片描述

>>>>>> 设置事件触发在目标阶段(默认就是)
		
		点击box3,首先进入捕获阶段,从box3的祖先元素box1开始捕获。直到box3。
		然后触发box3的事件。
		然后冒泡。
		
<!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>

        .box1{
            width:500px;
            height: 500px;
            background-color: red;
        }

        .box2{
            width:400px;
            height: 400px;
            background-color: blue;
        }

        .box3{
            width:300px;
            height: 300px;
            background-color: pink;
        }

    </style>
</head>
<body>

    <div class="box1">
        <div class="box2">
            <div class="box3"></div>
        </div>
    </div>

</body>
    <script>


            var divs=document.getElementsByTagName("div");
            
            var box1=divs[0];
            var box2=divs[1];
            var box3=divs[2];

             box1.addEventListener("click",function(){
                 alert("我是box1")
             },false)

             box2.addEventListener("click",function(){
                 alert("我是box2")
             },false)

             box3.addEventListener("click",function(){
                 alert("我是box3")
             },false)

    </script>

<script>

 

 
</script>
</html>

在这里插入图片描述

六、浏览器的默认行为

	
	+++ 浏览器的默认行为
			
			浏览器的默认行为指的是浏览器本身自带的属性,比如		
							1、a标签的自动跳转。
									a标签的自动跳转是a标签的onclick事件的默认行为。
									
							2、滑轮滚动,网页如果有滚动条也自动滚动
									滚动条滚动是标签的onmousewheel事件的默认行为。
										
							3、在文本框中输入内容属于onkeydown事件的默认行为。
	

	
	+++ 取消浏览器的默认行为	
			
			1) 取消浏览器的默认行为,这种方式只适用于通过addEventListener绑定的事件函数。
				
					elem.onclick=function(event){		
					    //调用preventDefault方法,取消浏览器的默认行为	
		        		event.preventDefault()
		    		}  
					
			2)  取消浏览器的默认行为,这种方式适用于通过HTML标签、JS绑定的事件函数
					elem.onclick=function(event){
						//返回false,取消浏览器的默认行为
		        		return false;
		    		}  
			
			3) 取消浏览器默认行为,兼容性处理
					elem.onclick=function(event){
						
						//调用preventDefault方法,取消浏览器的默认行为	
		        		event.preventDefault()
						//返回false,取消浏览器的默认行为
		        		return false;
		        		
		    		}  

			

2.1 取消a标签的默认行为

	
	取消a标签的默认行为,此时点击a标签就不会跳转。
			
			方式一: 
					<a href="javascript:;">百度</a>
			
			方式二:
				 	var aElem=document.getElementsByTagName("a")[0]
				    aElem.onclick=function(event){
						
				        event.preventDefault();
				        return false;
				        
				    }				
			

2.2 取消滑轮滚动的默认行为

	取消滑轮滚动的默认行为,此时滑动滚轮,浏览器如果有滚动条,就不会滑动了

 	var div=document.getElementsByTagName("div")[0]
    div.onmouseWheel=function(event){
		
        event.preventDefault();
        return false;
        
    }
>>>>>> 滚动滑轮,div的高度发生变化,但是浏览器滚动条不会滚动
<!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>
</head>
<body style="height:2000px">

    <div style="width:100px;height: 100px;background-color: red; position: absolute;"></div>
</body>


<script>
    
    var div=document.getElementsByTagName("div")[0];
    document.onmousewheel=function(event){

        event=event||window.event;

        //向上滚动
        if(event.wheelDelta>0){
            div.style.height=(div.scrollHeight-10)+"px";
        }

        //向下滚动
        if(event.wheelDelta<0){
            div.style.height=(div.scrollHeight+10)+"px";
        }
            
        return false;
    }

</script>

</html>

在这里插入图片描述

2.3 在文本框中只能输入英文

<!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>
</head>
<body style="height:2000px">

    <input type="text">
</body>


<script>
    
    var input=document.getElementsByTagName("input")[0];
    input.onkeydown=function(event){

        event=event||window.event;

        console.log(event.keyCode)

        if(event.keyCode < 65 || event.keyCode >90){
            return false;
        }
    }

</script>

</html>

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340