事件

一.注册事件的三种方式

给元素添加事件称为注册事件,常见的事件有:click、load、mouseover、mouseout、mouseenter、mouseleave、
change、input、focus、blur等。

1.使用传统方式注册事件

<button>传统注册单击事件</button>
 
var btn = document.querySelector('button');
btn.onclick = function(){
      alert('随便1号');
}
btn.onclick = function(){
      alert('随便2号');
}
 
btn.onclick = null ; //移除事件处理程序
 
传统注册事件方式特点:注册事件的唯一性,同一个元素同一个事件只能设置一个处理函数,后注册的事件会覆盖前面的事件
 

2.使用方法监听注册事件addEventListener(type,listener,[useCapture])

type:事件类型字符串,要加引号!! 比如click、 mouseover

listener:事件处理函数 事件发生时 会调用监听该函数  可以是匿名函数function(){}的形式 也可以是函数名或者是箭头函数 () => {}
useCapture:可选参数 是一个布尔值 默认false
 
<button>方法监听注册单击事件</button>
 
var btn = document.querySelector('button');
btn.addEventListener('click',function(){
    alert('事件侦听一号');
},false);
btn.addEventListener('click',function(){
    alert('事件侦听二号');
},false);

特点:同一个元素同一个事件可以注册多个监听器

function fn(){
alert('我要被移除啦');
}
或者是
var fn =function(){
 alert('我要被移除啦');
}
btn.addEventListener('click',fn,false);
btn.removeEventListener('click',fn,false);//移除事件
注意:使用事件侦听方式注册事件想要移除该事件,必须保证参数完全一致,第二个参数只能是函数名的形式。

 

 

3.使用attachEvent()注册事件

      

<button>attachEvent注册单击事件</button>
var btn = document.querySelector('button');
btn.attachEvent('onclick',function(){
    alert('我是IE8及更早的注册方式了1号');
});
btn.attachEvent('onclick',function(){
    alert('我是IE8及更早的注册方式了2号');
});

 

 
 
特点:同一个元素添加两个不同的事件处理程序,会以添加它们的顺序反向触发,上述会先弹出2号再弹出1号,
并且作为事件处理程序添加的匿名函数也无法移除
 
 
function fn(){
    alert('我要被移除啦');
}
或者是
var fn = function(){
   alert('我要被移除啦');
}
btn.attachEvent('onclick',fn);
btn.detachEvent('onclick',fn);//移除事件

 

二.事件对象

在DOM中发生事件时,所有相关信息都会被收集并存储在一个名为event的对象中。这个对象包含了一些

基本信息,比如导致事件的元素、发生的事件类型,以及可能与特定事件相关的任何其他数据。

event写在事件处理函数的小括号里,当形参看。事件对象只有有了事件才会存在,是系统自动创建的,不需要我们传递参数

<button>事件对象</button>

var btn=document.querySelector('button');

btn.addEventListener('click',function(event){

    console.log(event.type);  //  事件类型 click

    console.log(event.target); // 事件的触发者 这里是button

    console.log(event.pageX); //事件发生时鼠标到页面而非视口左边的距离

    console.log(event.pageY); ////事件发生时鼠标到页面而非视口上边的距离

console.log(event.eventPhase)//表示调用事件处理程序的阶段:1代表捕获阶段,2代表到达目标阶段,3代表冒泡阶段
})

 

clientX 得到鼠标在可视区域内的x坐标 (不包含不可视区域)
clientY 得到鼠标在可视区域内的y坐标 (不包含不可视区域)
offsetX 得到鼠标在偏移元素内容的x坐标 (当前添加事件的元素里面的坐标 不包含border)
offsetY 得到鼠标在偏移元素内容的y坐标 (当前添加事件的元素里面的坐标 不包含border)
layerX 默认是得到鼠标基于页面的x坐标 当你添加定位以后他是基于定位元素的坐标
layerY 默认是得到鼠标基于页面的y坐标 当你添加定位以后他是基于定位元素的坐标
screenX 得到鼠标在屏幕的上的x坐标
screenY 得到鼠标在屏幕上的y坐标

按键的相关属性

altKey 是否长按alt键
ctrlKey 是否长按ctrl键
shiftKey 是否长按shift键

键盘事件相关的内容(需要键盘来触发的事件)

key 属性 (当前按下的键)
keycode 属性 (获取当前按下键大写的ascii码)
charCode 属性(字符键 press事件 ascii码)

e.target和this的指向区别

<div>123</div>
<ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
</ul>
 
var div=document.querySelector('div');
var ul=document.querySelector('ul');
 
 div.addEventListener('click',function(e){
     console.log(e.target);//div
     console.log(this); //div
});
 
ul.onclick = function(e){   
    console.log(e.target);  //指向事件的触发者 这里点击哪个小li,e.target就指向哪个小li
    console.log(this);//指向事件的绑定者ul
}

 

 

阻止默认行为:让链接不跳转,或者让提交按钮不提交

<a href="www.qfedu.com">qf官网</a>
var a = document.querySelector('a');
a.addEventListener('click',function(e){
    e.preventDefault();
//e.returnValue = false ie写法
//e.preventDefault?e.preventDefault():e.returnValue = false 兼容写法
//return false 也可以阻止默认行为 但是return后面的代码不再执行 且只支持传统注册方式 })

 

 

三.事件流

事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播 这个传播过程就是DOM事件流

DOM事件流的三个阶段:
1.捕获阶段: 从上往下 document html body 目标对象
2.当前目标阶段
3.冒泡阶段 从目标对象 body html document
JS代码中只能执行捕获或者冒泡其中的一个阶段,onclick和attachEvent只能得到冒泡阶段  
addEventListener(type,listener,[useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序 如果是false 表示在事件冒泡阶段调用事件处理程序
 
 
<style>
        .father{
            width:500px;
            height:500px;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: skyblue;
            margin:100px auto;
        }
        .son{
            width:200px;
            height:200px;
            background-color: pink;
            text-align: center;
            line-height: 200px;
        }
</style>
 
<div class="father">
     <div class="son">son盒子</div>
</div>

 

 

事件捕获阶段

var son = document.querySelector('.son');
var father = document.querySelector('.father');
 
son.addEventListener('click',function(){
   alert('son'); // body father son
},true);
 
father.addEventListener('click',function(){
   alert('father'); // body father
},true);
 
document.body.addEventListener('click',function(){
   alert('body'); // body
},true);

 

 

事件冒泡阶段

son.addEventListener('click',function(e){
    alert('son');   //  son father body document
 
    //e.stopPropagation();    阻止冒泡
    // e.cancelBubble ie678使用
//兼容写法:e.stopPropagation?e.stopPropagation():e.cancelBubble = true
},false); father.addEventListener('click',function(e){ alert('father'); //father body document // e.stopPropagation(); },false); document.body.addEventListener('click',function(e){ alert('body'); // body document }) document.addEventListener('click',function(e){ alert('document'); // document },false)

 

 

利用冒泡原理实现事件委托(事件代理)

事件委托的原理:不要给每个子节点单独设置事件监听器,事件监听器应该设置在其父节点上 然后利用冒泡原理影响每个子节点

.current{

   background-color:skyblue;

}

<ul>
   <li class='current'>li1</li>
   <li>li2</li>
   <li>li3</li>
   <li>此处省略n个小li</li>
   <li>li100</li>
</ul>
 
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
  //点哪个小li 哪个小li背景色变天蓝色的三种方式
    for(var i=0;i<ul.children.length;i++){
       ul.children[i].style.backgroundColor='';
}
e.target.style.backgroundColor='skyblue';
 
   
  for(var i=0;i<ul.children.length;i++){
       ul.children[i].className='';
}
e.target.className='current';
 
document.querySelect('ul .current').classList.remove ('current');
e.target.classList.add('current');
 
},false)

 

 
此外,jQuery中我们在动态创建元素的时候,后来创建的元素是不能直接给元素注册事件的,这时候就可以用到我们的事件委托思想。
<ul>
     <li>先来滴</li>
</ul>

$("ul").on("click","li",function(){
     alert("点原来滴后来滴都有用");
});
var li =$("<li>后来滴</li>");
$("ul").append(li);

 

 
 

 拖动的模态框

      * {
            margin: 0;
            padding: 0;
        }

        .box {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 300px;
            height: 300px;
            display: block;
            background-color: red;
            transform: translate(-50%, -50%);
        }

        .drag {
            height: 50px;
            background-color: purple;
            line-height: 50px;
            padding-left: 10px;
        }
 
       
      <div class="box">
         <div class="drag">
            <button class="closeBtn">关闭</button>
         </div>
      </div>
 
      
<script>
    var box = document.querySelector('.box');
    var drag = document.querySelector('.drag');
    var closeBtn = document.querySelector('.closeBtn');

    drag.addEventListener('mousedown', function (e) {
        var x = e.pageX - box.offsetLeft;//获取鼠标按下时 鼠标在drag盒子内的左边坐标
        var y = e.pageY - box.offsetTop;//获取鼠标按下时 鼠标在drag盒子内的上边坐标

        document.addEventListener('mousemove', move);
       
        function move(e) {
            box.style.left = e.pageX - x + 'px';
            box.style.top = e.pageY - y + 'px';
        }

        document.addEventListener('mouseup',function(){
            document.removeEventListener('mousemove',move);
        })
    })

    closeBtn.addEventListener('click',function(){
            box.style.display = 'none';
        })
</script>

 

 全选反选

<input type="checkbox" id="checkAll">全选/取消全选
<input type="checkbox" id="reverseCheck">反选
<div>
     <input type="checkbox">
     <input type="checkbox">
     <input type="checkbox">
     <input type="checkbox">
     <input type="checkbox">
</div>

<script>
    var checkAll = document.querySelector('#checkAll');
    var reverseChecks = document.querySelector('#reverseCheck');
    var inputs = document.querySelectorAll('div>input[type="checkbox"]');

    // 全选按钮
    checkAll.onclick = function(){
        for(var i=0;i<inputs.length;i++){
            inputs[i].checked = this.checked;
        }
    }
   
    // 下面按钮
    for(var i=0;i<inputs.length;i++){
        inputs[i].onclick = function(){
            var flag=true;
            for(var i=0;i<inputs.length;i++){
                if(!inputs[i].checked){
                    flag=false;
                    break;
                }
               
            }
            checkAll.checked = flag;
        }
    }

    // 反选按钮
    reverseChecks.onclick = function(){
        if(this.checked){
            reverse();
        }
    }
    function reverse(){
        for(var i=0;i<inputs.length;i++){
            inputs[i].checked = !inputs[i].checked ;
        }
    }
</script>

 

 

 
 
 
 

 

 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 

 

点击查看代码 ``` 点击查看代码 ``` 点击查看代码 ``` ``` ``` ```
posted @ 2022-08-08 03:15  4小时充足睡眠  阅读(165)  评论(0)    收藏  举报