DOM


DOM 重点核心

关于DOM操作,主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。

  • 创建:document.write,inner HTML,createElement
  • 增:appendChild,insertBefore
  • 删:removeChild
  • 改:主要修改dom的元素属性,如内容,属性值,表单的值等
  • 查:
    1、dom 提供的API方法:getElementById、getElementsByTagName
    2、H5 提供的新方法:querySelector、querySelectorAll (推荐)
    3、利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling)
  • 属性操作:主要针对于自定义属性
    1、setAttribute:设置 dom 的属性值
    2、getAttribute:得到 dom 的属性值
    3、removeAttribute 移除属性
  • 事件操作:
    1、给元素注册事件

DOM的节点层级

任何HTML或XML文档都可以用DOM表示为一个由节点构成的层级结构。节点分很多类型,每种类型对应着HTML文档中不同的信息和(或)标记。

每种节点都有自己不同的特性、数据和方法,而且与其他类型有某种关系(相当于把文档树比作家谱)。这些关系构成了层级,让标记可以表示为以一个特定节点为根的树形结构。

以以下的HTML为例:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="./a.css"/>
</head>
<body>
    <p>hello word</p>
    <script src="index.js"></script>
</body>
</html>

其DOM层级结构(DOM树)如下:
在这里插入图片描述
其中,Document 节点表示为每个文档的根节点。在这里,根节点的唯一子节点是 < html > 元素,称为文档元素。

并且 HTML 中的每段标记都可以表示为这个树形结构中的一个节点。元素节点表示 HTML 元素,属性节点表示属性,文档类型节点表示文档类型,注释节点表示注释。

DOM中总共有12种节点类型,这些类型都继承一种基本类型。


节点关系

  • 文档中的所有节点都与其他节点有关系
  • 这种关系可以形容为家族关系,相当于把文档树比作家谱
  • 利用这些关系指针,几乎可以访问到文档树的任何节点
  • 这种便利性是 childNodes 的最大亮点
  • 下图形象的展示了这些关系:
    在这里插入图片描述

Node类型

DOM Level 1 描述了名为 Node 的接口,这个接口是所有 DOM 节点类型都必须实现的。Node 接口在 JavaScript中被实现为 Node 类型。

在 JavaScript 中,所有节点类型都继承 Node 类型,因此所有类型都,共享相同的,基本属性方法

重点关心下面几个属性:

  • nodeType 节点类型

  • nodeName 节点名称

  • nodeValue 节点值

  • childNodes 获取所有的子节点(包括文档类型节点,甚至代码间的换行空白都被当作节点获取)

  • children 获取所有的元素子节点(不包含文档类型节点)

  • firstChild 获取第一个子节点 (不一定是元素节点)
    - lastChild 获取最后一个子节点

  • nextSibling 获取下一个弟弟节点(不一定是元素节点)

  • previousSibling 获取上一个哥哥节点

  • parentNode 获取父亲节点

(注:子节点就是子节点,不包括孙节点)

以及下面几个方法:

  • appendChild 将节点添加为父元素的子节点中的最后一个

  • insertBefore 将节点添加到父元素的子节点中的某一节点的前面

  • replaceChild 替换某一节点

  • removeChild 移除某一节点

  • cloneNode 复制原有的节点,如果传递的值是 true,代表将所有后代元素一起复制;如果传递的是 false,代表只复制当前的元素本身(只有标签没有内容)

  • hasChildNodes 返回一个布尔值,表示当前节点是否包含有子节点

  • normalize

Node 的属性

  • nodeType

    每个节点都有nodeType属性,表示该节点的类型。

    在JS中常用的只有几个,元素节点,文本节点,注释节点,文档类型节点,他们对应的值是:

     节点类型   数字  nodeName的值    nodeValue的值
     元素节点    1    大写的标签名     null
     文本节点    3    #text           文本内容
     注释节点    8    #comment        注释内容
     document   9    #document       null
    

    在标准浏览器中会把空格,Enter 当作文本节点。

  • nodeName和nodeValue

    nodeName 和 nodeValue 保存着有关节点的信息。这两个属性的值完全取决于节点类型。在使用这两个属性前,最好先检测节点类型。

    对于元素节点nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终为null。

	if (someNode.nodeType == 1){
	    testNodeName = someNode.nodeName; 
	    testNodeValue = someNode.nodeValue; 
  • childNodes

    • 每个节点都有一个 childNodes 属性,其中包含一个 NodeList实例。

    • NodeList 是一个类数组对象,用于存储按位置存取的有序节点。

      注:虽然可以使用中括号访问 NodeList 里面的值,而且也有 length 属性,但它不是 Array 的实例。

    • 下面的例子展示如何访问 NodeList 中的节点 — —可以通过item, 也可以通过中括号(推荐)

	var ul = document.querySelector('ul');
	var lis = document.querySelectorAll('li');
	var lis_len = lis.length;
	var first_child = lis[0]; // 推荐使用
	var second_child = lis.item(1);
	var last_child = lis[lis_len - 1];

Document类型

Document类型是 JavaScript 中表示文档节点的类型。document表示整个HTML页面。

定位(查找)元素

查看 Document 上的方法,最常用的就是查找元素的方法。

  • getElementById( )

    在整个文档中,通过元素的ID获取这个元素,如果没有这个ID,则返回null。

    需要注意的是:getElementById( )方法接收一个参数,即要获取元素的ID,且参数ID必须跟元素在页面中的ID属性值完全匹配,包括大小写。如果页面中存在多个具有相同ID的元素,则getElementById( )返回在文档中出现的第一个元素。

  • getElementsByTagName( )

    这个方法接收一个参数,即要获取元素的标签名,返回包含零个或多个元素的 NodeList 。因此可用中括号或 item ( )方法取得特定的元素。

  • querySelector( )

    这个方法通过不同的选择器获取元素。

  • querySelectorAll ( )

    这个方法通过不同的选择器获取一组元素的结合。

文档子节点

DOM规范提供了以下两个访问子节点的快捷方式。虽然 document.childNodes 始终有 < html > 元素,但使用 documentElement 属性可以更快更直接地访问该元素。

  • document.documentElement;//拿到 < html > 元素
  • document.body;

文档信息

  • document.title 设置文档的标题
  • document.URL 获取或者设置完整的URL
  • document.domain 获取或者设置域名
  • document.referrer 取得来源页面的URL

Element类型

Element类型也是Web开发中最常用的类型。

HTML元素

所有HTML元素都通过HTMLElement类型表示。

每个HTML元素都存在下面的标准属性

  • id,元素在文档中的唯一标识符

  • title,包含元素的额外信息,通常以提示条形式展示

  • className,相当于class属性,用于指定元素的CSS类(没有将这个属性命名为class,是因为class是ECMAscript的保留字)

  • lang,元素内容的语言代码(很少用)

  • dir,语言的书写方向(很少用)

取得属性

与属性相关的DOM方法主要有3个,但习惯使用(.)的方法获取属性

  • getAttribute( )
  • setAttribute( )
  • removeAttribute ( )

注:根据HTML5规范要求,自定义属性名前面应该前缀 data- 以方便验证。

创建元素

用 document.createElement( )方法创建新元素。这个方法接收一个参数,即要创建元素的标签名。

创建的元素属于游离状态,还没有被添加到文档树中,因此,新建的元素并不会马上看到,可以使用 appendChild( ),insertBefore ( ),replaceChild( )方法。


事件

javascript 与 HTML 的交互是通过事件实现的,事件意味着用户或浏览器执行的某种动作

  • DOM 0级事件:

    • 行内事件:在标签中写事件
    • 元素.on事件名=函数
  • DOM 2级事件

    • 只有一个:监听方法,有两个方法用来添加和移除事件处理程序:addEventListener()和removeEventListener()。

DOM事件流

事件流描述了页面接受事件的顺序。

DOM2 Events 规范规定事件流分为3个阶段:事件捕获、到达目标和事件冒泡。

以简单的 HTML 为例,点击 < DIV > 元素会以下图所示的顺序触发事件。
在这里插入图片描述

  • 事件捕获

    事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了再事件到达最终目标前拦截事件。

例如:

    <div class="father" style="width: 200px;height: 200px;background-color: pink;">
        <div class="son" style="width: 100px;height: 100px;background-color:skyblue">son盒子</div>
    </div>
    <script>
        var son = document.querySelector('.son');
        son.addEventListener('click', function () {
            alert('son');
        }, true);
    </script>

在这个例子中,给son盒子注册事件处理程序。点击son盒子后按照document -> html ->body -> father -> son的顺序开始接收(点击)事件,并且因为只有 son 有事件处理程序,因此只有点了 son 后才有警告框。

  • 事件冒泡

    事件冒泡被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播到没那么具体的元素(文档)。

  • 事件委托 (事件冒泡的典型应用)

    "过多事件处理程序"的解决方案是使用事件委托。事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。

例如:

    <ul id='myLink'>
        <li id='xxh'>徐鑫瀚</li>
        <li id='lkw'>蓝康伟</li>
        <li id='xlj'>肖琳峻</li>
    </ul>

这里的html包含3个列表项,如果需求是点击每个列表项都执行想要的操作,通常的做法是为每个列表项添加事件处理程序。

    var xxh = document.querySelector('#xxh');
    var lkw = document.querySelector('#lkw');
    var xlj = document.querySelector('#xlj');
    xxh.addEventListener('click', function () {
        alert('xxh');
    })
    lkw.addEventListener('click', function () {
        alert('lkw');
    })
    xlj.addEventListener('click', function () {
        alert('xlj');
    })

因为对页面所有需要使用 onclick 的事件处理程序的元素都如法炮制,结果会出现大量雷同的代码。

使用事件委托,只要给所有元素共同的祖先元素添加一个事件处理程序,就可以解决问题。

    var myLink = document.querySelector("#myLink");
    myLink.addEventListener('click', function (event) {
        var target = event.target;
        switch (target.id) {
            case "xxh":
                alert('xxh');
                break;
            case "lkw":
                alert('lkw');
                break;
            case "xlj":
                alert('xlj');
                break;
        }
    })

DOM事件处理程序

事件意味着用户或浏览器执行的某种动作,如单击(click)、加载(load)、鼠标悬停(mouseover),为响应事件而调用的函数被称为事件处理程序(或事件监听器)。

  • DOM 0 事件处理程序 ( 传统处理方式 )

    DOM 0 事件处理程序是把一个函数赋值给 (DOM元素的)一个事件处理程序的属性。
    删除:通过将事件处理程序属性的值设置为 null ,可以移除通过 DOM0 方式添加的事件处理程序。

  • DOM 2 事件处理程序

    DOM 2 为事件处理程序的赋值和移除定义了 addEventListener( )和 removeEventListener ( )方法。它们接收相同的3个参数:事件名、事件处理程序数和一个布尔值,true 表示在捕获阶段调用事件处理程序,false ( 默认值 )表示在冒泡阶段调用事件处理程序。

注: JS代码只能执行捕获或者冒泡其中一个阶段。

下面的例子展示注册事件和删除注册事件的方式:

        var btns = document.querySelectorAll('button');
        //传统注册事件
        btns[0].onclick = function () {
            alert(11);
            //传统注册事件的删除
            btns[0].onclick = null;
            //执行完第一次弹出警告后,执行注册事件删除,之后再点击不回弹出警告
        }
        //方法监听注册事件
        btns[1].addEventListener('click', fn);
        function fn() {
            alert(22);
            btns[1].removeEventListener('click', fn);
        }

DOM 事件对象

在DOM发生事件时,所有相关信息都会被收集并存储在一个名为 event 的对象中。这个对象包含了一些基本信息,如导致事件的元素、发生事件的类型等。

不同的事件生成的事件对象会包含不同的属性和方法。不过,有些属性和方法所有事件对象都会包含,如 target 、preventDefault ( ),stopPropagation( )等。

  • preventDefault( ):用于阻止特定事件的默认动作。如:链接的默认动作就是在被单击时导航到 href 属性指定的 url 。如果想阻止这个行为,可以在 onclick 事件处理程序中取消。通常的做法是:href = javascript:;)
        var a = document.zquerySelector('a');
        a.onclick = function (event) {
            event.preventDefault();
        }
  • stopPropagation( ):阻止事件冒泡。
  • 在事件处理程序内部,this 对象始终等于 currentTarget 的值,而 target 只包含事件的实际目标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值