JS 学习笔记 | DOM 篇

本文详细介绍了DOM(文档对象模型)的概念及其在JavaScript中的应用。内容涵盖document对象的属性,如doctype、documentElement、body等,以及如何通过DOM操作页面元素,包括选择、创建和修改元素属性。此外,还探讨了Node节点的属性和方法,如appendChild、insertBefore等,以及HTML元素的相关属性。
摘要由CSDN通过智能技术生成

1.什么是 DOM

DOM 全称为 Document Object Model,即文档对象模型。它是一套用来管理控制 html 文档的规则。而 Document 节点则是一种具象化的表现形式。

假设我们把整个 html 文档看成一个对象,那么这个对象就是 Document 节点。
而我们如何操作、控制这个对象的标准,就是 DOM。

注意:DOM 中规定 html 页面中的 所有元素 都是节点。

2.怎么理解 document

document 节点又被叫做 document 对象。每个载入浏览器的 HTML 文档都会成为 document 对象。
document 对象使我们可以从脚本中对 HTML 页面的所有元素进行访问。
document 是 html 文档的根节点,每个网页都有自己的 document 节点。
window.document 属性就指向这个节点。也就是说只要浏览器开始载入 HTML 文档,这个对象就存在了,可以直接使用。
在这里插入图片描述

3.Document 节点属性

JavaScript 为 document 节点提供了很多属性方便我们更好的使用。相对用的比较多的有下面这些:

doctype、documentElement、body、head:返回文档内部的某个节点

3.1 doctype

对于 HTML 文档来说 document 对象一般有两个子节点,第一个节点就是 doctypedoctype 节点是一个对象,包含了当前文档类型信息。如果网页没有 DTD,该属性返回 null。
对于 HTML5 文档,doctype 节点就是 !DOCTYPE html>

语法:

document.doctype;
var doctype = document.doctype;
console.log(doctype);	// <!doctype html>
console.log(doctype.name);  // html

3.2 documentElement

documentElement 属性,表示当前文档的根节点。它通常是 document 节点的第二个子节点,紧跟在 document.doctype 后面。
对于 HTML 网页,该属性返回 HTML 节点。但是对我们来说一般都是通过 documentElement 节点来访问页面中的其它子节点。

语法:

document.documentElement;
console.log(document.documentElement);

在这里插入图片描述

3.3 body

body 属性返回当前文档的 bodyframeset 节点,如果不存在这样的节点,就返回 null
这个属性是可写的,如果对其写入一个新的节点会导致原有的所有子节点被移除。暂时我们不做考虑。

语法:

document.body;
console.log(document.body);

在这里插入图片描述

3.4 head

head 属性返回当前文档的 head 节点,如果当前文档有多个 head,则返回第一个

语法:

document.head;
console.log(document.head);

在这里插入图片描述
documentURI、URL、domain、lastModified、location、title、readyState:返回文档指定信息

3.5 documentURI

documentURI 属性返回当前文档的网址。documentURI 属性所有文档都具备。

语法:

console.log(document.documentURI);

3.6 URL

documentURI 属性返回当前文档的网址。URL 属性只有 HTML 文档才具备。

语法:

document.URL

3.7 domain

domain 属性返回当前文档的域名。
例如某张网页的网址是 http://www.example.com/hello.htmldomain 属性就等于 www.example.com。如果无法获取域名则返回 null

语法:

document.domain;

3.8 lastModified

lastModified 属性返回当前文档(网页)最后修改的时间戳,格式为字符串。

语法:

document.lastModified;	// 05/21/2020 21:50:10

注意lastModified 属性的值是字符串,所以不能用来直接比较。如果想要比较两个文档谁的日期更新,需要转成时间戳格式才能进行比较。

if (Date.parse(doc1.lastModified) > Date.parse(doc2.lastModified)) {
	// ...
}

注意:Date.parse 方法能够将时间格式字符串转换成时间戳格式。

3.9 location

location 属性返回一个只读对象,提供了当前文档的 URL 信息。

返回完整的 URL:document.location.href
返回当前遵守的协议:document.location.protocol
返回当前页面域名 + 端口号:document.location.host
返回当前页面域名:document.location.hostname
返回当前页面端口号,如果不存在返回空:document.location.port
返回当前页面在服务器中的路径:document.location.pathname
返回当前页面 URL 中的查询字符串:document.location.search
跳转到另一个网址:document.location.assign("http://google.com")

location 中有关的其它内容:
以下方法效果相同,都能改变当前页面的 url:

location.assign("传递一个 url");
window.location = "传递一个 url";
location.href = "传递一个 url";

reload():重新加载当前显示的页面。

location.reload(false);	// 优先从本地缓存重新加载
location.reload(true);	// 优先从服务器重新加载

location 对象的 search 属性代表 URL 的查询字符串(包括 ?)

// 查询字符串为 ?id=x&sort=name
var search = window.location.search;
search = search.slice(1);	// 得到 "id=x&sort=name"
search = search.split("&");	// 得到数组 ["id=x", "sort=name"]

3.10 title

title 属性返回当前文档的标题,该属性是可写的。

语法:

document.title;
document.title = "新标题";

3.11 characterSet

characterSet 属性返回渲染当前文档的字符集,比如 UTF-8、ISO-8859-1。

语法:

document.characterSet;

3.12 readyState

readyState 属性返回当前文档的状态。
共有三种可能值:

  • 加载 HTML 代码阶段(尚未完成解析)是 “loading”。
  • 加载外部资源文件阶段 “interactive”。
  • 全部加载完成是 “complete”。

anchors、forms、images、links、scripts:返回文档内部特定节点的集合。

anchors 属性返回网页中所有指定了 name 属性的 a 节点元素。
forms 属性返回网页中所有表单。
images 属性返回网页中所有图片。
links 属性返回网页中所有的链接元素(即带有 href 属性的 a 标签)
scripts 属性返回网页中所有脚本。

var scripts = document.scripts;
if (scripts.length !== 0) {
	console.log("当前网页有脚本!");
}

4.使用 Document 操作页面

4.1 选择页面元素

4.1.1 选择单个元素 方式1

querySelector() 方法返回匹配指定的 CSS 选择器的元素节点。如果有多个满足条件的节点,则返回第一个匹配的节点,如果没有发现匹配的节点则返回null

例如:

<a href="" class="aLink1">123</a>
<a href="" class="aLink2">456</a>
<script>
    var aLink = document.querySelector("a");
    console.log(aLink.innerHTML);   // 123 
</script>

注意querySelector() 是匹配的选择器,如果选择器为类选择器时参数应该为".类名"

4.1.2 选择单个元素 方式2

  • getElementById():返回匹配指定 id 属性的元素节点。
  • getElementsByTagName():返回所有指定标签的元素。
  • getElementsByClassName():返回符合指定类名的所有元素。
  • getElementsByByName():用于选择拥有 name 属性的 HTML 元素。

4.1.3 选择所有元素

querySelectorAll() 方法用来选中页面元素,根据指定的选择器进行筛选。如果有多个元素满足条件,则返回这些元素构成的集合。

语法:

document.querySelectorAll("选择器名");

注意

  • 返回的结果是一个节点列表,不是数组,但能够像数组一样使用列表。
  • 如果查询失败不是返回 null,而是返回一个空的节点列表。

4.2 创建页面元素

4.2.1 创建元素

createElement() 生成 html 元素节点

语法:

document.createaElement("标签名");
var newP = document.createElement("p");
document.body.appendChild(newP);

直接创建一个按钮根本没办法直观看到,因此通过 appendChild() 的方式添加到 body 中。appendChild() 方法的作用能够将代码创建的元素添加到指定位置。

注意:这样创建的元素并没有内容,也没有属性,而是默认存在于内存中。在页面开发中的实用性较差。因此如果需要创建一个带有内容或者带有属性的元素就需要用到下面的两个方法来配合。

4.2.2 生成文本节点

createTextNode(),参数为想要生成的文本内容。

语法:

var newP = document.createElement("p");
var pText = document.createTextNode("这是 p 的文本节点内容");
newP.appendChild(pText);
document.body.appendChild(newP);

4.2.3 生成新的属性对象节点

createAttribute() 生成新的属性对象节点,并返回它。

语法:

var newP = document.createElement("p");
var pText = document.createTextNode("这是 p 的文本节点内容");
newP.appendChild(pText);
var pStyle = document.createAttribute("style");
// 创建的属性节点使用 value = "" 的形式赋值
pStyle.value = "color: cyan;";
// 将属性绑定到节点上
newP.setAttributeNode(pStyle);
document.body.appendChild(newP);

注意:本方法创建的是属性节点,不是 CSS 属性节点。

4.3 操作页面的元素属性

CSS 和 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但它们毕竟同属网页开发中的技术,因此不可避免的会有交叉和相互配合。
所以在整体页面的布局中我们推荐使用 HTML + CSS 的方式来编写页面的结构和样式,在细节以及交互模块的编写过程中我们推荐使用 JS 的方式来辅助编写。

很显然,对于整个 HTML 页面来说,CSS 部分所代表的样式就显得更为重要一些。因为这些样式能够决定我们的页面整体显示效果,因此 JS 中也提供了几种操作页面元素属性的方法:

4.3.1 元素节点特性方法

getAttribute()setAttribute()removeAttribute()

操作 Element 节点的 CSS 样式,最简单的方法之一就是使用节点对象的 getAttribute 方法和 removeAttribute 方法,读写或删除 HTML 元素的 style 属性。

语法:

getAttribute("属性名");
setAttribute("属性名", "属性值");
removeAttribute("属性名");
var div = document.querySelector("div");
   div.setAttribute("style", "width: 200px; height: 200px;" + 
       "background-color: red; border: 1px solid black");
   console.log(div.getAttribute("style"));
   div.removeAttribute("style");

4.3.2 元素节点的 style 属性

Element 节点本身还提供 style 属性,用来操作 CSS 样式。style 属性指向一个对象,用来读写页面元素的行内 CSS 样式。

语法:

var divStyle = document.querySelector("div").style;
console.log(divStyle);
divStyle.width = "200px";
divStyle.height = "200px";
divStyle.border = "1px solid black";
divStyle.backgroundColor = "green";
divStyle.cssFloat = "left";

4.3.3 元素节点的 style 属性的 cssText 写法

style 对象的 cssText 属性可以用来读写或删除整个 style 属性。因此上面的写法可以改写成:

divStyle.cssText = "backgroundColor: green; float: right; width: 200px; height: 200px;" 
+ "border: 1px solid black;"

注意

  • 该方式删除整个 style 属性可以用 divStyle.cssText = ''; 这种写法
  • cssText 对应的是 HTML 元素的 style 属性,所以不用改写 CSS 属性名。

4.3.4 元素节点的 style 属性方法

setProperty()getPropertyValue()removeProperty()

style 对象提供了三个方法来读写行内 CSS 规则:

  • setProperty(propertyName, value):设置某个 CSS 样式。
  • getPropertyValue(propertyName):读取某个 CSS 属性。
  • removeProperty(propertyName):删除某个 CSS 属性。

这三个方法的第一个参数,都是 CSS 属性名,且不用改写连词线。

语法:

var divStyle = document.querySelector("div").style;
divStyle.setProperty("background-color", "red");
divStyle.getPropertyValue("background-color");
divStyle.removeProperty("background-color");

5.Node

5.1 Node 概述

DOM 是文档对象模型的简称,它的基本思想是:
把结构化文档解析成一系列节点,再由这些节点解析成一个树状结构(DOM Tree)。
所有的节点和最终的树状结构,都有规范的对外接口,以达到使用编程语言操作文档的目的。
所以,DOM 可以理解成文档编程接口。
在这里插入图片描述
注意:严格地说,DOM 不属于 JavaScript,但是操作 DOM 是 JavaScript 最常见的任务。而 JavaScript 也是最常用于 DOM 操作的语言,所以 DOM 往往放在 JavaScript 中介绍。

node 是 DOM 的最小组成单位,一个文档的树形结构就是由各种不同类型的节点组成。
对于HTML 文档,node 主要有以下 6 种类型:
在这里插入图片描述

5.2 Node 的属性

5.2.1 通用属性

  • nodeName:返回节点的名称
  • nodeType:返回节点的类型
    在这里插入图片描述

5.2.2 返回当前 node 的相关节点属性

  • ownerDocument
    返回当前节点所在的顶层文档对象,除 document 节点会返回 null,其它节点全部返回 #document
  • nextSibling
    返回紧跟在当前节点后面的第一个同级节点,如果当前节点后面没有同级节点则返回 null
    注意:该属性可以得到文本节点和评论节点。因此如果当前节点后面有空格,该属性会返回一个文本节点,内容为空格
  • previousSibling
    返回当前节点的前一个同级节点,如果前面没有同级节点则返回 null
    注意:该属性可以得到文本节点和评论节点。因此如果当前节点后面有空格,该属性会返回一个文本节点,内容为空格
  • parentNode
    parentNode 属性返回当前节点的父节点,如果当前节点没有父节点,则返回 nulldocument 节点)。
    注意:一般情况下,一个节点的父节点只可能是三种类型:element 节点、document 节点和 documentFragment 节点。
  • parentElement
    parentElement 属性返回当前节点的父元素节点,如果当前节点没有父节点,或者父节点类型不是 Element 节点,则返回 null
    注意parentElement 是 IE 所独有的属性,其能实现的功能 parentNode 都能实现。可以说 parentNodeparentElement 的标准版本。

5.2.3 返回 node 内容属性

  • textContent
    textContent 属性返回当前节点和它所有后代节点的文本内容。
    注意textContent 属性,自动忽略当前节点内部的 HTML 标签,返回所有文本內容(包含空格)。
  • nodeValue
    nodeValue 属性返回或设置当前节点的值,格式为字符串。
    但是 nodeValue 只对 Text 节点、Comment 节点、XML 文档的 CDATA 节点有效,其它类型的节点一律返回 null
    因此,nodeValue 属性只用于 Text 节点。对于那些返回 null 的节点,设置 nodeValue 属性是无效的

5.2.4 返回当前 node 子节点相关信息

  • childNodes
    该属性会返回一个节点集合(NodeList),节点集合包括当前节点的所有子节点。
    需要指出的是,除了 HTML 中的元素节点之外,该属性返回的还包括 Text 节点和 Comment 节点。
    如果当前节点不包括任何子节点,则返回一个空的 NodeList 集合
    注意:由于 NodeList 对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果当中。
  • firstChild
    该属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回 null。需要注意的是,除了 HTML 元素子节点,该属性还包括文本节点和评论节点
  • lastChild
    该属性返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回 null

5.3 Node 的方法

5.3.1 appendChild()

appendChild() 方法接收一个节点对象为参数,将其作为最后一个子结点,插入当前节点。

var p = document.createElement("p");
document.body.appendChild(p);

5.3.2 hasChildNodes()

hasChildNodes() 方法返回一个布尔值,表示当前节点是否有子节点。

var foo = document.getElementById("foo");
if (foo.hasChildNodes()) {
	
}

5.3.3 cloneNode()

cloneNode() 方法用于克隆一个节点。它接收一个布尔值作为参数,表示是否同时克隆子节点,默认是 false,即不克隆子节点(浅克隆)。如果传入 true 会克隆子节点(深克隆)。
注意:克隆一个节点,会拷贝该节点的所有属性,但不包括 addEventListener()on-属性(例如 onclick = function() {}) 这种节点上的回调函数。

5.3.4 insertBefore()

insertBefore() 方法用于将某个节点插入当前节点的指定位置。
它接收两个参数,第一个参数是所要插入的节点,第二个参数是当前节点的子节点,新的节点将插在这个节点的前面。该方法返回被插入的新节点。

var ul = document.querySelector("ul");
var li = document.createElement("li");
var liText = document.createTextNode("1");
li.appendChild(liText);
ul.insertBefore(li, ul.firstChild);

上面的代码作用是将新建的 li 插入到 ul 的第一个子节点的前面。

5.3.5 removeChild()

removeChild() 方法接收一个子节点作为参数,用于从当前节点移除该节点,并且返回被移除的节点。

5.3.6 replaceChild()

replaceChild() 方法用于将一个新的节点,替换当前节点的某个子节点。
它接收连个参数,第一个参数是用来替换的新节点,第二个参数是将要被替换走的子节点,最终返回被替换走的那个节点。
语法:

var replaceNode = parentNode.replaceChild(newChild, oldChild);

例如:

var div = document.querySelector("div");
var span = document.createElement("span");
span.innerHTML = "这是一个 span";
document.querySelector("button").onclick = function() {
    div.parentNode.replaceChild(span, div);
}

以上代码的作用是使用新创建出的 span 的內容替代 div 的內容。

5.3.7 contains

contains()` 方法接收一个节点作为参数,返回一个布尔值。该方法用于判断 参数节点 是否为 当前节点 的 子节点。

5.3.8 isEqualNode

isEqualNode() 方法返回一个布尔值,用于检查两个节点是否相等。
语法:

node.isEqualNode("待比较节点");

注意:所谓相等是指两个节点的类型相同、属性相同、子节点相同。

5.4 Node 其它內容

5.4.1 HTML 元素

html 元素是网页的根元素,document.documentElement 就指向这个元素。JS 中关于 html 元素也提供了一些相关的属性和方法来帮助我们更好的操作:

  • 视图窗口大小:clientWidth 属性,clientHeight 属性
  • html 元素大小:offsetWidth 属性,offsetHeight 属性
var html = document.documentElement;
// 当前窗口的大小多大,clientXXX 的值就是多大
console.log("html clientWidth: " + html.clientWidth);
console.log("html clientHeight: " + html.clientHeight);
// HTML 元素多大,offsetXXX 的值就是多大
console.log("html offsetWidth: " + html.offsetWidth);
console.log("html offsetHeight: " + html.offsetHeight);

5.4.2 元素位置相关属性

  • offsetParent
    该属性表示获取 当前元素 的最靠近的、并且 CSS 的 position 属性不等于 static 的父元素。
    <p id="p-id" style="position: relative;">
        <span id="span-id">
            <a href="#" id="a-id">test-a</a>
        </span>
    </p>
    
    var a = document.querySelector("#a-id");
    var aParent = a.offsetParent;
    console.log(aParent);
    
    运行结果:在这里插入图片描述
  • offsetTop:当前 HTML 元素左上角相对于 offsetParent 的垂直位移。
  • offsetLeft:当前 HTML 元素左上角相对于 offsetParent 的水平位移。

5.4.3 querySelector 和 getElementsBy 系列的方法对比

  • 两者的 W3C 标准不同
    querySelector 系列属于 W3C 中的 Selectors API(JS)规范。
    getElementsBy 系列属于 W3C 中的 DOM 规范。
  • 两者浏览器的兼容不同
    querySelector 系列基本能被所有浏览器支持。
    getElementsBy系列通常只有在考虑兼容性的时候才被提起。
  • 接收参数不同
    querySelector 系列接收的参数是一个 CSS 选择器名。
    getElementsBy 系列接收的参数只能是单一的 className、tagName、id。
  • 返回值不同
    querySelectorAll 返回的是一个静态节点列表(Static NodeList)
    getElementsBy 系列返回的是一个动态节点列表(Live NodeList)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值