每个人都看得懂的 DOM(文档对象模型) 教学

DOM


DOM(Document Object Model)—— 文档对象模型。在浏览器眼里,网页的结构可不是我们看到的这个样子,而是一棵树,我们称之为 DOM 树。网页中一个个标签就是这棵树上的节点,所以当我们需要改变 HTML(网页) 的结构时,就需要使用 JavaScript 操作 DOM 树中的节点

随便一棵 DOM 树的结构:

50



我们简单分析一下这棵树,首先是大家熟悉的 head 和 body 标签,head 标签中有 title 标签,代表网页的标题;body 中有一个链接标签和一级标题,对应的代码如下:

<!-- 是不是很好理解呢(这里不写其他多余的东西) -->
<html>

<head>
    <title>文档标题</title>
</head>

<body>
    <!-- 这里 href 属性图中并没有给出具体的链接地址 -->
    <a href="#">我的链接</a>
    <h1>我的标题</h1>
</body>
    
</html>

对于 DOM 节点的操作无非就是【获取、更新、删除、插入】,用到的对象就是 BOM 中的 document(不知道 BOM 也没关系)



1、获取 DOM 节点

常用的获取 DOM 节点有以下 4 种方式

  • 通过元素 id 查找元素(最常用):document.getElementById(‘id 名’)
  • 通过类名来查找元素:document.getElementsByClassName(‘类名’)
  • 通过标签名来查找元素:document.getElementsByTagName(‘标签名’)
  • 通过元素 name 来查找元素:document.getElementsByName(‘元素名’)
<!-- 我们先写一个简单的网页(CSS 代码直接写在标签内了,省点空间) -->

<body style="width: 200px; text-align: center; border: 5px solid black">

<dl id="app">
    <dt style="font:bolder normal 20px 宋体">***** DOM *****</dt>
    <dd id="first" style="margin-left: 0">第一个节点</dd>
    <dd class="second" style="margin-left: 0">第二个节点</dd>
    <dd name="third" style="margin-left: 0">第三个节点</dd>
</dl>

</body>

网页长这个样子:

51


好心提醒一下:这三个节点分别设置了 id、class、name 属性,不要眼挫全都看成 id 了!

function func1() {
    
      
    
    //1、按照 id 选择节点,因为 id 是唯一的,所以能直接定位到目标节点(最常用)
    let first = document.getElementById('first');

    //2、按照 class 名字选择节点,细心的你们发现函数名 Elements 带上 s 了嘛,这是因为通过 class 获取的元素有很多
    let second = document.getElementsByClassName('second');

    //3、按照标签名选择节点(也很常用,而且可以进行拓展),同样一次可以选取多个
    let third = document.getElementsByTagName('dt');

    //4、按照 name 选择节点(不常用,这里不详细说了),也是一次选取多个
    let forth = document.getElementsByName('third');
    
    console.log(first);
    console.log(second);
    console.log(third);
    console.log(forth);
}

控制台显示结果(注意红色标注):

52


可以看到除了 id 选择,其它都以 数组 的形式呈现(原因代码上已经注释了)

除了上边 4 种直接查找,我们是否可以利用树的结构实现间接查找呢?当然可以,既然是 DOM 树,无非就利用父节点找孩子节点呗:

function func2(){
    
    
    //先通过 id 找到父节点
    let father = document.getElementById('app');

    //然后使用父节点的 firstElementChild 属性找到其第一个孩子节点(在这里就是 "***** DOM *****")
    let first_child = father.firstElementChild;
    
    //同理,找到父节点最后一个孩子节点(这里是 "第三个节点")
    let last_child = father.lastElementChild;
    
    console.log(first_child);
    console.log(last_child);
}

控制台显示结果(结果应该都能看懂吧):

53



.2、更新 DOM 节点

当我们获取一个 DOM 节点后,可以更新其文本内容或者 CSS 样式。具体我们将通过 innerHTML 或者 innerText 属性实现更新操作

innerHTML:功能强大,但安全方面需要注意

function func3() {
    
    

    //1、使用 innerHTML 最基本的功能就是更新节点中的文本
    let first = document.getElementById('first');   //获取 id = 'first' 的节点
    first.innerHTML = 'The first node';             //将其文本内容更新为 'The first node'


    //2、除了可以更新文本外,还可以添加新的 HTML 标签
    let second = document.getElementsByClassName('second');//获取 class = 'second' 的节点
    /* 然后看下面一长串,我们首先更改了节点的内容(将 '第二个节点' 改为 'The second node')
       接下来按照 HTML 的格式,添加以下内容(写成你们熟悉的格式):
       <ul>
           <li class="lg">HTML</li>
           <li class="lg">CSS</li>
           <li class="lg">JavaScript</li>
       </ul>

       注意:所有的内容都需要写在单引号内! */
    second[0].innerHTML = 'The second node <ul><li class="lg">HTML</li><li class="lg">CSS</li><li class="lg">JavaScript</li></ul>';
}

浏览器执行 func3():

54


当然除了基本的文本内容,节点还具有 style 属性,自然可以修改样式:

/* 使用 style 格式:
   节点名称.style.样式名称 = '样式值' 
   
   注意:样式名称不要使用 - 连接,而要采用 驼峰命名法!例如 font-size 要写成 fontSize */

function func4() {
    
    
    let language = document.getElementsByClassName('lg');   //获取新增的三个节点
    let colorArray = ['green', 'orange', 'blue']
    for (let i = 0; i < language.length; i++) {
    
    
        language[i].style.color = colorArray[i];     //修改它们的颜色
        language[i].style.listStyle = 'none';        //将它们前面的圆点去掉(驼峰命名法)
    }
}

注意,这里必须先执行 func3(),再执行 func4() 才能修改样式,否则不存在 class = ‘lg’ 的节点:

55


innerText:功能较少,但是比较安全

innerText 为什么比 innerHTML 更加安全呢?因为 innerText 会自动对字符串进行 HTML 编码,保证拿到的内容是纯字符串,这样做就无法设置 HTML 标签,自然就更加安全(避免 XSS 攻击)

function func5() {
    
    
    let father = document.getElementById('app');
    father.lastElementChild.innerText = 'The third node';
}

控制台执行 func5():

56



3、删除 DOM 节点

删除节点很容易,记住一句话:想要删除某个节点,首先需要找到父节点,再调用父节点的 removeChild 方法删除该节点

/* 现在我们想要删除 '第一个节点',按照规定,首先需要找到它的父节点,也就是 <ul> 标签
   接下来再找到待删除的 <dd> 标签
   最后执行父节点的 removeChile 方法 */

function func6(){
    
    
    let father = document.getElementById('app');
    let son = document.getElementById('first');
    father.removeChild(son);		//是不是很简单
}

浏览器执行 func6():

57



有时候我们只能获取待删除的节点,却不知道它的父节点是谁,这时候怎么办?使用 parentElement(万能方法)

function func7(){
    
    
    let son = document.getElementById('first');
    son.parentElement.removeChild(son);  //son.parentElement 就是它的父节点
}//结果就不展示了,和上边一样

相反,遇到只能获取父节点的情况,该怎么办(虽然这种情况很少见)?使用 children

function func8(){
    
    
    let father = document.getElementById('app');
    father.removeChild(father.children[1]);   //father.children[1] 就代表 father 这个节点的第二个孩子节点,注意下标从 0 开始
}//结果还是一样

//注意:删除操作是一个动态过程,例如这次你删除了第二个节点,那么原本的第三个节点现在就变成了第二个节点!所以下标问题一定要注意


4、插入 DOM 节点

之前我们接触了 innerHTML,可以利用它实现标签(节点)的添加,但是这种方式并不完美,因为它会覆盖原本的内容。如果我们希望保留原本的节点,通过追加的方式插入新的节点,就需要使用 appendChild() 方法

//插入节点首先必须找到待插入的位置,也就是某一个特定的节点,然后再进行后续的操作
//下面演示最完整的插入操作:找到插入的位置 -> 创建新节点 -> 设置属性 -> 插入新节点

function func9() {
    
    
    
    let father = document.getElementById('app');	//父节点(待插入位置)
    let newNode = document.createElement('dd');		//新节点的标签名称
    newNode.id = 'forth';							//新节点的 id
    newNode.innerText = '第四个节点';				 //新节点的文本内容
    newNode.style.marginLeft = '0';				    //设置新节点的 CSS 样式
    newNode.style.color = 'orange';
    father.appendChild(newNode);					//完成插入操作
}

//appendChild() 添加的位置为末尾!

浏览器执行 func9():

58



有时候我们需要插入的节点本来就存在于 DOM 树中,就无需创建,直接拿来用就行

DOM 树会删掉插入前节点的位置,将它放在新的位置处:

function func10() {
    
    
    let father = document.getElementById('app');	//父节点(待插入位置)
    let node = document.getElementById('first');	//已经存在的节点
    node.style.color = 'orange';                    //给你们变个色
    father.appendChild(node);						//注意位置的变化
}

浏览器执行 func10()(原本的 ‘第一个节点’ 跑到最后一行去了):

59



补充:由于 appendChild 只能在尾部插入,为了实现在任意位置插入,我们可以使用 insertBefore

/* 源码:insertBefore<T extends Node>(newChild: T, refChild: Node | null): T;
   看不懂?给你们翻译成人话:
   父节点.insertBefore(待插入节点, 你希望插入到其中哪个节点之前)*/

function func11() {
    
    
    let father = document.getElementById('app');
    let referenceNode = document.getElementById('first');
    //新节点和之前长的一样,这里不解释了
    let newNode = document.createElement('dd');
    newNode.id = 'forth';
    newNode.innerText = '第四个节点';
    newNode.style.marginLeft = '0';
    newNode.style.color = 'orange';

    //插入到 father 内,位置在 referenceNode 之前
    father.insertBefore(newNode, referenceNode);
}

浏览器执行 func11():

60



至此,所有关于 DOM 树【获取、更新、删除、插入】操作都介绍完毕,操作的时候注意逻辑关系就可

猜你喜欢

转载自blog.csdn.net/qq_52174675/article/details/122820984