JavaScript事件

多个事件的绑定

  • DOM对象.addEventListener(类型,事件处理函数,是否冒泡)

    类型: 表示监听事件类型的字符串。

    事件处理函数: 当这个事件处理的时候的操作

    是否支持冒泡: 当设为true 时,沿着DOM树向上冒泡的事件,不会触发事件。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。

    注意:有兼容性问题,在IE9以后的版本才支持,老版本浏览器只支持attachEvent().

  • DOM对象.attachEvent(‘on’ + 事件名称, 事件处理函数)

    注意:IE9之前用这个

处理兼容性代码

function addEventListener(element, event, fn) {
    //如果没有这个属性默认是undefined
    if(element.addEventListener) { 
        // 默认冒泡
        element.addEventListener(event, fn);
    } else {
        element.attachEvent('on' + event, fn);
    }
}

移除事件

// 第一种方式的移除事件
var btn = document.getElementById('btn');
btn.onclick = function () {
    console.log('hello');
    // 移除事件
    btn.onclick = null;
}

// 第二种方式的移除事件
btn.addEventListener('click', fn, fasle);
// 移除事件,如果想移除事件,那么绑定事件的时候不能使用匿名函数
btn.removeEventListener('click', fn);

function fn () {
    console.log('hello');
}

// 第三种方式的移除事件,attach意思是附加,detach意思是分离
btn.attachEvent('onclick', fn);
// 移除事件,如果想移除事件,那么绑定事件的时候不能使用匿名函数
btn.detachEvent('onclick', fn);

function fn () {
    console.log('hello');
}

处理兼容性代码

function removeEventListener(element, event, fn) {
    //如果没有这个属性默认是undefined
    if(element.removeEventListener) { 
        // 默认冒泡
        element.removeEventListener(event, fn);
    } else {
        element.detachEvent('on' + event, fn);
    }
}

事件冒泡

事件冒泡简介

addEventListener 的第三个参数为false的时候为事件冒泡,当参数为true的时候为事件捕获

事件冒泡:会从最内层一层一层冒到最外层的元素

事件捕获:会从最外层一层一层到最内层元素

事件的三个阶段

1. 捕获阶段
2. 执行当前点击的元素
3. 冒泡阶段

HTML代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>事件冒泡</title>
    <style>
        div{
            padding: 20px;
            background-color: aliceblue;
        }
        #div2{
            background-color: red;
        }
        #div3{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="div1">
        <div id="div2">
            <div id="div3"></div>
        </div>
    </div>
</body>
</html>

JavaScript代码如下

		// 此时为事件冒泡
		var arr = [div1, div2, div3];

        for (var i = 0; i < arr.length; i++) {
            arr[i].addEventListener('click', function () {
                console.log(this.id);
            }, false);
        }
        // 输出结果 : div3 div2 div1
	// 此时为事件捕获
	var arr = [div1, div2, div3];

    for (var i = 0; i < arr.length; i++) {
        arr[i].addEventListener('click', function () {
            console.log(this.id);
        }, true);
    }
    // 输出结果 : div1 div2 div3

事件冒泡注意的地方

onlick和attachEvent这两个绑定的方式,不能设置事件捕获,只能用默认的事件冒泡。

事件冒泡的作用(事件委托)

  • e.target :是真正触发事件的对象。
  • e.currentTarget:代表this

案例

<!-- 单击li背景色变红 -->
<ul id="ul">
        <li>001</li>
        <li>002</li>
        <li>003</li>
        <li>004</li>
</ul>

ul.addEventListener('click', function (e) {
            e.target.style.background = 'red';
		}, false);

事件对象

事件对象简介

通过事件对象,可以获取到事件发生的时候喝事件相关的一些数据

var btn = document.getElementById('btn');
btn.onclick = function (e) {
    // DOM标准中,是给事件处理函数一个参数
    // e就是事件对象
    // 在老版本的IE中获取事件对象的方式 window.event
    e = e || windown.event; // 处理浏览器兼容问题
}

事件对象的属性和方法

1. e.eventPhase(了解)

  • 1捕获阶段
  • 2目标阶段
  • 3冒泡阶段

2. e.target

  • 获取真正触发事件的对象浏览器兼容问题,在老版本IE中指的是srcElement
  • 处理兼容:var target = target || srcElement

3. e.currentTarget

  • 指this(事件处理函数所属的对象)

**4.e.type **

  • 获取事件名称

    //优势,可以根据不同的事件名称做不同的事情,节省代码。
    	box.onclick = fn;
        box.onmouseover = fn;
        box.onmouseout = fn;
    
        function fn(e) {
          e = e || window.event;
          switch (e.type) {
            case 'click': 
              console.log('点击box');
              break;
            case 'mouseover': 
              console.log('鼠标经过box');
              break;
            case 'mouseout': 
              console.log('鼠标离开box');
              break;
          }
        }
    

5. e.clientX 、e.clientY

  • 获取的鼠标在浏览器可视区域的坐标

    注意:是相对于可视区的坐标值,原点在可视区的左上角

6. e.pageX 、e.pageY(有兼容性问题,IE9之后支持)

  • 相对于整个页面的坐标

    var img = document.getElementsByTagName('img');
    document.onmousemove = function (e) {
        var e = e || window.event;
        // 当有滚动条的时候,必须用pageX(相对于页面的坐标值)
        img[0].style.left = e.pageX + 'px';
        img[0].style.top = e.pageY + 'px';
    }
    

    处理兼容性问题:pageX = clientX + 页面滚动出去的距离

    function getPage(e) {
        var pageX = e.pageX || e.clientX + getScroll().scrollLeft;
        var pageY = e.pageX || e.clientY + getScroll().scrollTop;
        return {
            pageX:pageX,
            pageY:pageY
        }
    }
    
  • 页面滚动出去的距离

    • 谷歌浏览器

      • document.body.scrollLeft 横向距离
      • document.body.scrollTop 纵向距离
    • 有些浏览器

      • document.documentElement.scrollLeft 横向距离

      • document.documentElement.scrollTop 纵向距离

        document.documentElement获取的是html

    • 处理滚动距离的兼容性

      function getScroll() {
          // 如果获取不到那么他的值为0,这样就可以用 ||运算符来进行处理兼容
          var scrollLeft = document.body.scrollLeft  || document.documentElement.scrollLeft;
          var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
      }
      
  • 例题(获取盒子在页面上的位置)

    • offsetLeft:横向偏移
    • offsetTop:纵向偏移
      在这里插入图片描述

7. e.preventDefault()方法(有兼容性问题)

  • 取消默认行为

  • 处理兼容性问题

    if (e.preventDefault) { // 如果她不存在返回undefined
        e.preventDefault();
    } else {
        e.returnValue = false; // ie老版本中处理默认行为
    }
    
    // 推荐使用return false来处理默认行为
    

8. e.stopPropagation()方法 (有兼容性问题)

  • 阻止冒泡

  • 处理兼容性问题

    if (e.stopPropagation) { // 如果她不存在返回undefined
        e.stopPropagation();
    } else {
        e.cancelBubble = true; // ie老版本中处理默认行为
    }
    
    

9. e.keyCode

  • 获取键盘按键的编码

    A:65

    a:97

    // 键盘事件
    // keydown 键盘按下的时候
    // keyup   键盘弹起的时候
    // keydown 和 keyup的区别  keydown的时候我们所按的键还没有落入文本框
    // keyup键盘弹起的时候按的键已经落入文本框
    var txt = document.getElementById('txt');
    txt.onkeydown = function (e) {
    // 判断当前用户按下的键是否是数字
    e = e || window.event;
    // 如果e.keyCode 的值在 48-57 是数字
    // e.keyCode  键盘码
    // console.log(e.keyCode);
    // 按下后退键  8,删除一个字符 
    if ((e.keyCode < 48 || e.keyCode > 57) && e.keyCode !== 8) {
        // 非数字
        // 取消默认行为
        e.preventDefault();
        // return false;  如果用return false 取消默认行为那么后续的代码将不会再执行
    }
        }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值