dom级别和对应事件级别;事件流

用惯了插件,脚手架越发想了解最底层或是最初是怎么控制dom交互的,之前也看过大多不理解,要么就是硬记...

今天按照自己理解做了个笔记方便日后随用随取

一 DOM事件流

事件

  是文档或浏览器窗口中发生的一些特定的交互瞬间JavaScript与HTML之间的交互是通过事件实现的。

事件流

  是事件在目标元素和祖先元素间的触发顺序, 

  在早期,微软和网景实现了相反的事件流, 网景主张捕获方式, 微软主张冒泡方式:

   捕获 - Capture - 事件由最顶层逐级向下传播, 直至到达目标元素.

   冒泡 - Bubble - 从下往上. 事件由第一个被触发的元素接收, 然后逐级向上传播.

  最 w3c 采用折中的方式, 规定先捕获再冒泡平息了战火. 如此一个事件就被分成了三个阶段(是的, 不光是捕获和冒泡):

  捕获阶段 - The capture phase - 事件从最顶层元素 window 一直传递到目标元素的父元素.

  目标阶段 - The target phase - 事件到达目标元素. 如果事件指定不冒泡. 那就会在这里中止.

  冒泡阶段 - The bubble phase - 事件从目标元素父元素向上逐级传递直到最顶层元素 window.

   DOM2 中, 事件监听机制提供了一个参数来决定事件是在捕获阶段生效还是在冒泡阶段生效

  EventTarget.addEventListener() 方法将指定的监听器注册到目标元素上, 当该对象触发指定的事件时, 指定的回调函数就会被执行.

语法

target.addEventListener(type, listener, options);

  type: 表示监听事件类型的字符串. 事件列表.

    listener: 当所监听的事件类型触发时的回调. 会接收到一个事件通知对象.

    options: 可选. 可用的选项如下:

      capture: Boolean, 如果是 true, 表示 listener 会在捕获阶段触发. 默认是 false,冒泡.

      once: Boolean, 如果是 true, 表示 listener 在添加之后最多只调用一次.

      passive: Boolean,如果是true, 表示 listener 永远不会调用 preventDefault(). 如果 listener 仍然调用了这个函数, 客户端将会忽略它并抛出一个控制台警告.

注意:为什么要单独区分一个目标阶段
对于目标元素上的事件监听器来说, 事件会处于目标阶段, 而不是冒泡阶段或者捕获阶段. 在目标阶段的事件会触发该元素上的所有监听器, 而不在乎这个监听器到底在注册时 useCapture 是 true 还是 false.
 

万维网联盟(w3c)World Wide Web Consortium创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构.

二 DOM级别

文档对象模型 (DOM) 是一个平台,一个中立于语言的应用程序编程接口 (API),允许程序访问并更改文档的内容、结构和样式。

DOM 级别 0,不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 Microsoft Internet Explorer 3.0 中的等价功能性的一种定义。

  DOM 发展过程中的关键角色有:ArborText、IBM、Inso EPS、JavaSoft、Microsoft、Netscape、Novell、the Object Management Group、SoftQuad、Sun Microsystems 以及 Texcel。W3C 的 DOM 级别 1 建立于此功能性之上。

DOM 级别 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。DOM 级别 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。

DOM 级别 2 DOM 级别 1 添加了样式表对象模型,并定义了操作附于文档之上的样式信息的功能性。DOM 级别 2 同时还定义了一个事件模型,并提供了对 XML 命名空间的支持

DOM 级别 3 DOM Level 3 规定了内容模型 (DTD 和 Schemas) 和文档验证。同时规定了文档加载和保存、文档查看、文档格式化和关键事件.

对应的 DOM 事件

Html 事件处理程序(最早):

<button type="button" onclick="fn" id="btn">

点我试试

</button>

<script>

    function fn() {

        alert('Hello World');

    }

</script>

 

缺点就是HTMLJS强耦合,当我们一旦需要修改函数名就得修改两个地方

 

 

DOM0级事件处理

  通过JS获取到了这个id的按钮,并将一个函数赋值给了一个事件处理属性onclick;解绑事件

 

缺点在于一个处理程序无法同时绑定多个处理函数

<button id="btn" type="button"></button>

<script>

    var btn = document.getElementById('btn');

    btn.onclick = function() {

        alert('Hello World');

    }

    // btn.onclick = null; 解绑事件

</script>

DOM2级事件

  定义了addEventListener和removeEventListener用来绑定和解绑事件,方法中含3个参数:绑定的事件处理属性名称(不包含on)、处理函数是否在捕获时执行事件处理函

IE8级以下版本不支持,需要用attachEvent和detachEvent来实现

<button id="btn" type="button"></button>

<script>

    var btn = document.getElementById('btn');

    function showFn() { alert('Hello World'); }

    btn.addEventListener('click', showFn, false);

  // btn.removeEventListener('click', showFn, false); 解绑事件

</script>(IE8级以下版本只支持冒泡型事件)

btn.attachEvent('onclick', showFn); // 绑定事件

btn.detachEvent('onclick', showFn); //解绑事件

DOM3级事件 在DOM2级事件的基础上添加了更多的事件类型,全部类型如下:

  UI事件,当用户与页面上的元素交互时触发,如:load、scroll

  焦点事件,当元素获得或失去焦点时触发,如:blur、focus

  鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup

  滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel

  文本事件,当在文档中输入文本时触发,如:textInput

  键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress

  合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart

  变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified

  同时DOM3级事件也允许使用者自定义一些事件。

 获取DOM节点

1.通过元素类型的方法来获取DOM节点:

document.getElementById(“id”)                              id名,较少使用,一般只用在顶级层

document.getElementsByTagName(“p”)[i]

标签名

document.getElementsByClassName(“class”)[i]

类名,常用

document.getElementsByName(“name”)[i]

name属性值,一般不用

document.querySelector(“.class”)(第一个)

css选择符模式,与之匹配的第一个元素,如果没找到,则返回null

document.querySelectorAll(“.class”)[i]

结果为一个类数组

注意:document节点下调用这些方法,当然也可以在其他的元素节点下调用;最后两个为静态的,不是实时的,保存的是当时的状态,是一个副本.

2.根据关系树来选择(遍历节点树/元素节点数)

  ① 节点(DOM文档对象模型):

可以将任何HTML、XML文档描绘成一个多层次的节点树。所有的页面都表现为以一个特定节点为根节点的树形结构html文档中根节点为document节点。

所有节点都有nodeType属性,通过nodeType属性可以来判断节点的类型。

节点主要有以下几种类型:

  Element类型(元素节点):nodeType值为 1

  Text类型(文本节点):值为 3

  Comment类型(注释节点):值为 8

  Document类型(document节点):值为 9;其规定的一些常用的属性有

  document.body    document.head  分别为HTML中的 <body><head>

  document.documentElement为<html>标签

节点都有hasChildNodes()方法判断有无子节点,有一个或多个子节点时返回true

通过一些属性可以来遍历节点树:

parentNode

获取所选节点的父节点,最顶层的节点为#document

firstChild

获取所选节点的第一个子节点

childNodes

获取所选节点的子节点们

lastChild

获取所选节点的最后一个子节点

nextSibling

获取所选节点的后一个兄弟节点 列表中最后一个节点的nextSibling属性值为null

previousSibling

获取所选节点的前一兄弟节点 列表中第一个节点的previousSibling属性值为null

② 由于文档中的节点类型较多,遍历子节点的结果很多时候并不能得到我们想要的结果,使用遍历元素节点则很方便

parentElement //返回当前元素的父元素节点(IE9以下不兼容)

children  // 返回当前元素的所有子节点

firstElementChild //返回的是第一个元素子节点(IE9以下不兼容)

lastElementChild  //返回的是最后一个元素子节点(IE9以下不兼容)

nextElementSibling  //返回的是后一个兄弟元素节点(IE9以下不兼容)

previousElementSibling  //返回的是前一个兄弟元素节点(IE9以下不兼容

 

posted @ 2020-03-13 11:03  HappyHacking!  阅读(970)  评论(0编辑  收藏  举报