安全建设的任务

JavaScript的常见用途和书写规范,持续更新中

  返回  

JavaScript:Dom知识点总结

2021/7/21 17:32:14 浏览:

目录

一、DOM简介

二、HTML DOM 树形结构:

三、DOM 节点

节点类型

节点父、子和同胞

(1) 父级节点

(2)子节点childNodes

(3)子节点children

(4)子节点first和last

(5)兄弟节点

四、DOM对象

1、查找 HTML 元素常用方法

(1)get方法

(2) querySelector 和 querySelectorAll

(3)获取特殊元素(body,html)

2、事件基础

(1)事件概述

(2)事件三要素

​(3) 事件汇总

3、改变元素内容 

(1)innerText和innerHTML

(2)常用元素的属性操作

(3)样式属性操作

(4)案例

4、自定义属性

(1) 获取属性值

(2)设置属性值

(3)移除属性

(4)H5自定义属性

5、创建、添加、删除、复制节点

(1)创建节点

(2)添加节点

(3)删除节点

(4)复制节点(克隆节点)

(5)三种动态创建元素区别


一、DOM简介

DOM (Document Object Model) 译为文档对象模型,是 HTML 和 XML 文档的编程接口。

HTML DOM 定义了访问和操作 HTML 文档的标准方法。

DOM 以树结构表达 HTML 文档。

通过可编程的对象模型,JavaScript 获得了足够的能力来创建动态的 HTML:

  • JavaScript 能够改变页面中的所有 HTML
  • 元素 JavaScript 能够改变页面中的所有 HTML 属性
  • JavaScript 能够改变页面中的所有 CSS 样式
  • JavaScript 能够对页面中的所有事件做出反应

二、HTML DOM 树形结构:

 

  • 文档:一个页面就是一个文档,DOM 中使用 document 表示
  • 元素:页面中的所有标签都是元素,DOM 中使用 element 表示
  • 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示

三、DOM 节点

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:

  • 整个文档是一个文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

节点类型

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个
基本属性。
  • 元素节点 nodeType 为 1
  • 属性节点 nodeType 为 2
  • 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
我们在实际开发中,节点操作主要操作的是 元素节点

节点父、子和同胞

节点树中的节点彼此拥有层级关系。

我们常用父(parent)子(child)同胞(sibling)等术语来描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。

  • 在节点树中,顶端节点被称为根(root)。
  • 每个节点都有父节点、除了根(它没有父节点)。
  • 一个节点可拥有任意数量的子节点。
  • 同胞是拥有相同父节点的节点。

下面的图片展示了节点树的一部分,以及节点之间的关系:

(1) 父级节点

node.parentNode
  • parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
  • 如果指定的节点没有父节点则返回 null

(2)子节点childNodes

parentNode.childNodes(标准)
parentNode.childNodes 返回包含指定节点的子节点的 集合 ,该集合为即时更新的集合。
注意: 返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如:
<ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>

    </ul>
 var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        // 1. 子节点  childNodes 所有的子节点 包含 元素节点 文本节点等等
        console.log(ul.childNodes);

结果:

 换行属于text节点

如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) {
// ul.childNodes[i] 是元素节点
 console.log(ul.childNodes[i]);
} }

(3)子节点children

parentNode.children(非标准)
parentNode.children 是一个只读属性,返回 所有的子元素节点 。它只返回子元素节点,其余节点不返回 ( 这个是我们重点掌握的 )。
虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用

(4)子节点first和last

 parentNode.firstChild

firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。

parentNode.lastChild
lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
parentNode.firstElementChild

firstElementChild 返回第一个子元素节点,找不到则返回null。

 parentNode.lastElementChild

lastElementChild 返回最后一个子元素节点,找不到则返回null。

<!DOCTYPE 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>Document</title>
</head>

<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
        <li>我是li5</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1. firstChild 第一个子节点 不管是文本节点还是元素节点
        console.log(ol.firstChild);
        console.log(ol.lastChild);
        // 2. firstElementChild 返回第一个子元素节点 ie9才支持
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);
        // 3. 实际开发的写法  既没有兼容性问题又返回第一个子元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
    </script>
</body>

</html>

结果:

(5)兄弟节点

同上一个,直接上代码

<!DOCTYPE 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>Document</title>
</head>

<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
        console.log(div.nextSibling);
        console.log(div.previousSibling);
        // 2. nextElementSibling 得到下一个兄弟元素节点
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>
</body>

</html>

四、DOM对象

当浏览器载入 HTML 文档, 它就会成为 Document 对象

Document 对象是 HTML 文档的根节点
Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问 

提示: Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。

1、查找 HTML 元素常用方法

(1)get方法

方法描述
getElementById()返回带有指定 ID 的元素。
getElementsByTagName()返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByClassName()返回包含带有指定类名的所有元素的节点列表。
// 返回ID为'test'的节点:
var test = document.getElementById('test');

// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');

// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');

(2) querySelector querySelectorAll

注意:querySelector querySelectorAll里面的选择器需要加符号,比如:

document.querySelector('#nav');

<!DOCTYPE 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>Document</title>
</head>

<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
        // 1. getElementsByClassName 根据类名获得某些元素集合
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);
        // 2. querySelector 返回指定选择器的第一个元素对象  切记 里面的选择器需要加符号 .box  #nav
        var firstBox = document.querySelector('.box');
        console.log(firstBox);
        var nav = document.querySelector('#nav');
        console.log(nav);
        var li = document.querySelector('li');
        console.log(li);
        // 3. querySelectorAll()返回指定选择器的所有元素对象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);
        var lis = document.querySelectorAll('li');
        console.log(lis);
    </script>
</body>

</html>

(3)获取特殊元素(body,html)

获取body元素
doucumnet.body // 返回 body 元素对象
获取html元素
document.documentElement // 返回 html 元素对象

2、事件基础

在学习DOM的增删改查之前,我们先了解一下什么是事件。

(1)事件概述

JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
简单理解: 触发--- 响应机制
网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个 事件,然后去执行某些操作

(2)事件三要素

  1. 事件源 (谁)
  2. 事件类型 (什么事件)
  3. 事件处理程序 (做啥)

例子

<!DOCTYPE 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>Document</title>
</head>

<body>
    <button id="btn">唐伯虎</button>
    <script>
        // 点击一个按钮,弹出对话框
        // 1. 事件是有三部分组成  事件源  事件类型  事件处理程序   我们也称为事件三要素
        //(1) 事件源 事件被触发的对象   谁  按钮
        var btn = document.getElementById('btn');
        //(2) 事件类型  如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
        //(3) 事件处理程序  通过一个函数赋值的方式 完成
        btn.onclick = function() {
            alert('点秋香');
        }
    </script>
</body>

</html>

(3) 事件汇总

下面总结一些常用的事件。

鼠标事件

属性描述
onclick当用户点击某个对象时调用的事件句柄。
oncontextmenu在用户点击鼠标右键打开上下文菜单时触发
ondblclick当用户双击某个对象时调用的事件句柄。
onmousedown鼠标按钮被按下。
onmouseenter当鼠标指针移动到元素上时触发。
onmouseleave当鼠标指针移出元素时触发
onmousemove鼠标被移动。
onmouseover鼠标移到某元素之上。
onmouseout鼠标从某元素移开。
onmouseup鼠标按键被松开。

键盘事件

属性描述
onkeydown某个键盘按键被按下。
onkeypress某个键盘按键被按下并松开。
onkeyup某个键盘按键被松开。

表单事件

属性描述
onblur元素失去焦点时触发
onchange该事件在表单元素的内容改变时触发( <input>, <keygen>, <select>, 和 <textarea>)
onfocus元素获取焦点时触发
onfocusin元素即将获取焦点时触发
onfocusout元素即将失去焦点时触发
oninput元素获取用户输入时触发
onreset表单重置时触发
onsearch用户向搜索域输入文本时触发 ( <input="search">)
onselect用户选取文本时触发 ( <input> 和 <textarea>)
onsubmit表单提交时触发

 剪贴板事件

属性描述
oncopy该事件在用户拷贝元素内容时触发
oncut该事件在用户剪切元素内容时触发
onpaste该事件在用户粘贴元素内容时触发

完整版事件见如下链接:https://www.runoob.com/jsref/dom-obj-event.html

3、改变元素内容 

(1)innerText和innerHTML

element.innerText

从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉

element.innerHTML

起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行

(2)常用元素的属性操作

1. innerText、innerHTML 改变元素内容
2. src、href
3. id、alt、title

(3)样式属性操作

我们可以通过 JS 修改元素的大小、颜色、位置等样式。
1. element.style 行内样式操作
2. element.className 类名样式操作

注意1

1.JS 里面的样式采取驼峰命名法 比如 fontSize backgroundColor
2.JS 修改 style 样式操作,产生的是行内样式, CSS 权重比较高
注意2
1. 如果样式修改较多,可以采取操作类名方式更改元素样式。
2. class 因为是个保留字,因此使用 className 来操作元素类名属性
3. className 会直接更改元素的类名,会覆盖原先的类名

(4)案例

见:

javascript中的排他思想

javascript:点击小图片切换背景图片

javascript:dom案列实现勾选框的全选反选

4、自定义属性

(1) 获取属性值

  • element.属性 
  • element.getAttribute('属性')

区别:
  • element.属性 获取内置属性值(元素本身自带的属性)
  • element.getAttribute(‘属性’); 主要获得自定义的属性 (标准) 我们程序员自定义的属性

(2)设置属性值

  • element.属性 = ‘值’ 
  • element.setAttribute('属性', '')

区别:
  • element.属性 设置内置属性值
  • element.setAttribute(‘属性’); 主要设置自定义的属性 (标准)

(3)移除属性

  • element.removeAttribute('属性')
<!DOCTYPE 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>Document</title>
</head>

<body>
    <div id="demo" index="1" class="nav"></div>
    <script>
        var div = document.querySelector('div');
        // 1. 获取元素的属性值
        // (1) element.属性
        console.log(div.id);
        //(2) element.getAttribute('属性')  get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index
        console.log(div.getAttribute('id'));
        console.log(div.getAttribute('index'));
        // 2. 设置元素属性值
        // (1) element.属性= '值'
        div.id = 'test';
        div.className = 'navs';
        // (2) element.setAttribute('属性', '值');  主要针对于自定义属性
        div.setAttribute('index', 2);
        div.setAttribute('class', 'footer'); // class 特殊  这里面写的就是class 不是className
        // 3 移除属性 removeAttribute(属性)    
        div.removeAttribute('index');
    </script>
</body>

</html>

(4)H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
自定义属性获取是通过getAttribute(‘ 属性 ’) 获取。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
H5 给我们新增了自定义属性:
1. 设置H5自定义属性
H5规定自定义属性data-开头做为属性名并且赋值。
比如 <div data-index=“1”></div>
或者使用 JS 设置
element.setAttribute(‘data-index’, 2)
2. 获取H5自定义属性
1.
兼容性获取 element.getAttribute(‘data-index’);
2.
H5新增 element.dataset .index 或者 element.dataset [‘index’]                ie 11才开始支持
<!DOCTYPE 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>Document</title>
</head>

<body>
    <div getTime="20" data-index="2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getTime);
        console.log(div.getAttribute('getTime'));
        div.setAttribute('data-time', 20);
        console.log(div.getAttribute('data-index'));
        console.log(div.getAttribute('data-list-name'));
        // h5新增的获取自定义属性的方法 它只能获取data-开头的
        // dataset 是一个集合里面存放了所有以data开头的自定义属性
        console.log(div.dataset);
        console.log(div.dataset.index);
        console.log(div.dataset['index']);
        // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>
</body>

</html>

5、创建、添加、删除、复制节点

(1)创建节点

document.createElement('tagName')
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,
是根据我们的需求动态生成的,所以我们也称为 动态创建元素节点。

(2)添加节点

1. node.appendChild(child)
node.appendChild() 方法将一个节点添加到指定父节点的子节点列表 末尾 。类似于 CSS 里面的
after 伪元素。
2. node.insertBefore(child, 指定元素)
node.insertBefore() 方法将一个节点添加到父节点的指定子节点 前面 。类似于 CSS 里面的 before
伪元素。

(3)删除节点

node.removeChild(child)
node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点。

(4)复制节点(克隆节点)

node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
注意:
1. 如果括号参数为 空或者为 false ,则是 浅拷贝 ,即只克隆复制节点本身,不克隆里面的子节点。
2. 如果括号参数为 true ,则是 深度拷贝 ,会复制节点本身以及里面所有的子节点。

(5)三种动态创建元素区别

  • document.write()
  • element.innerHTML
  • document.createElement()
区别
  1.  document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
  3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
  4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结 不同浏览器下, innerHTML 效率要比 creatElement

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号