JavaSceipt学习笔记:操作DOM

概述

全局的Window对象有一个document属性,它引用一个Document对象,通过该对象操作DOM。

选择DOM元素

HTML文档中的<head>与<body>标签可以通过Document对象的head与body属性访问,但是更深层级的元素需要通过查询来获取。
有两组方法来选择元素,一组是通过CSS选择符来选择,另一组数通过元素的标签名、ID等来选择。

通过CSS选择符

document.querySelector()与document.querySelectorAll()是通过CSS选择符来选择DOM元素的。除了Document对象,这两个方法在Element对象上也上有定义。

querySelector()方法选择与选择符匹配的第一个子元素,若找不到返回null;
querySelectorAll()选择所有与选择符匹配的子元素,返回一个包含这些元素的NodeList对象,若找不到元素则该NodeList对象为空。NodeList是一个类数组对象。

Element.closest()也通过CSS选择符来选择元素,但是它的行为与querySelector()恰好相反。
它选择与选择符匹配的第一个祖先元素或自身,若匹配不到则返回努null。

CSS选择符的常用规则

标签名表示HTML标签,如div选择div元素;
#开头表示标签id,如#sidebar
.开头表示标签class,如'.pop';
以中括号表示任意属性,如[lang="fr"]
多个选择符可以组合,如a.link[lang][name="foo"];

选择符还可以指明文档的结构:
以空格分隔表示选择后代元素,如p span
>分隔表示选择子子元素,如p.log > a
+分隔表示选择后面紧跟的元素,如a+img
~分隔比哦啊是选择后面所有的同辈元素,如h2~p
:first-child:last-child选择头一个或最后一个子元素;

若多个选择符被,分隔,表示选择与其中任意一个选择符所匹配的元素,如button,input[type="button"]

不能被选择的CSS选择符

  • 伪元素表示元素的一部分,不匹配元素本身,不能被选择。如::before,::first-line等;
  • 部分伪类会暴露用户的浏览历史,出于安全与保护隐私的考虑,它们也不能被选择:
    • :link:尚未被访问的元素
    • :visited: 会在用户访问链接后生效

getElement系列方法

该系列方法的传值与CSS选择符没有任何关系。

  • Document.getElementById()
    通过标签的id属性值选择元素,只在Document对象上定义。

  • Document.getElementsByName()
    通过标签的name属性值选择元素,只在Document对象上定义。

  • getElementsByTagName()
    通过标签名选择元素,在Document与Element对象上都有定义。

  • getElementsByClassName()
    通过标签的类名选择元素,在Document与Element对象上都有定义。

预选择元素

Document对象预定义了一些属性作为预选择的元素。
除了head与body,其他属性都引用一个HTMLCollection对象:

  • images: 所有的<img>标签
  • links: 所有<a>标签
  • forms: 所有<form>标签

HTMLCollection对象与NodeList对象类似,都是类数组对象。但HTMLCollection对象可以通过DOM元素的id来访问特定的DOM元素。

document.all引用一个HTMLAllCollection对象,它包含文档中所有的元素,但是它被废弃了。

通过Element对象的属性访问特定元素

Element对象上有一组属性用于访问当前元素的父级、子级、同级的Element节点:

  • parentNode: 父节点,Element或Document对象,若不存在返回null。
  • childern: 包含所有Element子节点的HTMLCollection对象。
  • childElementCount: 所有Element节点的数量。
  • firstElementChild / lastElementChild: 头一个/最后一个Element子节点。不存在返回null。
  • previousElementSibling / nextElementSibling: 前一个/后一个Element节点。不存在返回null

Node对象上的一组属性用于取得所有类型的特定的节点,包含Element、Text与Comment节点:

  • parentNode: 父节点,Element或Document对象,若不存在返回null。
  • childNode: 只读的NodeList对象。包含所有子节点。
  • firstChild / lastChild: 头一个或最后一个子节点。没有子节点返回null。
  • nodeType: 当前节点的类型。Document为9,Element为1,Text为3,Comment为8。
  • NodeValue:Text或Comment节点的内容。
  • NodeName:Element节点的标签名,会转化为大写。

HTML标签属性与HTML元素属性

HTML标签都有对应的HTML元素,这些元素上定义了一些属性来镜像HTML标签的属性,可以被读写。
如id,title,onclick等是所有元素都有的属性。
但是特定的元素有自己所特有的属性,如:
对应<img>标签的HTMLImageElement元素的src属性;
对应<form>标签的HTMLFormElement元素的action与method属性。

另外,值得注意的是,<input>标签的value属性对应HTMLInputElement对象的defaultValue属性,而HTMLInputElement对象的value属性对应用户在<input>标签中输入的值。

创建、插入、删除节点

  • Document.createElement()
    传入标签名,创建指定的HTML元素
  • Element.append() / Element.prepend()
    向元素中末尾或开头插入一个或多个节点,支持Node对象与字符串参数
    element.append(document.createElement('p'), 'DOMString');
    
  • Element.before() / Element.after()
    在元素之前或之后插入一个或多个节点,支持Node对象与字符串参数
  • Element.remove()
    将节点从DOM树删除
  • Element.replaceWith()
    以指定的节点替换当前节点,接收一个或多个参数,支持Node对象与字符串。
  • appendChild() | insertBefore() | replaceChild() | removeChild()
    这些方法与上面方法功能一致,但是不如上面的方法好用。

操作元素属性

HTML标签属性与JS中元素属性的对应规则简单分为以下几点:

  • 单个单词,全小写
  • 连字符分隔的多个单词,以驼峰规则命名
  • JS保留字加html前缀,如for对应htmlFor
  • html标签属性值多为字符串,也可能是数字或布尔值,在JS中也是对应的。事件处理程序在html在可以是代码,但是在js中只能是函数或null。

HTML元素的属性不能通过delete关键字删除,要使用removeAttribute()来删除。
通过setAttribute()与getAttribute()来获取与设置元素属性。

操作class属性

标签class属性有两个对应的元素属性,className值为字符串,classList是一个DOMTokenList对象,它是类数组对象,可迭代。
DOMTokenList对象定义了add(),remove(),replace(),contains(),toggle()等方法来操作class属性。
toggle()方法很有意思,它为元素添加或删除类,取决于元素是否存在指定的类。

dataset属性

在HTML中,以data-开头的小写属性名都是有效的,可以通过元素对象的dataset属性类访问。
data-foo对应dataset.foo,data-foo-bar对应dataset.fooBar

操作元素内容

innerHTML属性为元素的HTML字符串,而textContent为剔除HTML标签的文本。
为innerHTML赋值,会解析该值并为元素替换内容。
不要为innerHTML使用+=赋值,效率不高。
不要将用户输入插入到文档,以防止XXS跨网站脚本攻击。

outerHTML包含元素自身的HTML字符串,对其赋值会取代元素自身。

Element.insertAdjacentHTML()用于向元素的特定位置插入字符串,它不会解析当前元素,不会序列化当前元素内容,比innerHTML效率要高。
第一个参数为插入位置,第二个参数为插入内容。
支持以下位置:

  • 'beforebegin':元素自身的前面。
  • 'afterbegin':插入元素内部的第一个子节点之前。
  • 'beforeend':插入元素内部的最后一个子节点之后。
  • 'afterend':元素自身的后面。
Element.insertAdjacentHTML('beforebegin', 'DOMString');

textContent属性返回元素的文本内容,对于Element元素,它返回自身及所有子元素的文本。

没有src属性的<script>标签被称为行内标签,它有一个text属性,标签标签内的文本。
文档解析器会忽略其中的尖括号与&符号,且其内容永远不会在浏览器中显示。
这意味着只要将<script>标签的type属性设置为任何非text/javascript后,就可以在标签内嵌入任何文本。

posted @ 2023-06-17 01:26  钰琪  阅读(36)  评论(0编辑  收藏  举报