知识点前言

各种框架层出不穷,但DOM操作一直都会是前端工程师的基础,必备知识。

只会Vue和React等框架,而不懂DOM操作的前端程序员们。。。

在这里插入图片描述

DOM的本质?Do you know?

在这里插入图片描述

首先,先了解一下什么是xml 。 上代码:

"1.0" encoding="ISO-8859-1"?>
<note>
<to>Georgeto>
<from>Johnfrom>
<heading>Reminderheading>
<body>Don't forget the meeting!body>
note>

XML (可扩展标记语言 EXtensible Markup Language)

XML 是一种标记语言, 被设计用来传输和存储数据,而非显示数据(HTML就被设计用来显示数据)

XML使用的标签没有被预定义,你需要自行定义标签。

SGML、HTML、XML、XHTML、HTML5 之间的关系,知道否?

HTML是一种特殊的XML。它遵循W3C的规定,各种规定,必须先写什么,怎么写什么。

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>Documenttitle>
head>
<body>
    <div>
        <p>跟着W3C标准,有饭吃。。。ヽ( ̄▽ ̄)ノp>
    div>
body>
html>

在这里插入图片描述

那么如果是一个字符串对象(html一大坨)的话,让浏览器,js处理是非常不方便的。

如何查询,如何操作等等比较麻烦。所以浏览器拿到代码之后。。。

DOM可以理解为浏览器把拿到的html代码,结构化一个浏览器能识别并且js可操作的一个模型而已(也就是DOM结构树)

在这里插入图片描述

树结构什么的不要我讲了吧

DOM 节点操作获取 DOM 节点**document.getElementById(); //id名,在实际开发中较少使用,选择器中多用class id一般只用在顶级层存在 不能太过依赖id

****document.getElementsByTagName(); //标签名

****document.getElementsByClassName(); //类名

****document.getElementsByName(); //name属性值,一般不用

****document.querySelector(); //css选择符模式,返回与该模式匹配的第一个元素,结果为一个元素;如果没找到匹配的元素,则返回null

****document.querySelectorAll() //css选择符模式,返回与该模式匹配的所有元素,结果为一个类数组

**

注意:

在这里插入图片描述

根据前面,我们已经知道:DOM(文档对象模型)可以将任何HTML、XML文档描绘成一个多层次的节点树。所有的页面都表现为以一个特定节点为根节点的树形结构。html文档中根节点为document节点。

在这里插入图片描述

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

经常使用的节点主要有以下几种类型:

Element类型(元素节点):nodeType值为 1Text类型(文本节点):nodeType值为 3Comment类型(注释节点):nodeType值为 8Document类型(document节点):nodeType值为 9

其规定的一些常用的属性有:

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

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

parentNode //获取所选节点的父节点,最顶层的节点为#documentchildNodes //获取所选节点的子节点们firstChild //获取所选节点的第一个子节点lastChild //获取所选节点的最后一个子节点nextSibling //获取所选节点的后一个兄弟节点 列表中最后一个节点的nextSibling属性值为null`previousSibling` //获取所选节点的前一兄弟节点 列表中第一个节点的`previousSibling`属性值为`null`

注意:

由于文档中的节点类型较多,遍历子节点的结果很多时候并不能得到我们想要的结果。

小心哦!!空文本也是文本节点!

使用遍历元素节点则很方便。

在这里插入图片描述

parentElement//返回当前元素的父元素节点(IE9以下不兼容)children // 返回当前元素的元素子节点firstElementChild //返回的是第一个元素子节点(IE9以下不兼容)lastElementChild //返回的是最后一个元素子节点(IE9以下不兼容)nextElementSibling //返回的是后一个兄弟元素节点(IE9以下不兼容)previousElementSibling //返回的是前一个兄弟元素节点(IE9以下不兼容)

注意:

这些获取节点的方式,返回值要么是一个特定的节点,要么是一个集合HTMLCollection,这个节点的集合是一个类数组。

HTML中的 attribute 和 JavaScript中的 property

attribute

**attribute是HTML标签中定义的属性(修改html属性,会改变html结构),它的值只能是字符串。

attribute 有三个方法:setAttribute() , getAttribute(), removeAttribute()

**

property

property是JavaScript为元素对象定义的属性(修改对象属性,不会体现到html结构中)property 属性可以看作 DOM 对象的键值对,用点操作符修改。它也可以和其他的 JavaScript 对象一样添加自定义的属性以及方法。property 的值可以是任何的数据类型,对大小写敏感。

attribute 和 property 共同拥有的属性

虽然Attribute和Property定义的属性分别在不同层面上,但是有以下几个属性是共享的:

id class lang dir title

"div" class="class" lang="lang" dir="dir" title="title" user="user" > var ele = document.getElementById('id'); console.log(ele.getAttribute('id')) // id console.log(ele.getAttribute('class')) // class console.log(ele.getAttribute('lang')) // lang console.log(ele.getAttribute('dir')) // ltr console.log(ele.getAttribute('title')) // title console.log(ele.getAttribute('user')) // user ele.user1= 'user1' console.log(ele.id) // id console.log(ele.className) // class console.log(ele.lang) // lang console.log(ele.dir) // ltr console.log(ele.title) // title console.log(ele.user1) // user console.log(ele.user) // undefined console.log(ele.getAttribute('user1')) // null

自定义的 property 不会出现在 html 代码中,只存在 js 中。因此,ele.getAttribute(‘user1’) 结果为:null

html 标签的5个标准特性:id,title,lang,dir,className(在DOM中以property方式操作这几个特性会同步到html标签中)。所以即使在html中没有指定id、title等,也会默认赋予一个空串,通过property属性(点操作符)可以访问。 而除此之外在html中设置的其他属性是不能通过Property访问到的(除了attribute特有的属性)。因此,ele.user 结果为:undefined

注意:

有一些比较特殊的情况:

- input 元素的 value

var input1 = document.getElementById('input1'); // 获取id为'input1' 的input元素
input1.setAttribute('value', 'test');  // 用setAttribute()方法设置value属性为'test'
console.log(input1.value); // test
a.value = 'change';   // property方式设置value
console.log(a.getAttribute('value')); // test

用点操作符修改 value 值,并不会同步到 attribute 上;但是通过 setAttribute 修改属性值,会同步到 property 上。

- 表单

type='radio' checked='checked' id='radio'>
<script>
  var radio = document.getElementById('radio');
  console.log(radio.getAttribute('checked')); // 'check'
  console.log(radio.checked); // true
script>

一些表单元素,对于这些特殊的 attribute 节点,只要存在该节点,对应的 property 就为true,disabled 类似

- href

<a href='a.html' id='web'> a>
<script>
  var radio = document.getElementById('web');
  console.log(web.getAttribute('href')); // 'a.html' 
  console.log(web.href); // 绝对路径
script>

attribute 取得是相对路径;property 取得是绝对路径。

建议:

尽量使用property,因为property可能会在js的一些机制中避免DOM的重新渲染,而attribute一旦改了html结构,则一定会引起DOM重新渲染。

以下两种情况用attribute:

自定义 attribute 标签,因为它不能同步到 property 上。访问内置的 html 标签的 attribute,如 input 的 value(可以用来检验 value 值是否改变)DOM 结构操作

各种DOM操作,请读者自由发挥,耍起来哟~~

一定要记得多敲敲!!!

在这里插入图片描述

示例:主要代码如下

"div1" class="container"> <p id="p1">一段文字 1p> <p>一段文字 2p> <p>一段文字 3p>
<div id="div2"> <img src="https://img-blog.csdnimg.cn/20200201200740869.jpg"/> div> const div1 = document.getElementById('div1') const div2 = document.getElementById('div2') // 新建节点 const newP = document.createElement('p') newP.innerHTML = 'this is newP' // 插入节点 div1.appendChild(newP) // 移动节点 const p1 = document.getElementById('p1') div2.appendChild(p1) // 获取父元素 console.log( p1.parentNode ) // 获取子元素列表 const div1ChildNodes = div1.childNodes console.log( div1.childNodes ) const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => { if (child.nodeType === 1) { return true } return false }) console.log('div1ChildNodesP', div1ChildNodesP) // 删除子元素 div1.removeChild( div1ChildNodesP[0] )

DOM 性能

DOM 操作非常“昂贵”,避免频繁的DOM操作。

复习回顾

在这里插入图片描述

DOM 是哪种数据结构

DOM 操作的常用API

attribute 和 property 的区别

一次性插入多个DOM节点,考虑性能


本文由转载于互联网,如有侵权请联系删除!