重生前端之我在javascript敲代码(07-DOM事件(下))

本文详细介绍了JavaScript中的事件处理程序注册方法,包括HTML标签和DOM元素的on方法,以及addEventListener的使用。讨论了事件冒泡过程和如何移除事件绑定。此外,还涵盖了事件委托、阻止事件传播、鼠标坐标属性和window对象的相关属性。
摘要由CSDN通过智能技术生成

一. 注册事件处理程序

可以使用:

1 通过HTML标签属性注册事件处理程序

2 通过DOM元素属性注册事件处理程序

注意:通过上面这种方式添加事件,同一个类型的事件如果添加多次的话,只执行最后添加的事件。

3 使用addEventListener()方法注册事件处理程序

  • addEventListener事件绑定、监听、捕获 ---》标准浏览器中有作用,非标准IE不兼容

  • 语法:元素.addEventListener(事件名,函数,true/false) true代表事件捕获,false代表事件冒泡。

  • 由于现在的浏览器都是执行事件冒泡,所以第三个参数通常写成false。

注意:同一种类型的事件可以添加多次,执行顺序是先添加会先执行,后面依次执行。

如下是代码详情:

  <!-- 不推荐 -->
    <div onclick="alert('点我干啥')">我是boss</div>
    <!--第二种  -->
    <div id="box">给元素绑定事件</div>
    <!-- 第三种 -->
    <!-- 使用addEventListener()方法注册事件处理程序-->
    <div id="box1">通过addEventListener方法注册事件</div>
   
    <script>
        var box = document.getElementById('box');
        box.onclick = function () {
            console.log('绑定点击事件')
        }
        var box1 = document.getElementById('box1');
        // box1.addEventListener('事件类型','事件的处理函数')
        box1.addEventListener('click',function(){
            console.log('绑定点击事件')
        })
        var box2 = document.getElementById('box2');
        // window.addEventListener('resize',function(){

        // })
        
       
      
        
</script>

二. 事件处理程序

事件就是用户或浏览器自身执行的某种动作。比如click、load和mouseover,都是事件的名字。而相应事件的函数就叫做事件处理程序(或事件侦听器)。

2.1 添加事件处理程序的两种方法
  • 第一种:“on”加事件类型,如onclick、onload等;

var btn = document.getElementsByTagName("button")[0];
​
btn.onclick = function(){
​
    alert("点击事件被触发了1");
​
}

注意:通过上面这种方式添加事件,同一个类型的事件如果添加多次的话,只执行最后添加的事件。

  • 第二种是通过addEventListener()方法:

btn.addEventListener("dblclick", function(){
      alert("双击1");
});
​
btn.addEventListener("dblclick", function(){
      alert("双击2");
});

同一种类型的事件可以添加多次,执行顺序是先添加会先执行,后面依次执行。

2.2移除事件绑定
 <!-- 不推荐 -->
    <div onclick="alert('点我干啥')">我是boss</div>
    <!--第二种  -->
    <div id="box">给元素绑定事件</div>
    <!-- 第三种 -->
    <!-- 使用addEventListener()方法注册事件处理程序-->
    <div id="box1">通过addEventListener方法注册事件</div>
    <div id="box2">移除事件</div>
    <script>
        var box = document.getElementById('box');
        box.onclick = function () {
            console.log('绑定点击事件')
        }
        var box1 = document.getElementById('box1');
        // box1.addEventListener('事件类型','事件的处理函数')
        function fn(e){
            console.log('绑定点击事件',e)
        }
        box1.addEventListener('click',fn)
        var box2 = document.getElementById('box2');
        // window.addEventListener('resize',function(){

        // })
        box2.onclick = function(){
            box1.removeEventListener('click',fn)
            box.onclick = null
        }
       
      
        
</script>

三. 事件的传递过程(事件冒泡)

JS和HTMl元素的交互几乎都是通过“事件”来完成的,事件从触发到完成响应一般分为3个阶段:捕获阶段,目标阶段,和冒泡阶段。

  1. 捕获阶段:事件从根节点流向目标节点,途中流经各个DOM节点,在各个节点上触发捕获事件,直到达到目标节点。

  2. 目标(target)阶段:在此阶段中,事件传导到目标节点。浏览器在查找到已经指定给目标事件的监听器后,就会运行该监听器。

  3. 事件冒泡: 当为多个嵌套的元素设置了相同的事件处理程序,它们将触发事件冒泡机制。在事件冒泡中,最内部的元素将首先触发其事件,然后是栈内的下一个元素触发该事件,以此类推,直到到达最外面的元素。如果把事件处理程序指定给所有的元素,那么这些事件将依次触发。

​​​​​​​

从图中我们可以知道

  • 1、一个完整的JS事件流是从window开始,最后回到window的一个过程

  • 2、事件流被分为三个阶段(1-5)捕获过程、(5-6)目标过程、(6-10)冒泡过程

//事件捕获的演示 
<style>
        .father {
            width: 600px;
            height: 600px;
            border: 3px solid red;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: #ff534c;
        }
    </style>
</head>
<body>
    <div class="father">
        这是father
        <div class="son">这是儿子</div>
    </div>
    <script>
        // 获取到元素
        var father= document.getElementsByClassName('father')[0];
        var son = document.getElementsByClassName('son')[0];
        // 事件绑定
        // addEventListener('事件类型','处理函数','boolen是否捕获')
        // true 捕获阶段 默认是false 冒泡阶段
        document.addEventListener('click',function(e){
            console.log('document',e);
        },true)
        father.addEventListener('click',function(e){
            console.log('father',e);
        },true)
        son.addEventListener('click',function(e){
            console.log('son',e);
        },true)
    </script>
//事件的传递过程
<style>
        .father {
            width: 600px;
            height: 600px;
            border: 3px solid red;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: #ff534c;
        }
    </style>
</head>
<body>
    <div class="father">
        这是father
        <div class="son">这是儿子</div>
    </div>
    <script>
        // 获取到元素
        var father= document.getElementsByClassName('father')[0];
        var son = document.getElementsByClassName('son')[0];
        // 事件的绑定
        // 从内向外触发事件
        // 并不是所有的事件都能冒泡
        // 
        document.onclick = function(){
            console.log('document')
        }
        father.onclick = function(){
            console.log('father')
        }
        son.onclick = function(){
            console.log('son')
        }
        // 事件从触发到完成响应一般分为3个阶段:捕获阶段,目标阶段,和冒泡阶段
    </script>
//阻止冒泡
<style>
        .father {
            width: 600px;
            height: 600px;
            border: 3px solid red;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: #ff534c;
        }
    </style>
</head>
<body>
    <div class="father">
        这是father
        <div class="son">这是儿子</div>
    </div>
    <script>
        // 获取到元素
        var father= document.getElementsByClassName('father')[0];
        var son = document.getElementsByClassName('son')[0];
        // 事件的绑定
        // 从内向外触发事件
        // 并不是所有的事件都能冒泡
        
        father.onclick = function(){
            console.log('father')
        }
        son.onclick = function(e){
            console.log('e',e)
            console.log('son')
            // 阻止时间传播 e.stopPropagation()
            e.stopPropagation()
        }
        // 事件从触发到完成响应一般分为3个阶段:捕获阶段,目标阶段,和冒泡阶段
    </script>

四. 事件委托

事件委托: 原本绑定在子元素身上的事件,现在绑定到父元素上,利用事件冒泡的传递的过程,来触发当前的事件,这样的做法叫做事件委托,也叫事件代理。

 <ul id="ulList">
        <li>这是第一个li</li>
        <li>这是第二个li</li>
        <li>这是第三个li</li>
    </ul>
    <script>
        // var lis = document.getElementsByTagName('li');
        // for(var i=0;i<lis.length;i++){
        //     lis[i].onclick = function(){
        //         console.log('每一个li',this)
        //     }
        // }
        // 事件委托:原本绑定在子元素上面的事件,现在绑定到父元素上面了
        // 事件委托又叫事件代理--提升代码的执行效率
        var ulList = document.getElementById('ulList');
        ulList.onclick = function(e){
            console.log('e',e.target)
        }
    </script>

五. 阻止事件传播

使用事件对象的 stopPropagation() 方法停止事件传播。

六. 阻止默认事件

方法一:使用事件对象的 preventDefault() 方法阻止默认行为。

方法二:在事件的处理函数中返回 false。

七.javascript中常用坐标属性

7.1 MouseEvent属性

由鼠标事件(MouseEvent)可以发现: 其中包含了许多的坐标,且每个坐标的含义都不一样。下面我们来挨个介绍常用的坐标,以及它们的含义。

  • 1.clientX、clientY 点击位置距离当前body可视区域的x,y坐标

  • 2.pageX、pageY(不会随着滚动条的滚动而改变) 对于整个页面来说,包括了被卷去的body部分的长度,相对文档区域左上角距离

  • 3.screenX、screenY 点击位置距离当前电脑屏幕的x,y坐标

  • 4.offsetX、offsetY 鼠标相对于事件源元素的x,y坐标(光标相对于自身盒子内侧的坐标,不包括边框)

<style>
        *{
            margin: 0;
            padding: 0;

        }
        .box{
            width: 200px;
            height: 4000px;
            border: 20px solid red;
            padding: 20px;
            margin: 50px;

        }
    </style>
</head>
<body>
    <div class="box">

    </div>
    <script>
        var box = document.getElementsByClassName('box')[0];
        box.onclick = function(e){
            // clientX: 鼠标相对于浏览器可视区的x坐标 浏览器的左上角为坐标原点
            // clientY: 鼠标相对于浏览器可视区的y坐标浏览器的左上角为坐标原点
            // console.log('ex',e.clientX);
            // console.log('ey',e.clientY);
            // pageX、pageY
            // 对于整个页面来说,包括了被卷去的body部分的长度,相对文档区域左上角距离
            // console.log('ex',e.pageX);
            // console.log('eY',e.pageY);
            // screenX、screenY
            // 点击位置距离当前电脑屏幕的x,y坐标
            // console.log('screenX',e.screenX);
            // console.log('screenY',e.screenY);
            // offsetX、offsetY
            // 鼠标相对于事件源元素的x,y坐标(光标相对于自身盒子内侧的坐标,不包括边框)  
            console.log('offsetX',e.offsetX)
            console.log('offsetY',e.offsetY)

            
        }
    </script>
//小盒子随鼠标移动的一个小案例
<style>
        .box{
            width: 200px;
            height: 200px;
            background-color: red;
            position: fixed;

        }
    </style>
</head>
<body>
    <div class="box">

    </div>
    <script>
        // 获取元素
        var box = document.getElementsByClassName('box')[0];
        // 鼠标移动事件
        document.onmousemove = function(e){
            console.log('e',e)
            box.style.left = e.clientX +'px'
            box.style.top = e.clientY +'px'
        }
    </script>
7.2 元素(HTMLElement)的offset属性(重点)

offset这个属性,可以说是非常有用的,顾名思义,offset翻译过来就是偏移量,从名字就可以看出它的具体意义了。也即是元素相当于父元素的偏移量。

  • 1.offsetTop: 元素相对父元素上边的偏移。(只读)

  • 2.offsetLeft: 元素相对父元素左边的偏移。(只读)

  • 3.offsetWidth: 自身包括padding 、 边框、内容区的宽度。

  • 4.offsetHeight: 自身包括padding、边框、内容区的高度。

  • 5.offsetParent: 作为偏移参照点的父级元素。

offsetLeft 和left 的区别

如果父div的position定义为relative,子div的position定义为absolute,那么子div的style.left的值是相对于父div的值,这同offsetLeft是相同的。

区别在于:

  • style.left 返回的是字符串,如28px,offsetLeft返回的是数值28,如果需要对取得的值进行计算, 还用offsetLeft比较方便。

  • style.left是读写的,offsetLeft是只读的,所以要改变div的位置,只能修改style.left。

<style>
        .father{
            width: 900px;
            height: 600px;
            border: 3px solid red;
            margin: 50px 0;
            position: relative;
        }
        .son{
            width: 100px;
            height: 100px;
            border: 20px solid blue;
            position: absolute;
            left: 20px;
            top: 40px;
        }

    </style>
</head>
<body>
    <div class="father">
       father
       <div class="son"></div> 
    </div>
    <script>
        var son = document.getElementsByClassName('son')[0];
        // 子绝父相 获取到的是距离父元素左上角的位置
        // console.log(son.offsetLeft);//可读就意味着只能获取不能设置值
        // console.log(son.offsetTop);
//         - 3.offsetWidth: 自身包括padding 、 边框、内容区的宽度。
// - 4.offsetHeight: 自身包括padding、边框、内容区的高度。
        console.log(son.offsetWidth);
        console.log(son.offsetHeight);
        // 作为偏移参照点的父级元素。
        console.log(son.offsetParent);
    </script>
7.3 元素的client属性
  • clientHeight(clientWidth):内容可视区域的高度/宽度,也就是说页面浏览器中可以看到内容的这个区域的高度(不含边框,也不包含滚动条等边线)

  • clientLeft,clientTop: 这两个返回的是元素周围边框的厚度,可以理解为边框的长度,如果不指定一个边框或者不定位改元素,他的值就是0.

<style>
        .box{
            width: 200px;
            height: 200px;
            padding: 10px;
            /* background-color: red; */
            border-left: 20px solid #000;
            border-top: 20px solid #ff534c;
        }
    </style>
</head>
<body>
    <div class="box">

    </div>
    <script>
        var box = document.getElementsByClassName('box')[0];
        console.log('box.offsetWidth',box.offsetWidth);
        console.log('box.offsetHeight',box.offsetHeight);
        // 不含边框,也不包含滚动条等边线
        console.log('box.clientWidth',box.clientWidth);
        console.log('box.clientHeight',box.clientHeight);
        console.log('box.clentLeft',box.clientLeft);
        console.log('box.clientTop',box.clientTop);
    </script>
7.4 元素的scroll 属性

scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

<style>
        .box{
            width: 200px;
            height: 300px;
            border: 3px solid red;   
            overflow: auto;
        }
    </style>
</head>
<body>
    <div class="box">
   足够多的内容
    </div>
    <script>
        var box = document.querySelector('.box');
        box.onclick = function(){
            //scrollTop 被卷进去的距离 垂直方法
            // console.log(box.scrollTop);
            // 获取内容的宽度 不包含滚动条
            console.log(box.scrollWidth)
            // 内容的高度 不包含滚动条
            console.log(box.scrollHeight)

        }
    </script>
7.5 window属性
  • window.pageXOffset 获取当前页面相对于窗口显示区左上角的 X 位置。(页面滚动的距离)

  • window.pageYOffset 获取当前页面相对于窗口显示区左上角的 Y 位置。(只读)

  • window.screenLeft 可以获得浏览器距屏幕左上角的左边距

  • window.screenTop 可以获得浏览器距屏幕左上角的上边距

  • window.screen.width记录了客户端显示屏的宽

  • window.screen.height记录了客户端显示屏的高

  • window.innerWidth:返回以像素为单位的窗口的内部宽度。如果垂直滚动条存在,则这个属性将包括它的宽度。(只读)

  • window.innerHeight:返回以像素为单位的窗口的内部高度。如果有水平滚动条,也包括滚动条高度。(只读)

<style>
        .box {
            width: 300px;
            height: 3000px;
            border: 2px solid red;
        }
    </style>
</head>

<body>
    <div class="box">

    </div>
    <script>
        //         - window.pageXOffset 获取当前页面相对于窗口显示区左上角的 X 位置。(页面滚动的距离)
        // - window.pageYOffset 获取当前页面相对于窗口显示区左上角的 Y 位置。(只读)
        // - window.screenLeft 可以获得浏览器距屏幕左上角的左边距   
        // - window.screenTop 可以获得浏览器距屏幕左上角的上边距
        // - window.screen.width记录了客户端显示屏的宽
        // - window.screen.height记录了客户端显示屏的高
        var box = document.getElementsByClassName('box')[0];
        box.onclick = function () {
            console.log(window.pageXOffset);
            console.log(window.pageYOffset);//重点
            console.log(window.screenLeft);
            console.log(window.screenTop);
            console.log('屏幕W', window.screen.width);
            console.log('屏幕H', window.screen.height);
            // - window.innerWidth:返回以像素为单位的窗口的内部宽度。如果垂直滚动条存在,则这个属性将包括它的宽度。(只读)
            // - window.innerHeight:返回以像素为单位的窗口的内部高度。如果有水平滚动条,也包括滚动条高度。(只读)
            console.log('窗口W', window.innerWidth);
            console.log('窗口H', window.innerHeight);
        }

    </script>

 

​​​​​​​

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值