DOM——事件高级(注册事件,事件冒泡,事件代理)

1.注册事件

1.1 传统注册事件

以on开头, onclick,具有唯一性,同一个元素,同一个事件只能设置一个处理函数,后注册的处理函数会覆盖前面注册的处理函数

<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    //被覆盖
    btn.onclick = function () {
      alert(1);
    };
    btn.onclick = function () {
      alert('ggg');//ggg
    }
  </script>
</body>

1.2 方法监听注册方式 addEventListener()

W3C推荐,IE9之前不支持,用addEvent()代替,同一元素,同一事件可以注册多个监听器,按照注册顺序依次执行

eventTarget.addEventListener(type,listener[, useCapture])

1.type    事件类型字符串,比如click,mouseover,注意不带on
2.listener    事件处理函数,事件发生时,会调用该监听函数
3.useCapture    可选参数,布尔值,默认false
<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    btn.addEventListener('click', function () {
      alert('ggxjsb');
    })
    btn.addEventListener('click', function () {
      alert('ggxededjsb');
    })
  </script>
</body>

1.3 addEvent事件监听(非标准,不推荐,IE8支持)

eventTarget.attachEvent(eventNameWithOn,callback)

1.eventNameWithOn:事件类型字符串,比如onclick,onmouseover,

2.callback:事件处理函数
<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    btn.attachEvent('onclick', function () {
      alert('hvn');
    })
  </script>
</body>

2.删除事件

2.1 删除事件的方式

传统注册方式

eventTarget.onclick=null
<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    btn.onclick = function () {
      alert('jio');
      //解绑事件
      btn.onclick = null;
    }
  </script>
</body>

方法监听注册方式(注意回调函数单独写)

eventTarget.removeEventListener(type,listener[, useCapture])
<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    btn.addEventListener('click', fn);
    function fn() {
      alert('jzioan');
      btn.removeEventListener('click', fn)
    }
  </script>
</body>

3.DOM事件流

事件流描述的时从页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流

DOM事件流分为三个阶段

(1)捕获阶段

(2)当前目标阶段

(3)冒泡阶段

事件冒泡:IE最早提出,时间开始时有最具体的元素接收,然后主机向上传播到DOM最顶层节点的规程

事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体元素接收的过程

注意

(1)JS代码中只能执行捕获或者冒泡其中的一个阶段

(2)onclick和attachEvent只能得到冒泡阶段

(3)addEventListener(type,listener[,useCapture]) 第三个参数是true,表示在事件捕获阶段斯调用事件处理程序,如果是false,表示事件冒泡阶段调用事件处理程序

(4)实际开发中更关注事件冒泡

(5)有些事件没有冒泡,onblur,onfocus,onmouseenter,onmouseleave

代码验证

 <style>
    .father {
      width: 600px;
      height: 600px;
      background-color: green;
    }

    .son {
      width: 400px;
      height: 400px;
      background-color: orange;
    }

    .a {
      width: 200px;
      height: 200px;
      background-color: grey;
    }
  </style>
<body>
  <div class="father">
    father
    <div class="son">
      son
      <div class="a">a</div>
    </div>
  </div>
  <script>
    // 事件捕获阶段,从高层向底层,document -> html -> body -> father -> son -> a
    // 以下代码点击之后的弹出顺序:.father ->.son -> a
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    var a = document.querySelector('.a');
    a.addEventListener('click', function () {
      alert('a');
    }, true);
    son.addEventListener('click', function () {
      alert('.son');
    }, true);
    father.addEventListener('click', function () {
      alert('.father');
    }, true);
    // 事件冒泡阶段,从底层到高层,a -> son -> father -> body -> html -> document
    // 以下代码弹出顺序 a ->.son ->.father
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    var a = document.querySelector('.a');
    a.addEventListener('click', function () {
      alert('a');
    }, false);
    son.addEventListener('click', function () {
      alert('.son');
    }, false);
    father.addEventListener('click', function () {
      alert('.father');
    }, false);


  </script>
</body>

4.事件对象

  4.1 什么是事件对象

//1.event就是一个事件对象,写在侦听函数的小括号里,当形参看待

  //2.事件对象有了事件才会存在,他是系统自动创建的,不需要传参

  //3.事件对象是时间的一系列相关数据的集合

  //4.事件对象可以自己命名,例如 function(e)

  //5.事件对象有兼容性问题,ie678用window.event

//6.其中有很多属性和方法

<body>
  <div>123</div>
  <script>
    var div = document.querySelector('div');
    div.onmouseover = function (event) {
      console.log(event);
    }
  //1.event就是一个事件对象,写在侦听函数的小括号里,当形参看待
  //2.事件对象有了时间才会存在,他是系统自动创建的,不需要传参
  //3.事件对象是时间的一系列相关数据的集合
  //4.事件对象可以自己命名,例如 function(e)
  //5.事件对象有兼容性问题,ie678用window.event

  </script>
</body>

4.2 事件对象常见属性和方法

方法说明
e.target返回触发事件的对象,标准
e.srcElement

返回触发事件的对象,非标准,ie678

e.type返回事件类型,比如click,mouseover
e.cancelBubble阻止冒泡,ie6-8用
e.returnValue阻值默认事件,比如不让连接跳转,ie6-8用
e.preventDefault()阻止默认事件,标准
e.stopPropagation()阻止冒泡,标准

4.2.1 返回触发事件的对象

 区分e.target和this

<body>
  <div>123</div>
  <ul>
    <li>111</li>
    <li>222</li>
    <li>333</li>
  </ul>

  <script>
    var div = document.querySelector('div');
    //注意:e.target返回的是触发事件的对象,this返回的是绑定事件的对象
    div.onclick = function (e) {
      console.log(e.target);//<div>123</div>
      console.log(this);//<div>123</div>
    }

    var ul = document.querySelector('ul');
    ul.addEventListener('click', function (e) {
      //在这里,ul绑定了事件,因此,this指向ul
      console.log(this);//  <ul></ul>
      //点击li,是li触发了事件,e.target就返回li
      console.log(e.target)//<li></li>
      //e.currentTarget与this相似
      console.log(e.currentTarget);//<ul></ul>
    })
  </script>
</body>

4.2.2 获取事件类型和阻止默认行为

<body>
  <div>124</div>
  <a href="http://www.baidu.com">百度</a>
  <form action="http://www.baidu.com">
    <input type="submit" value="提交" name="sub">
  </form>
  <script>
    var div = document.querySelector('div');
    div.addEventListener('click', fn);
    function fn(e) {
      console.log(e.type)//click
    }
    //阻止默认行为
    var a = document.querySelector('a');
    a.addEventListener('click', function (e) {
      e.preventDefault();
    })
    //传统方式
    a.onclick = function (e) {
      //普通浏览器
      e.preventDefault();
      //低版本浏览器ie6-8
      e.returnValue;
      //return false也能阻止默认行为,没有兼容性问题,但是后面的代码也不执行,也仅限于传统方式
      return false;
    }
  </script>
</body>

4.2.3 阻止冒泡

结果只弹出a->son

<body>
  <div class="father">
    <div class="son">
      <div class="a"></div>
    </div>
  </div>
  <script>
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    var a = document.querySelector('.a');
    father.addEventListener('click', function () {
      alert('father');

    });
    son.addEventListener('click', function () {
      alert('son');
    })
    a.addEventListener('click', function (e) {
      alert('a')
      //阻止冒泡,想阻止谁就给谁加
      e.stopPropagation();
    });
  </script>
</body>

5.事件委托(代理,委托)

原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

<body>
  <ul>
    <li>点我事件代理</li>
    <li>点我事件代理</li>
    <li>点我事件代理</li>
    <li>点我事件代理</li>
    <li>点我事件代理</li>
    <li>点我事件代理</li>
  </ul>
  <script>
    //事件代理核心:给父节点添加侦听器,利用事件冒泡影响每一个子节点
    var ul = document.querySelector('ul');
    ul.addEventListener('click', function (e) {
      alert('点我事件代理')
      //e.target可以获得当前点击的对象
      for (var i = 0; i < ul.children.length; i++) {
        ul.children[i].style.backgroundColor = '';
      }
      e.target.style.backgroundColor = 'green'
    })
  </script>
</body>

6.常用鼠标事件

事件触发条件
onclick鼠标左键点击
onmouseover鼠标经过离开
onmouseout鼠标离开触发
onfocus获得鼠标焦点
onblur失去鼠标焦点
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

6.1禁止鼠标右键菜单,主要控制应该合适显示上下文菜单,用于取消程序默认的上下文菜单

contextmenu

6.2 禁止鼠标选中

selectstart
<body>
  不能复制这句话
  <script>
    //contextmenu禁止右键
    document.addEventListener('contextmenu', function (e) {
      e.preventDefault()
    });
    document.addEventListener('selectstart', function (e) {
      e.preventDefault()
    })
  </script>
</body>

6.3鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合,目前主要用到MouseEvent和KeyboardEvent

鼠标事件对象说明
e.clientY返回鼠标相对于窗口可视区的X坐标
e.clientY返回鼠标相对于窗口可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标,ie9支持
e.pageY返回鼠标相对于文档页面的Y坐标,ie9支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的Y坐标
<body>
  <script>
    document.addEventListener('mousemove', function (e) {
      console.log(e);
      //1.Client鼠标在可视区的X和Y坐标
      console.log(e.clientX);
      console.log(e.clientY);
      //2.page鼠标在页面文档的X和Y坐标
      console.log(e.pageX);
      console.log(e.pageY);
    })
  </script>
</body>

鼠标跟随案例

<body>
  <img src="https://img1.baidu.com/it/u=10729751,2293405087&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500" alt="">
  <script>
    var pic = document.querySelector('img')
    document.addEventListener('mousemove', function (e) {
      //获取鼠标坐标
      var x = e.pageX;
      var y = e.pageY;
      //将鼠标的坐标赋值给图片,这里一定记得加px
      pic.style.left = x - 75 + 'px';
      pic.style.top = y - 75 + 'px';
    })
  </script>
</body>

7.常用键盘事件

事件说明
onkeyup键盘按键松开时触发
onkeydown键盘按键被按下时触发
onkeypress某个键盘按键被按下时触发,不识别功能键
<body>
  <script>
    document.onkeyup = function () {
      alert('键盘弹起')
    }
    document.addEventListener('keydown', function () {
      alert('按下键盘')
    })
    document.addEventListener('keypress', function () {
      alert('按下键')
    })
  </script>
</body>

事件执行顺序:keydown-->keypress-->keyup

keyCode判断按下哪个键,返回ASCII码

keyup和keydown事件不区分字母大小写,a和A获得的都是65

keypress区分大小写

<body>
  <script>
    document.addEventListener('keyup', function (e) {
      console.log(e);
      //获取按下的键的ASCII码
      console.log(e.keyCode);//68
    })
    document.addEventListener('keypress', function (e) {
      console.log(e);
      console.log(e.keyCode);
    })
  </script>
</body>

8.模仿京东按键输入内容案例

//检测用户是否按下了s键,如果按下,就把光标定位到搜索框里面,使用keyCode判断用户按下的是否是s键,使用js的focus()方法获得搜索框的焦点

<body>
  <input type="text">
  <script>
    var search = document.querySelector('input');
//若用keydown,还会将s键输入内容框
    document.addEventListener('keyup', function (e) {
      if (e.keyCode === 83) {
        search.focus();
      }
    })
  </script>

</body>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值