js之DOM操作

DOM操作

DOM(Document Object Modle,文档对象模型)是W3C定制的一套技术规范,用来描述js脚本如何与HTML或XML文档进行交互Web标准。DOM规定了一系列标准接口,允许开发人员通过标准方式访问文档结构操作网页内容控制样式和行为等。

学习重点

  • 使用js操作节点
  • 使用js操作元素
  • 使用js操作文本和属性
  • 使用js操作文档和文档片段

节点概述

在网页中所有的对象和内容都被称为节点,如文档元素文本属性注释等。节点(Node)是DOM最基本的单元,并派生出不同类型的节点,它们共同构成了文档的树形结构模型。

节点类型

根据DOM规范,整个文档是一个文档节点,每个标签是一个元素节点,元素包含的文本是文本节点,元素的属性是一个属性节点,注释属于注释节点,以此类推。

节点类型 说明 可包含的字节类型
Document 表示整个文档,DOM树的根节点 Element、ProcessingInstruction、Comment、DocumentType
DocumentFragment 表示文档片段,轻量级的Document对象,仅包含部分文档 ProcessingInstruction、Comment、Text、CDATASection、EntityReference
DocumentType 为文档定义实体提供接口 None
ProcessingInstruction 表示处理指令 None
EntityReference 表示实体引用元素 ProcessingInstruction、Comment、Text、CDATASection、EntityReference
Element 表示元素 Text、Comment、ProcessingInstruction、CDATASection、EntityReference
Attr 表示属性 Text、EntityReference
Text 表示元素或属性中的文本 None
CDATASection 表示文档中的CDATA区段,器包含的文本不会被解析器解析 None
Comment 表示注释 None
Entity 表示实体 ProcessingInstruction、Comment、Text、CDATASection、EntityReference
Notation 表示在DTD中声明的符号 None

使用nodeType属性可以判断一个节点的类型。

节点类型 nodeType返回值
Element 1
Attr 2
Text 3
CDATASection 4
EntityReference 5
Entity 6
ProcessingInstruction 7
Comment 8
Document 9
DocumentType 10
DocumentFragment 11
Notation 12
  • 实例】下面实例演示如何借助节点的nodeType属性检查当前文档中包含元素的个数。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
    
    
            function count(n) {
    
    
                var num = 0;
                if (n.nodeType == 1) {
    
    
                    num++;
                }
                var son = n.childNodes;
                for (var i = 0; i < son.length; i++) {
    
    
                    num += count(son[i]);
                }
                return num;
            }
            console.log("当前文档包含 " + count(document) + "个元素");
        }
    </script>
</head>

<body>
    <h1>DOM</h1>
    <p>DOM<cite>Document Object Model</cite>首字母简写,中文翻译为<b>文档对象模型</b>,是<i>W3C</i>组织推荐的处理可扩展标识语言的标准编程接口</p>
    <ul>
        <li>D表示文档,HTML文档结构
        </li>
        <li>O表示对象,文档结构的js脚本化映射</li>
        <li>M表示模型,脚本与结构交互的方法和行为</li>
    </ul>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GU4pbHhL-1600770996698)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/1.jpg)]

在上面的js脚本中定义了一个记数函数,然后通过递归调用的方式逐层检索document下做包含的全部节点,在计数函数中再通过node.nodeType == 1过滤掉非元素节点,进而统计文档中包含的全部元素。

节点名称和值

使用nodeName和nodeValue属性可以读取节点的名称和值。属性取值说明:

节点类型 nodeName返回值 nodeValue返回值
Document #document null
DocumentFragment #document-fragment null
DocumentType doctype名称 null
EntityReference 实体引用名称 null
Element 元素的名称 null
Attr 属性的名称 属性的值
ProcessingInstruction target 节点的内容
Comment #comment 注释的文本
Text #test 节点的内容
CDATASection #cdata-section 节点的内容
Entity 实体名称 null
Notation 符号名称 null
  • 实例】不同类型的节点,nodeName和nodeValue属性取值不同。元素的nodeName属性返回值是标签名,而元素的nodeValue属性返回值为null。因此在读取属性值之前,应该先检测类型。
var node = document.getElementByTagName("body")[0];
if(node.nodeType==1) {
    
    
  var value = node.nodeName;
}
console.log(value);

nodeName属性在处理标签时比较有用,而nodeValue属性在处理文本信息比较实用。

扫描二维码关注公众号,回复: 12478836 查看本文章

节点关系

DOM把文档视为一棵树型结构,也称为节点树。节点之间的关系包括:上下父子关系、相邻兄弟关系。简单描述如下:

  • 在节点数中,最顶端节点为根节点
  • 除了根节点之外,每个节点都有一个父节点。
  • 节点可以包含任何数量的子节点。
  • 叶子是没有子节点的节点。
  • 同级节点是拥有相同父节点的节点。

访问节点

DOM为Node类型定义如下属性,以便js访问节点。

  • ownerDocument:返回当前节点的根元素(document对象)。
  • parentNode:返回当前节点的父节点,所有的节点都仅有一个父节点。
  • childNodes:返回当前节点的所有子节点的节点列表。
  • firstChild:返回当前节点的第一个子节点。
  • lastChild:返回当前节点的最后一个子节点。
  • nextSibling:返回当前节点之后相邻的同级节点。
  • previousSibling:返回当前节点之前相邻的同级节点。
  1. childNodes

childNodes返回所有子节点的列表,它是一个随时可变的类数组。文本节点和属性节点都不包含任何子节点,所以它们的childNodes属性返回值是一个空集合。可以使用haschildNodes()方法或者childNodes.length>0来判断一个节点是否包含子节点。

  1. parentNode

parentNode返回元素类型的父节点,因为只有元素才可能包含子节点。不过document节点没有父节点,document节点的parentNode属性将返回null。

  1. firstChildlastChild

firstChild返回第一个子节点,lastChild返回最后一个子节点。文本节点和属性节点的firstChild和lastChild属性的返回值为null。

  • 注意:firstChild等价于childNodes的第一个元素,lastChild属性值等于childNodes的最后一个元素。如果firstChild等于null,则说明当前节点为空节点。
  1. nextSiblingpreviousSibling

nextSibling返回下一个相邻节点,previousSibling返回上一个相邻点。如果没有同属性一个父节点的相邻节点,则返回null。

  1. ownerDocument

ownerDocument表示根节点。node.ownerDocument等价于document.documentElement。

操作节点

操作节点的基本方法:

方法 说明
appendChild() 向节点的子节点列表的结尾添加新的子节点
cloneNode() 复制节点
hasChildNodes() 判断当前节点是否拥有子节点
insetBefore() 在指定的子节点前插入新的子节点
normalize() 合并相邻的Text节点并删除
removeChild() 删除(并返回)当前节点的指定子节点
replaceChild() 用新节点替换一个子节点
  • 提示:appendChild()、insertBefore()、removeChild()、replaceChild()四个方法用于对子节点进行操作。使用者四个方法之前,可以使用parentNode属性先获取父节点。另外,并不是所有类型的节点都有子节点,如果在不支持子节点,如果在不支持子节点的节点上调用了这些方法将会导致错误发生。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
     
     

            var ul = document.getElementsByTagName("ul")[0];
            ul.onclick = function() {
     
     
                this.style.border = "solid blue 1px";
            }
            var ul1 = ul.cloneNode(true);
            document.body.appendChild(ul1);

        }
    </script>
</head>

<body>
    <h1>DOM</h1>
    <p>DOM是<cite>Document Object Model</cite>首字母简写,中文翻译为<b>文档对象模型</b>,是<i>W3C</i>组织推荐的处理可扩展标识语言的标准变成接口</p>
    <ul>
        <li>D表示文档,HTML文档结构</li>
        <li>O表示对象,文档结构为js脚本化映射</li>
        <li>M表示模型,脚本与结构交互的方法和行为</li>
    </ul>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZmYQ6NDu-1600770996702)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/2.jpg)]

文档节点

文档节点代表整个文档,使用document可以访问。它是文档内其他节点的访问入口,提供了操作其他节点的方法。主要特征值:nodeType等于9、nodeName等于“#document”、nodeValue等于null、parentNode等于null、ownerDocument等于null。

访问文档

在不同环境中,获取文档节点的方法不同。具体说法如下:

  • 文档内部节点,使用ownerDocument访问。
  • 脚本中,使用document访问。
  • 框架页,使用contentDocument访问。
  • 异步通信中,使用XMLHttpRequest对象的responseXML访问。

访问子节点

文档子节点包括以下类型:

  • doctype文档类型,如<!doctype html>
  • html元素,如<html>
  • 处理指令,如<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
  • 注释,如<!--注释-->

访问方法说明如下:

  • 使用document.documentElement可以访问html元素。
  • 使用document.doctype可以访问doctype。注意,部分浏览器不支持。
  • 使用document.childNodes可以遍历子节点。
  • 使用document.firstChild可以访问第一个子节点,一般为doctype。
  • 使用docuemnt.lastChild可以访问最后一个子节点,如html元素或注释。

访问特殊元素

文档中存在很多特殊元素,使用下面的方法可以获取,若获取不到则返回null。

  • 使用document.body可以访问body元素。
  • 使用documetn.head可以访问head元素。
  • 使用document.defaultView可以访问默认制图,即所属的窗口对象window。
  • 使用document.scrollingElement可以访问文档内滚动的元素。
  • 使用document.activeElement可以访问文档内获取焦点的元素。
  • 使用document.fullscreenElement可以访问文档内正在全屏显示的元素。

访问元素集合

document包含一组集合对象,使用它们可以快速访问文档内元素,简单说明如下。

  • document.anchors:返回设置name属性的<a>标签。
  • document.links:返回所有设置了href属性的<a>标签。
  • document.forms:返回所有form对象。
  • document.images:返回所有image对象。
  • document.applets:返回所有applet对象。
  • document.enbeds:返回所有enbed对象。
  • document.plugins:返回所有plugin对象。
  • document.scripts:返回所有的script对象。
  • document.styleSheets:返回所有样式表集合。

访问文档信息

document包含很多信息,简单说明如下:

  1. 静态信息
  • document.URL:返回当前文档的网址。
  • document.domain:返回当前文档的域名,不包含协议和接口。
  • document.location:访问location对象。
  • docuemnt.lastModified:返回当前文档最后修改的时间。
  • document.title:返回当前文档的标签。
  • document.characterSet:返回当前文档的编码。
  • document.referrer:返回当前文档的访问者在哪里。
  • document.dir:返回文字方向。
  • document.compatMode:返回浏览器处理文档的模式,值包括BackCompat(向后兼容模式)和CSS1Compat(严格模式)。
  1. 状态信息
  • document.hidden:表示当前页面是否可见。如果窗口最小化、切换页面,则document.hidden返回true。
  • document.visibilitystate:返回文档的可见状态。取值包括visible(可见)、hidden(不可见)、prerender(正在渲染)、unloaded(已卸载)。
  • document.readyState:返回当前文档的状态、取值包括loading(正在加载)、interactive(加载外部资源)、complete(加载完成)。

访问文档元素

docuement对象包含多个文档内元素的方法,简单说明如下:

  • getElementById():返回指定id属性值的元素。注意,id值要区分大小写。,如果找到多个id相同的元素,则返回第一个元素;如果没有找到指定id值的元素,则返回null。
  • getElementsByTagName():返回所有指定标签名的元素节点。
  • getElementsByname():返回指定名称(name属性值)的元素节点。该方法多用于表单结构中,获取单选按钮组或复选框组。

提示:getElementByTagName()方法返回的是一个HTMLCollection对象,与nodeList对象类似,可以使用方括号语法或者item()方法访问HTMLCollection对象中的元素,并通过length属性取得这个对象中元素的数量。

元素节点

在客户端开发中,大部分操作都是针对元素节点的。主要特征值:nodeType等于1。nodeName等于标签名、nodeValue等于null。元素节点包含5个公共属性:id(标识符)、title(提示标签)、lang(语言编码)、dir(语言方向)、className(CSS类样式),这些属性可读可写。

访问元素

  1. getElementById()方法

使用getElementById()方法可以准确获取文档中指定元素。用法如下:

document.getElementById(ID);

参数ID表示文档中对应元素的id属性值。如果文档中不存在指定元素,则返回值为null。该方法只适用于document对象。

  • 实例1】在下面实例中,使用getElementById()方法获取<div id="box">对象,然后使用nodeName、nodeType、parentNode和childNodes属性查看该对象的节点类型、节点名称、父节点和第一个子节点的名称。
<div id="box">盒子</div>
<script>
	var box = document.getElementById("box");
  var info = "nodeName: " + box.nodeName;
  info += "\rnodeType: " + box.nodeName;
  info += '\rparentNode: ' + box.parentNode.nodeName;
  info += "\rchildNodes: " + box.childNodes[0].nodeName;
  console.log(info);
</script>
  1. getElementsByTagName()方法可以获取指定标签名称的所有元素。用法如下:
document.getElementsByTagName(tagName)

参数tagName表示指定标签名称的标签,该方法返回一个节点集合,使用length属性可以获取集合中包含元素的个数,利用下标可以访问其中某个元素对象。

  • 实例2】下面代码使用for循环获取每个p元素,并设置p元素的class属性为red。
var p = document.getElementsByTagName("p");
for (var i = 0; i < p.length; i++) {
    
    
  p[i].setAttrbute("class","red");
}

创建元素

使用document对象的createElement()方法能够根据参数指定的标签名称创建一个新的元素,并返回新建元素的引用。用法如下:

var element = document.createElement("tagName");

其中,element表示新建元素的引用,createElement()是document对象的一个方法,该方法只有一个参数,用来执行创建元素的标签名称。

  • 实例1】下面代码在当前文档中创建了一个段落标记p,存储到变量p中。由于该变量表示一个元素节点,所以它的nodeType属性值等于1,而nodeName属性值等于p。
var p = document.createElement("p");
var info = "nodeName" + p.nodeName;
info += ",nodeType: " + p.nodeType;
console.log(info);

使用createElement()方法创建的新元素不会被自动添加到文档里。如果要把这个元素添加到文档里,还需要使用appendChild()、insertBefore或replaceChild()方法实现。

  • 实例2】下面代码演示如何把新建的p元素添加到body元素下。当元素被添加到文档树中就会立即显示出来。
var p = document.createElement("p");
document.body.appendChild(p);

复制节点

cloneNode()方法可以创建一个节点的副本。

插入节点

在文档中插入节点主要包括两种方法。

  1. appendChild()方法:

appendChild()方法可像当前节点的子节点列表的末尾添加新的子节点。用法如下:

appendChild(newchild)

参数newchild表示新添加的节点对象,并返回新增的节点。

  • 实例1】下面实例展示了如何把段落添加到文档中指定的div元素中,使它成为当前节点的最后一个子节点。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
    
    
            var p = document.createElement("p");
            var txt = document.createTextNode("盒模型");
            p.appendChild(txt);
            document.getElementById("box").appendChild(p);
        }
    </script>
</head>

<body>
    <div id="box"></div>
</body>

</html>

如果文档树中已经存在参数节点,则将从文档树中删除,然后重新插入新的位置。如果添加的节点是DocumentFragment节点,则不会直接插入,而是把它的子节点插入当前节点的结尾。

  • 提示:将元素添加到文档树中,浏览器会立即呈现该元素。此后,对这个元素所做的任何修改都会实时反映在浏览器中。
  • 实例2】在下面实例中,新建两个盒子和一个按钮,使用CSS设计两个盒子显示为不同的效果;然后为按钮绑定事件处理程序,设计单击按钮时执行插入操作。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <style>
        #red {
     
     
            border: solid red 20px;
        }
        
        #blue {
     
     
            border: solid blue 10px;
        }
    </style>
    <script>
        window.onload = function() {
     
     
            var ok = document.getElementById("ok");
            ok.onclick = function() {
     
     
                var red = document.getElementById("red");
                var blue = document.getElementById("blue");
                blue.appendChild(red);
            }
        }
    </script>
</head>

<body>
    <div id="red">
        <h1>红盒子</h1>
    </div>
    <div id="blue">蓝盒子</div>
    <button id="ok">移动</button>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k4SbuKlL-1600770996703)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/3.gif)]

上面代码使用appendChild()方法把红盒子移动到蓝盒子中间。在移动指定节点时,会同时移动指定节点包含的所有子节点。

  1. insertBefore()方法

使用insertBefore()方法可在已有的字节前插入一个新的子节点。

insertBefore(newchild, refchild);

其中参数newchild表示新插入的节点,refchild表示插入新节点的节点,用于指定插入节点的后面相邻位置。插入成功后,该方法将返回新插入的子节点。

  • 提示:insertBefore()方法与appendChild()方法一样,可以把指定元素及其所包含的所有子节点都一起插入到指定位置中。同时会先删除移动的元素,再重新插入到新的位置。

删除节点

removeChild()方法可以从子节点列表中删除某个节点。

nodeObject.removeChild(node)

其中参数node为要删除节点。如果删除成功,则返回删除节点;如果失败,则返回null。

当使用removeChild()方法删除节点时,该节点所包含的所有子节点将同时删除。

  • 实例1】在下面的实例中单击按钮时将删除红盒子中的一级标题。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <style>
        #red {
    
    
            border: solid red 20px;
        }
        
        #blue {
    
    
            border: solid blue 10px;
        }
    </style>
    <script>
        window.onload = function() {
    
    
            var ok = document.getElementById("ok");
            ok.onclick = function() {
    
    
                var red = document.getElementById("red");
                var h1 = document.getElementsByTagName("h1")[0];
                red.removeChild(h1);
            }
        }
    </script>
</head>

<body>
    <div id="red">
        <h1>红盒子</h1>
    </div>
    <div id="blue">蓝盒子</div>
    <button id="ok">移除</button>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q4ckUiui-1600770996706)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/4.gif)]

替换节点

replaceChild()方法可以将某个子节点替换成另一个。

nodeObject.replaceChild(new_node, old_node)

其中参数new_node为指定新的节点,old_node为被替代的节点。如果替换成功,则返回被替换的节点;如果替换失败,则返回null。

  • 实例1
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <style>
        #red {
     
     
            border: solid red 20px;
        }
        
        #blue {
     
     
            border: solid blue 10px;
        }
    </style>
    <script>
        window.onload = function() {
     
     
            var ok = document.getElementById("ok");
            ok.onclick = function() {
     
     
                var red = document.getElementById("red");
                var h1 = document.getElementsByTagName("h1")[0];
                var h2 = document.createElement("h2");
                red.replaceChild(h2, h1);
            }
        }
    </script>
</head>

<body>
    <div id="red">
        <h1>红盒子</h1>
    </div>
    <div id="blue">蓝盒子</div>
    <button id="ok">替换</button>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OOyaVf8-1600770996707)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/5.gif)]

当替换之后,原来的一级标题已经不见了,说明替换节点的操作的不是替换元素的名称,而是替换其包含的所有子节点以及其包含的所有内容。

同样的道理,如果替换节点还包含子节点,则子节点将一同被插入到被替换的节点中。可以借助replaceChild()方法在文档中使用现有的节点替换另一个存在的节点。

文本节点

文本节点表示元素和属性的文本内容,包含纯文本内容、转义字符,但不包含HTML代码。文本节点不包含子节点。主要特征值:nodeType等于3、nodeName等于“#text”、nodeValue等于包含的文本。

创建文本节点

使用document对象的createTextNode()方法可以创建文本节点。

document.createTextNode(data)

参数data表示字符串。

  • 实例】下面实例创建一个新的div元素,并为他设置class值为red,添加到文档中。
var element = document.createElement("div");
element.className = "red";
document.body.appendChild(element);

注意

由于DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点的情况。为了避免这种情况的发生,一般会在父元素上调用normalize()方法,删除空文本节点,合并相邻文本节点。

访问文本节点

使用nodeValue或data属性可以访问文本节点包括的文本。使用length属性可以获取包含文本的长度,利用该属性可以遍历文本中每个字符。

  • 实例
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
     
     
            function text(e) {
     
     
                var s = "";
                var e = e.childNodes || e;
                for (var i = 0; i < e.length; i++) {
     
     
                    s += e[i].nodeType != 1 ? e[i].nodeValue : text(e[i].childNodes);
                }
                return s
            }
            var div = document.getElementById("div1");
            var s = text(div);
            console.log(s); //  div 元素
        }
    </script>
</head>

<body>
    <div id="div1">
        <span class="red">div</span> 元素
    </div>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RfV4SJBp-1600770996709)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/6.jpg)]

在上面函数中,通过递归函数索引指定元素的所有子节点,然后判断每个子节点的类型,如果不是元素,则读取该节点的值,否则继续递归遍历该元素包含的所有子节点。

读取HTML字符串

使用元素的innerHTML属性可以返回调用元素包含的所有子节点对应的HTML标记字符串。

插入HTML字符串

使用innerHTML属性可以根据传入的HTML字符串,创建新的DOM片段,然后这个DOM片段完全替代调用元素原有的所有子节点。设置innerHTML属性值之后,可以像访问文档中的其他节点一样访问新创建的节点。

  • 注意:使用innerHTML属性也有一些限制。例如,在大多数浏览器中,通过innerHTML插入<script>标记后,并不会执行其中的脚本。

替换HTML字符串

outerHTML与innerHTML功能相同。

  • 实例】下面实例演示了outerHTML与innerHTML属性的不通效果。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
     
     
            var ul = document.getElementsByTagName("ul")[0];
            var lis = ul.getElementsByTagName("li");
            lis[0].onclick = function() {
     
     
                this.innerHTML = "<h2>我是一名初学者</h2>";
            }
            lis[1].onclick = function() {
     
     
                this.outerHTML = "<h2>当然喜欢</h2>";
            }
        }
    </script>
</head>

<body>
    <h1>单击回答问题</h1>
    <ul>
        <li>你叫什么?</li>
        <li>你喜欢JS么?</li>
    </ul>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1937m97O-1600770996711)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/7.gif)]

  • 注意:在使用innerHTML、outerHTML时,应删除被替换元素的所有事件处理程序和js对象属性。

读写文本

innerText和outerText也是IE的私有属性,但是没有被HTML5纳入规范。

  1. innerText属性

innerText在指定元素中插入文本内容,如果文本中包含HTML字符串,将被编码显示。

  1. outerText属性

outerText与innerText功能类似,但是它能够覆盖原有的元素。

属性节点

属性节点的主要特征值:nodeType等于2、nodeName等于属性的名称、nodeValue等于属性的值、parentNode等于null,在HTML中不包含子节点。属性节点继承于Node类型,包括以下3个专用属性。

name:表示属性名称,等效于nodeName。

value:表示属性值,可读可写,等效于nodeValue。

specified:如果属性值在代码中设置的,则返回true;如果为默认值,则返回false。

创建属性节点

使用document对象的createAttribute()方法可以创建属性节点,具体用法如下:

document.createAttribute(name)

参数name表示新创建的属性的名称。

  • 实例1】下面实例创建一个属性节点,名称为align,值为center,然后为标签<div id="box">设置属性align,最后分别使用3种方法读取属性align的值。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
     
     
            var element = document.getElementById("box");
            var attr = document.createAttribute("align");
            attr.value = "center";
            element.setAttributeNode(attr);

            console.log(element.attributes["align"].value); //center
            console.log(element.getAttributeNode("align").value); //center
            console.log(element.getAttribute("align")); //center
        }
    </script>
</head>

<body>
    <div id="box">document.createAttribute(name)</div>
</body>

</html>
  • 在传统DOM中,常用点语法通过元素直接访问HTML属性,如img.src、a.href等,这种方式虽然不标准,但是获得了所有浏览器的支持。
<img id="img1" src="">
<script>
	var img = document.getElementByIn("img1");	
	img.setAttribute("src","http://www.w3.org/");
	img.str = "http://www.w3.org/";
</script>

读取属性节点

使用元素的getAttribute()方法可以读取指定属性的值。用法如下:

getAttribute(name)

参数name表示属性名称。

  • 注意:使用元素的attribute属性、getAttributeNode()方法可以返回对应属性节点。如上实例1。
  • HTML DOM也支持使用点语法读取属性值,使用比较简便,也获得了所有浏览器的支持。
  • 对于class属性,则必须使用className属性名,因为class是js语言的保留字;对于for属性,则必须使用htmlFor属性名,这与CSS脚本中float和text属性被改名为cssFloat和cssText是一个道理。

设置属性值

使用元素的setAttribute()方法可以设置元素的属性值。用法如下:

setAttribute(name, value);

参数name和value分别表示属性名称和属性值。属性名和属性值必须必须以字符串的形式进行传递。如果元素中存在指定的属性,它的值将被刷新;如果不存在,则setAttribute()方法将为元素创建该属性并赋值。

  • 也可以使用快捷方式设置HTML DOM文档中元素的属性值。
<label id="label1">文本框:
  <input type="text" name="textfield" id="textfield" />
</label>
<script>
	var label = document.getElementByIn("label1");
  label.className = "class1";
  label.htmlFor = "textfield";
</script>

删除属性

使用元素的removeAttribute()方法可以删除指定的属性。

removeAttribute(name)

参数name表示元素的属性名。

使用类选择器

HTML5位document对象和HTML元素新增了getElementByClassName()方法,使用该方法可以选择指定类名的元素。getElementByClassName()方可以接受一个字符串参数,包括一个或多个类名。

  • 实例】下面实例使用document.getElementById(“box”)方法先获取<div id="box">,然后在它下面使用getElementByClassName(“blue red”)选择同时包含red和blue类的元素。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
     
     
            var divs = document.getElementById("box").getElementsByClassName("blue red");
            for (var i = 0; i < divs.length; i++) {
     
     
                console.log(divs[i].innerHTML);
            }
        }
    </script>
</head>

<body>
    <div id="box">
        <div class="blue red green">blue red green</div>
        <div class="blue red black">blue red black</div>
    </div>
</body>

</html>
  • document对象上调用getElementByClassName()会返回类名匹配的所有元素,在元素上调用该方法就只会返回后代元素中匹配的元素。

自定义属性

HTML5允许用户为元素自定义属性,但要求添加data-前缀,目前是为元素提供与渲染无关的附加信息,或者提供语义信息。例如:

<div id="box" data-myid="12345" data-myname="zhangsan" data-mupass="zhang123">自定义数据属性</div>

添加自定义属性后,可以通过元素的dataset属性访问自定义属性。dataset属性的值是一个DOMStringMap实例,也就是一个名值对的映射。在这个映射中,每个data-name形式的属性都会有一个对应的属性,只不过属性名没有data-前缀。

var div = document.getElementById("box");
// 访问自定义属性值
var id = div.dataset.myid;
var name = div.dataset.myname;
var pass = div.dataset.mypass;
// 重置自定义属性值
div.dataset.myid = "54321";
div.dataset.myname = "lisi";
div.dataset.mypass = "lisi543";
// 检测自定义属性
if (div.dataset.myname) {
    
    
    console.log(div.dataset.myname);
}

文档片段节点

DocumentFragment是一个虚拟的节点类型,仅存在于内存中,没有添加到文档数中,所以看不到渲染效果。使用文档片段你的好处,就是避免浏览器渲染和占用资源。当文档片段设计完善后,再使用js一次性添加到文档树中显示出来,这样可以提高效率。

主要特征值:nodeType值等于11、nodeName等于“#document-fragment”、nodeValue等于null、parentNode等于null。

创建文档片段的方法:

var fragment = document.createDocumentFragment();

使用appendChild()或insertBefore()方法可以把文档片段添加到文档树中。

每次使用js操作DOM都会改变页面呈现,并触发整个页面重新渲染(回流),从而消耗系统资源。为了解决这个问题,可以先创建一个文档片段,把所有新节点附加到文档片段上,最后再把文档片段一次性添加到文档中,减少页面重绘次数。

  • 实例】下面实例使用文档片段创建主流Web浏览器列表。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test02</title>
    <script>
        window.onload = function() {
    
    
            var element = document.getElementById("ul");
            var fragment = document.createDocumentFragment();
            var browers = ['Firefox', 'Chrome', 'Opera', 'Safari', 'Internet Explorer'];
            browers.forEach(function(browser) {
    
    
                var li = document.createElement("li");
                li.textContent = browers;
                fragment.appendChild(li);
            });
            element.appendChild(fragment);
        }
    </script>
</head>

<body>
    <ul id="ul"></ul>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amqF7ucc-1600770996712)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记九/8.jpg)]

CSS选择器

  • querySelector()
  • querySelectorAll()
  • 实例1】新建网页文档,如下:
<div class="content">
    <ul>
        <li>首页</li>
        <li class="red">财经</li>
        <li class="blue">娱乐</li>
        <li class="red">时尚</li>
        <li class="blue">互联网</li>
    </ul>
</div>

如果要获得第一个li元素,可以使用以下方法。

document.querySelector(".content ul li");

如果要获得宿友li元素,可以使用以下方法。

documet.querySelectorALl(".content ul li");

如果要获得所有的class为red的li元素,可以使用以下方法。

document.querySelectorAll("li.red");
  • 提示:DOM API模块也包含getElementByClassName()方法,使用该方法可以获取指定类名的元素。
  • 注意:getElementByClassName()方法只能够接受字符串,且为类名,而不需要加点号前缀,如果没有匹配到任何元素则返回空数组。

CSS选择器是一个便捷的确定元素的方法,这是因为大家对CSS已经很熟悉了。当需要联合查询时,使用querySelectorAll()更加便利。

  • 实例2】在文档中一些li元素的class名称是red,另一些是blue,可以用querySelectorAll()方法一次性获取这两类节点。
var lis = document.querySelectorAll("li.red, li.blue");

如果不使用querySelectorAll()方法,name要获取同样的列表,需要选择所有的li元素,然后通过迭代操作过滤出那些不需要的列表项目。

var result = [], lis1 = documentl.getElementByTagName('li'), classname = '';
for(var i = 0, len = lis1.length; i < len; i++){
    
    
	classname = lis1[i].className;
	if(classname === 'red' || classname === 'blue'){
    
    
		result.push(list[i]);
	}
}

比较上面两种方法,使用选择器querySelectorAll()方法比使用getElementByTagName()方法的性能要快得多。因此,如果浏览器支持document.querySelectorAll(),那么最好使用它。

猜你喜欢

转载自blog.csdn.net/weixin_46351593/article/details/108738229