17 JavaScript DOM

1 概述

所谓DOM,全称 Docuemnt Object Model 文档对象模型。

什么对象?文档对象?

在文档中一切皆对象,比如html,body,div,p等等都看做对象,那么我们如何来点击某个盒子让它变色呢?DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。

解析

HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树,getElementById是获取内中DOM上的元素节点。然后操作的时候修改的是该元素的属性。

DOM树(一切皆是节点)

image

上图可知,在HTML当中,一切都是节点:(非常重要)

  • 元素节点:HMTL标签。
  • 文本节点:标签中的文字(比如标签之间的空格、换行)
  • 属性节点::标签的属性

整个html文档就是一个文档节点。所有的节点都是Object。

2 DOM可以作什么

  • 找对象(元素节点)
  • 设置元素的属性值
  • 设置元素的样式
  • 动态创建和删除元素
  • 事件的触发响应:事件源、事件、事件的驱动程序

3 清除DOM的结构

  • 获取文档对象:document
  • 获取html:document.documentElement
  • 获取body: document.body

4 获取元素的三种方式

//方式一:通过id获取单个标签
var oDiv1 = document.getElementById("box1");      

//方式二:通过 标签名 获得 标签数组,所以有s
var oDiv2 = document.getElementsByTagName("div")[0];     

//方式三:通过 类名 获得 标签数组,所以有s
var oDiv3 = document.getElementsByClassName("box")[0];  

5 节点操作

5-1 setAttribute()&getAttribute()

获取节点下的属性,设置节点下的属性

<h2>你要买什么课程</h2>
<p title="请选择购买的课程">本课程是web全栈课程,期待你的购买</p>
<ul id="classList">
    <li class="item">JavaScript</li>
    <li class="item">CSS</li>
    <li>DOM</li>
</ul>

<script>
    var oP = document.getElementsByTagName('p')[0];
    
    //获取属性值 有一个必须的参数,这个节点的名字
    var title = oP.getAttribute('title'); //获取属性名和值
    console.log(title);

    //设置属性名和值 setAttribute(name,value)
    oP.setAttribute('id','box');
</script>

5-2 节点对象三个属性

在文档对象模型(DOM)中,每个节 点都是一个对象。DOM节点有三个重要的属性 :
1. nodeName:节点的名称
2. nodeValue :节点的值
3. nodeType:节点的类型

1. nodeName属性:节点的名称,是只读

1.元素节点的nodeName与标签名相同
2.属性节点的nodeName.与属性的名称相同
3.文本节点的nodeName永远是#text
4.注释节点的nodeName永远是#comment

2. nodeValue属性:节点的值

1.元素节点的nodeValue是undefined 或null
2.文本节点的nodeValue是文本自身
3.属性节点的nodeValue是属性的值
4.注释节点的nodeValue是注释自身

3. nodeType属性:节点的类型,是只读的。
以下常用的几种结点类型:

元素节点:节点类型
元素:1
属性:2
文本:3
注释:8
文档:9
<div id="box" title="我是文本">
    我是一个文本节点<!--我是一个注释节点-->
</div>
<script>
    //元素节点
    var oDiv = document.getElementById('box');
    console.log(oDiv.nodeName + ' | ' + oDiv.nodeValue
                + ' | ' + oDiv.nodeType); //DIV | null | 1

    //属性节点
    var attrNode = oDiv.attributes[0]; //获取oDiv下的属性。{0: id, 1: title, id: id, title: title, length: 2}
    console.log(attrNode.nodeName + ' | ' + attrNode.nodeValue
                + ' | ' + attrNode.nodeType); // id | box | 2

    //文本节点
    var textNode = oDiv.childNodes[0]; //[text, comment, text]
    console.log(textNode.nodeName + ' | ' + textNode.nodeValue
                + ' | ' + textNode.nodeType);

    //注释节点
    var commentNode = oDiv.childNodes[1]; //[text, comment, text]
    console.log(commentNode.nodeName + ' | ' + commentNode.nodeValue
                + ' | ' + commentNode.nodeType);

    //文档节点
    console.log(document.nodeType);
</script>

5-3 导航查找标签

版本一(推荐):

<div class="c2">
    <div class="c3">
        <ul class="c4">
            <li>000</li>
            <li class="c5" id="box">111</li>
            <li>222</li>
            <li>333</li>
        </ul>
    </div>
</div>
<script>
    var c5 = document.getElementsByClassName('c5')[0];
    //获取父集节点
    console.log(c5.parentElement);
    //获取父亲节点下第一个儿子标签
    console.log(c5.parentElement.firstElementChild);
    //获取父亲节点下的最后一个儿子标签
    console.log(c5.parentElement.lastElementChild);
    //获取父亲节点下的所有儿子标签(不包含text)
    console.log(c5.parentElement.children);
    //获取c5节点下的下一个标签
    console.log(c5.nextElementSibling);
    //获取c5节点下的下下一个标签
    console.log(c5.nextElementSibling.nextElementSibling);
    //获取c5节点下的上一个标签
    console.log(c5.previousElementSibling);
    //获取c5节点下的上上一个标签
    console.log(c5.previousElementSibling.previousElementSibling);
</script>

版本二:

<div class="previous">我是上一个兄弟</div><div id="father"><p>lxx</p><p>lww</p></div><div class="sibling">我是下一个兄弟</div>

<script>
    var oFather = document.getElementById('father');
    console.log(oFather.childNodes); //获取father下的所有元素(包含text)

    console.log(oFather.firstChild); //获取集合的第一个元素
    console.log(oFather.childNodes[0]); //获取集合的第一个元素

    console.log(oFather.lastChild); //获取集合的第二个元素
    console.log(oFather.childNodes[oFather.childNodes.length - 1]); //获取集合的第二个元素

    console.log(oFather.parentNode); //获取父集节点
  	console.log(oFather.parentNode.lastElementChild); //获取父亲节点下的最后一个儿子标签

    console.log(oFather.nextSibling); //获取'father'下一个兄弟节点

    console.log(oFather.previousSibling); //获取'father‘上一个兄弟节点
</script>

如果有换行文档需要用函数过滤掉

<div class="previous">我是上一个兄弟</div>
<div id="father">
  <p>lxx</p>
  <p>lww</p>
</div>
<div class="sibling">我是下一个兄弟</div>

<script>
  var oFather = document.getElementById('father');

  //获取id‘father’的元素节点
  function get_childNodes(fatherNode) {
    var nodes = fatherNode.childNodes;
    var arr = [];
    for (var i=0; i<nodes.length; i++){
      if (nodes[i].nodeType === 1){
        arr.push(nodes[i]);
      }
    }
    return arr;
  }
  console.log(get_childNodes(oFather));

  //获取id‘father’的下一个元素节点
  function get_nextSibling(n) {
    var x = n.nextSibling;
    while (x && x.nodeType != 1){
      x = x.nextSibling;
    }
    return x;
  }
  console.log(get_nextSibling(oFather));
  
  //获取id‘father’的上一个元素节点
  function get_previousSibling(n) {
    var x = n.previousSibling;
    while (x && x.nodeType != 1){
      x = x.previousSibling;
    }
    return x;
  }
  console.log(get_previousSibling(oFather));
</script>

image


5-4 节点增删改查

版本一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<button class="add_btn">添加节点</button>
<button class="del_btn">删除节点</button>
<button class="replace_btn">替换节点</button>
<div class="c1">
    <h3>hello JS!</h3>
    <h3 class="c2">hello world</h3>
</div>
<script>
    var add_btn = document.querySelector('.add_btn');
    var del_btn = document.querySelector('.del_btn');
    var replace_btn = document.querySelector('.replace_btn');
    var c1 = document.querySelector('.c1');
    var c2 = document.querySelector('.c2');
    add_btn.onclick = function () {
        //创建节点
        var ele = document.createElement('img'); //<img>
        ele.src = "https://img1.baidu.com/it/u=1269478472,4160885730&fm=26&fmt=auto&gp=0.jpg"
        console.log(ele);

        //插入节点
        // c1.appendChild(ele); //追加一个子节点(作为最后的节点)
        c1.insertBefore(ele,c2); //把增加的节点放到某个节点的前面
    }
    //删除节点
    del_btn.onclick = function () {
        c1.removeChild(c2); //获得要删除的元素,通过父元素调用删除
    }

    //替换节点(语法:.replaceChild(newnode,某个节点))
    replace_btn.onclick = function () {
        //创建替换节点
        var ele = document.createElement('img'); //<img>
        ele.src = "https://img1.baidu.com/it/u=1269478472,4160885730&fm=26&fmt=auto&gp=0.jpg"
        console.log(ele);
        
        c1.replaceChild(ele,c2);
    }
</script>
</body>
</html>

版本二:

<div id="box">
  <p id="active" k1='v1'>lxx</p>
</div>
<!--
动态的操作节点
1.创建节点 createElement()
2.插入节点 appendChild()
		insertBefore(newNode,node)
3.删除节点 removeChild()
4.替换节点 replaceChild(newNode,node)
5.创建文本节点 createTextNode()
-->
<script>
  //获取节点
  var oDiv = document.getElementById('box');
  //创建标签名
  var newNode1 = document.createElement('p');
  //获取k1属性的值
  console.log(ele.getAttribute('k1'));  
  //设置 class类名 和 value值
  newNode1.setAttribute('class','active');

  /*
  方式一:
  创建文本节点对象
  var textNode = document.createTextNode('alex');
  选择插入的位置
  newNode.appendChild(textNode);
  */
  //方法二:插入文本或者跟标签一起插入(渲染文本和标签)
  newNode1.innerHTML = '<a href="#">alex@qq.com</a>';
  /*
  方法二:插入纯字符串文本(只能渲染文本)
  newNode.innerText = '<a href="#">alex@qq.com</a>';
  */

  //插入标签(默认插入最后)
  oDiv.appendChild(newNode1);



  //插入 insertBefore 的方法
  //获取节点
  var oActive = document.getElementById('active');

  //创建标签名
  var newNode2 = document.createElement('p');

  //插入内容
  newNode2.innerHTML = '<a href="#">lxx@qq.com</a>';

  //第一个参数是新插入的节点,第二个参数是参考的节点
  oDiv.insertBefore(newNode2,oActive);



  //替换 replaceChild 方法
  //创建标签名
  var newNode3 = document.createElement('a');
  //设置 class类名 和 value值
  newNode3.setAttribute('href','http://www.baidu.com');
  //插入内容
  newNode3.innerHTML = '百度一下';
  //第一个参数是要替换的参数,第二参数是替换的新值
  oDiv.replaceChild(newNode3,oActive);



  //删除节点
  // oDiv.removeChild(oActive);


  // newNode1 = null; //释放对象
</script>

5-5 节点的样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #classList{
            color: white;
            background-color: black;
            width: 200px;
            height: 200px;
            text-align: center;
        }
    </style>
</head>
<body>
<p id="box">LXX</p>
<script>
    var oP = document.getElementById('box');
    /*
    方式一(直接设置为行内):
    console.log(oP.style);
    oP.style.color = 'white';
    oP.style.backgroundColor = 'black';
    oP.style.width = '250px';
    oP.style.height = '250px';
    oP.style.textAlign = 'center';
    oP.style.lineHeight = '250px';
    */
    //方式二(通过类的方式):
    oP.setAttribute('class', 'highLight')
</script>
</body>
</html>

5-6 CSS选择器标签

<div class="c2">
    <div class="c3">
        <ul class="c4">
            <li class="c5">000</li>
            <li class="c5" id="box">111</li>
            <li>222</li>
            <li>333</li>
        </ul>
    </div>
</div>
<script>
    //css方法获取元素节点
    var dom = document.querySelector(".c2 .c3 .c4 .c5");
    console.log(dom);
    //css方法获取多个相同的元素节点
    var els = document.querySelectorAll('ul li');
    console.log(els);
</script>

5-7 文本操作

<div class="name"><span>lxx</span></div>
<script>
    //查询文本
    var oDiv = document.querySelector('.name');
    console.log(oDiv.innerHTML); //标签和文本都渲染
    console.log(oDiv.innerText); //只渲染文本

    //设置文本
    oDiv.onclick = function () {
        // oDiv.innerHTML = '大帅'; //修改值
        oDiv.innerHTML = '<a href="#">大帅</a>'; //渲染标签和文本
        // oDiv.innerText = '<a href="#">大帅</a>'; //只渲染文本
    }
</script>

5-8 value查找方法

像input标签,select标签 以及textarea标签是没有文本的,但是显示内容由value属性决定

  • value操作
<input type="text" class="c1" value="hello world"><button class="btn">change</button>

<script>
    var btn = document.getElementsByClassName('btn')[0];
    btn.onclick = function () {
        //类查找
        // var ele = document.querySelector('.c1');
        // ele.value = 'hello JS!';

        //导航查找
        this.previousElementSibling.value = 'hello JS!';
    }
</script>

5-9 select取值赋值

<select name="" id="box">
    <option value="henan">河南</option>
    <option value="hebei">河北</option>
    <option value="hunan">湖南</option>
</select>
<button class="btn">change</button>
<script>
    //select标签
    var sel = document.querySelector('#box');
    console.log(sel.value); //取值
    var btn = document.getElementsByClassName('btn')[0];
    btn.onclick = function () {
        sel.value = 'hebei'; //赋值
    }
</script>

5-10 textarea取值赋值

<textarea id="text">lxx</textarea>
<script>
    //textarea标签
    var ele = document.querySelector('#text');
    console.log(ele.value); //取值
    ele.value = 'welcome to JS'; //赋值
</script>

5-11 class属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c1{
            background-color: #83c44e;
        }
        .c2{
            color: red;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
<div class="c1">hello world</div>
<script>
    var ele = document.querySelector('.c1');
    ele.onclick = function () {
        this.classList.add('c2'); //添加类样式
        this.classList.remove('c1'); //删除类样式
        console.log(this.className); //打印节点下样式的类名
    }
    ele.ondblclick = function () {
        this.classList.add('hide'); //隐藏
    }
</script>
</body>
</html>
posted @   角角边  Views(46)  Comments(0Edit  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示