Skip to content

事件

http://www.runoob.com/jsref/dom-obj-event.html

事件的传播

  • 第一阶段。从 window 对象传导到目标节点 (上层传递到下层),捕获阶段 capture
  • 第二阶段。在目标节点触发,目标阶段 target
  • 第三阶段。目标节点传导回 window 对象 (底层传回下层),冒泡阶段 bubbling

事件代理

  • 事件在冒泡阶段,始终会传导到父级别,所以,在父级别定义监听函数即可。此行为叫事件的代理
js
const ul = document.querySelector('ul');
ul.addEventListener('click', (event) => {
  if (event.target.tagName.toLowerCase() === 'li') {
    console.info('这就是li');
  }
});
  • 如需要以上代码不需要传播到 window,则可以使用 stopPropagation 方法阻止传播
    • stopPropagation 方法,阻止继续向下传播
    • 事件冒泡到 p,不再继续向上冒泡
js
p.addEventListener(
  'click',
  () => {
    if (event.target.tagName.toLowerCase() === 'li') {
      console.info('这就是li');
      event.stopPropagation();
    }
  },
  true
);

鼠标

事件描述例子
onclickdocument.body.onclick=function(){}
oncontextmenu对内容右键,firefox 支持 contentmenu
onmousedown
onmouseenter
onmouseleave
onmousemove
onmouseout
onmouseup

键盘

事件描述例子
onkeydown
onkeypress
onkeyup

框架/对象事件

事件描述例子
onabort
onbeforeload
onerror图片 src 加载错误,常用
onhashchange
onload
onpageshow一打开页面就出现,一般在 body
onpagehide用户离开网页时触发
onresize
onscroll
onunloadbody frameset

表单事件

事件描述例子
onblur
onchange
onfocus
onfocusin
onfocusout
oninput
onreset
onsearchinput="search"
onselect选取文档
onsubmit

剪切板

事件描述例子
oncopy
oncut
onpaste

打印事件

属性描述例子
onafterprint
obbeforeprint

拖动事件

事件描述例子
ondrag
ondraged
ondragenter
ondragleave
ondragover
ondragstart
ondrop

多媒体 (Media) 事件

事件描述例子
onabort
oncanplay
oncanplaythrough
ondurationchange
onemptied
onended
onerror
onloadeddata
onloadedmetadata
onloadstart
onpause
onplay
onplaying
onprogress
onratechange
onseeked
onstalled
onsuspend
ontimeupdate
onvolumechange
onwaiting

动画事件

事件描述例子
animationed
animationteration重复播放
animationstart

过渡事件

事件描述例子
transitionendcss 过渡后触发

其他事件

事件描述例子
onmeesagewebsocket、 web worker、 event source 、frame
onmousewheel->onwheel
ononline
onoffine
onpopstate
onshow
onstorage
ontoggle<details>
onwheel滚轮

事件对象

| 属性 | 方法 | 静态变量 | 描述 | 例子 | | ------------- | ----------------- | --------------- | ---------------------------------- | ---- | --- | | | | CAPTURING-PHASE | 当前事件阶段为——捕获阶段 | | | | | AT-TARGET | 当前事件时目标阶段,在评估目标事件 | | | | | BUBBLING-PHASE | 当前的事件为——冒泡阶段 | | | bubbles | | | | | | cancelable | | | | | | currentTarget | | | | | | eventPhase | | | | | | target | | | | | | timeStamp | | | | | | type | | | | | | | initEvent() | | | | | | prevenDefault() | | | | | | stopPropation() | | | | | | | | | | |

目标事件对象

属性方法描述例子
addEventListener()允许在目标事件中监听事件(IE8=attachEvent())
dispatchEvent()发送事件到监听器(IE8=fireEvent())
removeEventListener()运行一次注册在事件目标上的监听事件(IE8=detachEvent())

事件监听对象

属性方法描述例子
handleEvent()把任意对象注册为事件处理程序

文档事件对象

属性方法描述例子
createEvent()

鼠标/键盘事件对象

| 属性 | 方法 | 描述 | 例子 | | ------------- | ------------------- | ----------------------------------------------- | ---- | --- | | altKey | | | | | button | | event.button 可以知道是鼠标的那个按键左、右、中 | | | clientX | | | | | clientY | | | | | ctrlKey | | | | | Location | | | | | charCode | | | | | key | | | | | keyCode | | | | | which | | | | | metaKey | | | | | relatedTarget | | | | | screenX | | | | | screenY | | | | | shiftKey | | | | | | initMouseEvent() | 初始化鼠标事件对象 | | | | | initKeyboardEvent() | 初始化键盘事件对象 | | | | | | | | |

焦点事件

判断浏览器是否支持:document.implementation.hasFeature("FocusEvent"),"3.0"

触发次序冒泡事件非冒泡事件描述用例
1focusout失去焦点大多浏览器
2focusint获得焦点,大多浏览器
3blur元素失去焦点,浏览器都支持
4DOMFocusOut失去焦点,Opera 支持
5focus不冒泡,获得焦点触发
6DOMFocusIn冒泡,Opera 支持

郁闷,2018 年 10 月 31 日这一天面试,其实我都有做过,而且自然而然的做过,竟然答不上来,知识体系全部混乱。 这样下去,如果面试一些基础题,我真的可能找不到工作了。 之前也没怎么考虑是事件委托还是代理,自然而然就这样处理事件了。比如之前人工写的轮播在那个智能官网里面的,也没多想了,可谁知道那就是事件委托,哔了狗。

  • 如何去声明和使用事件,以点击事件来说
html
<!--onclick--->
<button>button</button>

<script>
   const btn = document.querySelector('button');
   function changeColorA() {}
   function changeColorB() {}
   function changeColor (){
     btn.style.backgroundColor='#'+Math.floor(Math.random()*16777215).toString(16)
   }
   //方式1
   btn.onclick=changeColor;
   //方式2  以添加addEventListener 函数来完成。具名函数方式
   btn.addEventListener('click',changeColor);

   //方式3 匿名函数来指代一下也是可以的
   btn.addEventListener('click',,function(){
       btn.style.backgroundColor='#'+Math.floor(Math.random()*16777215).toString(16)
   });
   // 移除事件
   btn.removeEventListener('click',changeColor);
  // 添加多个事件

  //  无法实现并存的方式,后者会覆盖前者
   btn.onclick=changeColorA;
   btn.onclick=changeColorB;

   //使用事件监听器注册的话,就可以实现了!!兼容性,addEventListener只支持到IE9
   btn.addEventListener('click',changeColorA);
   btn.addEventListener('click',changeColorB)
   //有些情况,如submit 事件总会使用preventDefault()阻止默认行为
</script>

事件委托/事件代理

  • 什么时候用到?for 循环里面多个点击事件,一次操作就可以完成,减少 DOM 操作次数
  • 原理:利用事件的 冒泡原理 来实现,
html
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>
js
// 很蠢的对每个li 标签都循环做点击事件
window.onload = function () {
  var ul = document.querySelector('ul');
  var li = document.querySelector('li');
  for (var i = 0; i < li.length; i++) {
    li[i].onclick = function () {
      alert(123);
    };
  }
};
  • 事件冒泡

    • 什么是冒泡原理?

    • 什么是事件冒泡?

      事件从最深的节点开始,逐步向上传播事件,div>ul>li>a,给 a 添加事件,事件就会一层一层的往外执行,执行顺序为 a->li->ul->div

    • 机制

      给最外面的 div 加点击事件,这里理解?:它的后代都会被点击到 那么 ul li a 做点击的时候,都会冒泡到最外层 div,也就是会触发。这就是事件委托,委托父级代为执行事件。反正最后都会被冒泡到??

    • 事件冒泡和事件捕获

      • 捕获阶段 父级->子级,向里
        • 检查最外层 html,是否在捕获阶段注册一个 onclick 事件处理程序,如果是,则运行
        • 然后移动到下一个元素,并执行相同操作,直到实际点击的元素
        • 结论是:事件始终从 html 层开始?
        • 顺序:父级——>子级、外到里
      • 冒泡阶段 子级->父级,向外
        • 检查实际点击元素是否在冒泡阶段注册 onclick 事件,如果是则运行
        • 然后移动到直接祖先,然后同上,直至 html 元素
        • 时间处理程序都在冒泡阶段注册 (但可以使用addEventListener(,,true) 在捕获阶段注册
        js
        video.onclick = function (e) {
          e.stopPropagation(); //阻止冒泡链扩大
          video.play(); //播放视频
        };
      • 事件委托 由于冒泡而被允许的概念
        • 通过委托父级,addEventListener 设置在父节点上,将事件监听器气泡的影响每个子节点,而不是每个子节点都设置事件监听器

Powered by veaba