【JS】DOM

本文详细介绍了DOM(文档对象模型)的核心概念,包括节点类型、获取元素的方法如getElementById、getElementsByTagName等,以及元素的属性操作、样式操作和事件处理。同时,讨论了如何通过类名、name属性和选择器来选取元素,并展示了全选、取消全选和元素尺寸、位置的相关API。此外,还涵盖了元素的添加、删除、替换和克隆等动态操作。

**MDN 文档对象模型手册:**https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model

DOM 英文全称“Document Object Model”,译为文档对象模型。

DOM 是一个与平台和编程语言无关的接口,通过这个接口程序和脚本可以动态的访问和修改文档的内容、结构和样式。

DOM最大的特点就是将文档表示为节点树

在这里插入图片描述

一、节点

1. 五大节点类型

类型含义Nodetype
document文档类型节点9
element元素类型节点1
attribute属性类型节点2
text文本类型节点3
comment注释类型节点8

2. 节点的属性

属性含义
nodeName节点名称
nodeValue节点值
nodeType节点类型

二、获取元素

1. 通过 ID 名getElementById

documet.getElementById('ID名')
  1. 如果有多个同ID名得元素,只获取第一个
  2. 如果找不到指定ID名得元素,返回null

2. 通过标签名getElementByTagName

从文档中获取:

document.getElementByTagName('标签名');

从某个元素的后代中获取:

元素对象.getElementByTagName('标签名');
  1. getElementByTagName()方法返回一个HTMLCollection对象,该对象是类数组
  2. 如果找不到符合条件的元素,返回空的元素,还是HTMLCollection对象

3. 通过类名(IE8 + 支持)getElementsByClassName

从文档中获取:

document.getElementsByClassName('item');

从元素的后代中获取:

元素对象.getElementsByClassName('item')
  1. getElementsByClassName() 方法返回一个 HTMLCollection 对象,该对象是类数组
  2. 如果找不到符合条件的元素,返回空的集合,还是 HTMLCollection 对象

4. 通过 name 属性值 getElementsByName

从文档中获取:

document.getElementsByName('name属性值');

无法从某个元素的后代中获取; 元素对象没有 getElementsByName() 方法

  1. getElementsByName() 方法返回一个 NodeList 对象,该对象是类数组
  2. 如果找不到符合条件的元素,返回空的集合,还是 NodeList 对象

5. 使用选择器获取元素 (推荐)

从文档中获取:

document.querySelector('选择器');
document.querySelectorAll('选择器');

从元素的后代中获取:

元素对象.querySelector('选择器');
元素对象.querySelectorAll('选择器');
  1. querySelector() 返回第一个符合条件的元素,如果没有符合条件的元素返回 null
  2. querySelectorAll() 返回由符合条件的元素组成的集合,是 NodeList 对象,是伪数组。

6. 获取文档中所有的元素

返回文档中所有的元素组成的集合,是伪数组

document.all

使用 document.all 可以快速判断 IE 还是 非IE:

// 快速判断IE还是非IE
if (document.all) {
    document.write('是IE浏览器!');
} else {
    document.write('不是IE浏览器!');
}

三、文档结构(根据元素关系获取元素)

1. 节点树

属性含义
parentNode获取父节点
childNodes获取所有子节点组成的集合,NodeList类型的对象
firstChild获取第一个子节点
lastChild获取最后一个子节点
previousSibling获取上一个兄弟节点
nextSibling获取下一个兄弟节点

2. 元素树

属性含义
parentElement获取父元素
children获取所有子节点组成的集合,HTMLCollection类型的对象
firstElementChild获取第一个子元素
lastElementChild获取最后一个子元素
previousElementSibling上一个兄弟元素
nextElementSibling下一个兄弟元素

四、元素的属性操作

1. 读写内置属性

内置元素指的是HTML标准版规范中规定好的属性,当获取到JS元素对象的时候,HTML标签的内置属性会变为JS对象的属性

元素对象.属性名;
// 设置
元素对象.属性名 = 值;
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg">
<script>
    var imgEle = document.querySelector('#myImg')
    console.log('src:', imgEle.src);
    console.log('alt:', imgEle.alt);
    console.log('title:', imgEle.title);
    imgEle.onclick = function () {
        imgEle.width = 200
    }
</script>

2. 读写设置在标签代码上的属性

//读取
元素对象.getAttribute('属性名');

//设置
元素对象.setAttribute('属性名','值');

和内置属性不同的地方:

  1. 自定义的属性可以获取
  2. 不会处理,是什么就输出什么,相对路径不会处理成相对路径
  3. 所有属性值都是字符串
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg" random="random">
<script>
    var imgEle = document.querySelector('#myImg')
    console.log(imgEle.getAttribute('random'));
    console.log(imgEle.getAttribute('alt'));
    console.log(imgEle.getAttribute('src'));
    imgEle.onclick = function () {
        imgEle.setAttribute('width', '600')
    }
</script>

3. data-* 形式的自定义属性

用在自定义属性上

<元素 data-home-address='值'>
元素对象.dataset.homeAddress;
元素对象.dataset.homeAddress = '值';
<img src="./src/assets/006WJqK7ly1hfvg3blrkhj30u00u07f2.jpg" alt="hello" width="400" title="wake up" id="myImg" data-random="random" data-load-pic="100.jpg">
<script>
    var imgEle = document.querySelector('#myImg')
    console.log(imgEle.getAttribute('data-random'));  //random
    console.log(imgEle.getAttribute('data-load-pic')); //100.jpg
    console.log(imgEle.dataset.random);
    console.log(imgEle.dataset.loadPic);
    imgEle.onclick = function () {
        imgEle.dataset.random = 'xx'
        imgEle.dataset.homeAddressId = 200
    }

</script>

image.png

4. 全选和取消全选案例

<ul id="selectBox">
    <li>
      <input type="checkbox">
      Document Object Model
    </li>
    <li>
      <input type="checkbox">
      Document Object Model
    </li>
    <li>
      <input type="checkbox">
      Document Object Model
    </li>
    <li>
      <input type="checkbox">
      Document Object Model
    </li>
</ul>
<hr>
<button id="btn1">全选</button>
<button id="btn2">取消全选</button>
<button id="btn3">反选</button>

<script>
    var checkboxItems = document.querySelectorAll('#selectBox input')
    var btn1 = document.querySelector('#btn1')
    var btn2 = document.querySelector('#btn2')
    var btn3 = document.querySelector('#btn3')
    btn1.onclick = function () {
        checkboxItems.forEach((i) => {
            i.checked = true
        })
    }
    btn2.onclick = function () {
        for (var i = 0; i < checkboxItems.length; i++) {
            checkboxItems[i].checked = false
        }
    }
    btn3.onclick = function () {
        checkboxItems.forEach((i) => {
            // if (i.checked) {
            //   i.checked = false
            // } else {
            //   i.checked = true
            // }
            i.checked = !i.checked
        })
    }
</script>

五、元素的样式操作

1. 读写行内样式

元素对象.style.CSS属性名;
元素对象.style.CSS属性名 = '新值';

如果属性名中有-,使用小驼峰或者中括号,如元素对象.style.backgroundColor元素对象.style['background-color']

该方式只能读取设置在行内的样式,使用该方式设置样式会设置在行内。

<button id="btn01">get</button>
<div id="box" style="width: 400px;height: 400px;background-color: azure;"></div>
<script>
    var box = document.querySelector('#box')
    var btn01 = document.querySelector('#btn01')
    btn01.onclick = function () {
        box.style.backgroundColor = '#ccc'
    }
</script>

2. 读取计算样式

计算样式:最终作用在元素上的样式,即使没有设置过也有默认样式。只能读取不可以设置

getComputedStyle(元素对象).属性名;
getComputedStyle(元素对象)['属性名'];
getComputedStyle(元素对象); //该方法返回是个对象
<button id="btn01">get</button>
<div id="box" style="width: 400px;height: 400px;background-color: azure;"></div>
<script>
    var box = document.querySelector('#box')
    var btn01 = document.querySelector('#btn01')
    var styleObj = getComputedStyle(box)
    btn01.onclick = function () {
        console.log(styleObj.width);
        console.log(styleObj['background-color']);
    }
</script>

兼容性写法(了解)

// 封装读取计算样式的函数
function getStyle(ele, attrName) {
    // 判断是否支持 getComputedStyle
    if (window.getComputedStyle) {
        return getComputedStyle(ele)[attrName];
    } else if (ele.currentStyle) {
        // IE的用法
        return ele.currentStyle[attrName];
    } else {
        return false;
    }
}

3. 通过设置元素的类名操作样式

  • className

    元素对象.className;		// 可读可写
    

    class 在 JS中是保留字, JS 的元素对象使用 className 属性对应 html 标签上的 class 属性

  • classList

    元素对象.classList;		//获取到由元素的类名组成的集合,是个伪数组对象
    
    方法含义
    contains()判断是否包含一个类名
    add()添加一个类名
    remove()删除一个类名
    toggle()切换一个类名(原来有该类型就移除,原来没有该类名就添加)
var itembox = document.querySelectorAll('.item')
itembox.forEach(function (i) {
    i.onclick = function () {
        // 使用className
        // if (i.className == 'item active') {
        //   i.className = 'item'
        // } else {
        //   i.className = 'item active'
        // }
        // 使用classList
        // console.log(i.classList);
        // if (i.classList.contains('active')) {
        //   i.classList.remove('active')
        // } else {
        //   i.classList.add('active')
        // }
        // 最简便方法
        i.classList.toggle('active')
    }
})

六、元素的文本内容(可读可写)

属性含义
innerHTML读写元素中html代码和文本
outerHTML读写元素中html代码和文本(包括元素自己的标签代码)
innerText读写元素中的文本内容(html标签会被剔除)(保留文本中的多的空格)
textContent读写元素中的文本内容(html标签会被剔除)(保留文本中的空格)

七、元素的尺寸(只读)

属性含义
offsetWidth/offsetHeight读取元素的总宽度和总高度
clientWidth/clientHeight读取内容+内边距的宽高
scrollWidth/scrollHeight在client的基础上加上溢出部分的宽高

image.png

元素对象.getBoundingClientRect().width	//同offsetWidth
元素对象.getBoundingClientRect().height	//同offsetHeight

读取视口的尺寸:

视口宽度:document.documentElement.clientWidth

视口高度:document.documentElement.clientHeight

相对于widow.innerWidth、window.innerHeight,本方案不会将滚动条本身的宽度算进去

// 读取视口的宽高
console.log(window.innerWidth);             //691
console.log(window.innerHeight);            //883
console.log(document.documentElement.clientWidth);    //674
console.log(document.documentElement.clientHeight);   //883

八、元素的位置 (只读)

属性含义
offsetLeft / offsetTop读取在第一个定位的祖先元素上的位置,如果没有定位的祖先元素,在整个页面
clientLeft / clientTop读取左边框宽度/上边框宽度

getBoundingClientRect()返回一个对象,对象中有如下属性:

属性含义
left在视口上的位置 x坐标
top在视口上的位置 y坐标
x同 left
y同 top
right元素的右下角在视口上的x坐标
bottom元素的右下角在视口上的y坐标

九、元素中内容的位置(可读可写)

属性含义
scrollLeft元素中的内容在元素上的水平位置, 值越大,内容越向左滚动(滚动条越向右)
scrollTop元素中的内容在元素上的竖直位置, 值越大,内容越向上滚动(滚动条越向下)

注意: 被操作的元素,overflow的属性值不能是 visible。

读写页面在视口上的位置(滚动的距离)

// 非IE的用法
document.documentElement.scrollTop;
document.documentElement.scrollLeft;

// IE 的用法
document.body.scrollTop;
document.body.scrollLeft;

// 兼容性写法
document.documentElement.scrollTop || document.body.scrollTop;

十、节点的添加/删除/替换/克隆

方法含义
creatElement(‘标签名’)创建元素节点
appendChild(新节点)添加子节点,新节点作为父元素的最后一个子节点
insertBefore(新节点, 旧节点)添加子节点,新节点会添加到旧节点的前面
removeChild(要删除的节点)删除子节点
replaceChild(新节点, 旧节点)替换子节点
cloneNode()返回复制好的元素
参数默认false,表示只克隆元素本身不克隆里面的内容
如果设置为true,连同里面的内容后代元素一起克隆
<div class="todolist">
    <div class="todo-header">
      <input type="text" id="input">
      <button id="addBtn">添加</button>
      <button id="insertBtn">插入</button>
      <button id="deleteBtn">删除</button>
      <button id="replaceBtn">替换</button>
      <button id="cloneBtn">克隆</button>
    </div>
    <div class="todo-body">
      <ul id="todoContent">
        <li>苹果</li>
        <li>西瓜</li>
      </ul>
    </div>
</div>
<li id="freeLi">草莓</li>
<script>
    // 获取相关元素
    var todoContent = document.querySelector('#todoContent');
    var inputEle = document.querySelector('#input');
    var addBtn = document.querySelector('#addBtn');
    var insertBtn = document.querySelector('#insertBtn');
    var deleteBtn = document.querySelector('#deleteBtn');
    var repalceBtn = document.querySelector('#replaceBtn');
    var cloneBtn = document.querySelector('#cloneBtn');
    var freeLi = document.querySelector('#freeLi');

    // 给每个 li 监听单击事件
    [].forEach.call(todoContent.children, function (liItem) {
      liItem.onclick = function () {
        liItem.classList.toggle('active');
      }
    });

    // 点击添加按钮
    addBtn.onclick = function () {
      // 创建新元素
      var newLi = document.createElement('li');
      // 设置li中的文本内容
      newLi.innerHTML = inputEle.value;
      // 将 li 添加到 ul 的里面
      todoContent.appendChild(newLi);
    };

    // 点击插入按钮 实现代办事项插入到最前面
    insertBtn.onclick = function () {
      // 创建新元素
      var newLi = document.createElement('li');
      // 设置li中的文本内容
      newLi.innerHTML = inputEle.value;
      // 给ul添加子元素 指定位置
      todoContent.insertBefore(newLi, todoContent.firstChild);
    };

    // 点击删除按钮,删除选中的元素
    deleteBtn.onclick = function () {
      // 获取到被选中的元素
      var selectedLis = document.querySelectorAll('#todoContent li.active');
      // 遍历被选中的元素,挨个删除
      selectedLis.forEach(function (selectedLi) {
        todoContent.removeChild(selectedLi);
      });
    };

    // 点击替换
    repalceBtn.onclick = function () {
      // 创建新元素
      var newLi = document.createElement('li');
      // 设置li中的文本内容
      newLi.innerHTML = inputEle.value;
      // 获取到被选中的元素
      var selectedLis = document.querySelectorAll('#todoContent li.active');
      // 遍历被选中的元素,挨个替换
      selectedLis.forEach(function (selectedLi) {
        todoContent.replaceChild(newLi.cloneNode(true), selectedLi);
      });
    };

    // 点击克隆
    cloneBtn.onclick = function () {
      todoContent.appendChild(freeLi.cloneNode(true))
    }
</script>

十一、HTML DOM

1. 表单相关元素

1.1 form 元素

方法含义
submit()调用时,表单会提交
reset()调用时,表单会重置
<form action="http://www.baidu.com/s" id="myForm">
<input type="text" name="wd">
</form>
<hr>
<button id="btn">搜索</button>
<script>
    // 获取form元素
    var formBox = document.querySelector('#myForm');

    // 获取按钮 双击按钮 提交表单
    var btn = document.querySelector('#btn');
    btn.ondblclick = function() {
        formBox.submit();
    };

    // 10s 之后表单自动重置
    setTimeout(function() {
        formBox.reset();
    }, 10000);
</script>

1.2 文本输入框和文本域(input 和 textarea)

方法含义
focus()获取焦点
blur()失去焦点
select()选中里面的内容
<button id="btn1">获取焦点</button>
<button id="btn2">失去焦点</button>
<button id="btn3">选中内容</button>
<hr>
<input type="text" id="input">
<br>
<textarea name="" id="txt" cols="30" rows="10"></textarea>

<script>
    // 获取input和textarea
    var input = document.querySelector('#input');
    var textarea = document.querySelector('#txt');
    var btn1 = document.querySelector('#btn1');
    var btn2 = document.querySelector('#btn2');
    var btn3 = document.querySelector('#btn3');

    // 点击获取焦点
    btn1.onclick = function() {
        textarea.focus();
        input.focus();
    }

    // 点击失去焦点
    btn2.onclick = function(){
        input.blur();
    }

    // 点击选中内容
    btn3.onclick = function() {
        textarea.select();
        input.select();
    }
</script>

1.3 select 元素

属性和方法含义
value获取被选中选项的value
selectedIndex获取被选中选项的索引
options获取所有选项的集合
add()添加一个选项,参数时option元素
remove()删除一个选项,参数是要删除选项的索引

特殊的地方,option和img可以new来创建元素

new Option('选项内容','value值');
<button id="btn1">获取选中的选项</button>
<button id="btn2">删除选中的选项</button>
<hr>
<select id="addressBox"></select>
<script>
    // 创建数组 定义地址信息
    var addressData = ['江苏', '江西', '浙江', '安徽', '河南', '新疆维吾尔自治区'];
    // 获取 select元素
    var selectBox = document.querySelector('#addressBox');

    // 遍历数组
    addressData.forEach(function(item, index) {
        // 创建option元素 并添加到 select 中
        selectBox.add(new Option(item, index));
    });

    // 点击按钮 获取选中的选项
    var btn1 = document.querySelector('#btn1');
    btn1.onclick = function() {
        console.log('所选选项的value:', selectBox.value);
        console.log('所选选项的索引:', selectBox.selectedIndex);
        // 选中的 options 元素
        console.log(selectBox.children[selectBox.selectedIndex]);
        console.log(selectBox.options[selectBox.selectedIndex]);
    };

    // 点击按钮 删除选中的选项
    var btn2 = document.querySelector('#btn2');
    btn2.onclick = function() {
        // selectBox.removeChild(selectBox.options[selectBox.selectedIndex]);
        selectBox.remove(selectBox.selectedIndex);
    }
</script>

2. 表格相关元素

2.1 table 元素

方法含义
insertRow()创建并添加tr元素
deleteRow()删除一行,参数是行的索引

2.2 tableRow 元素(tr 元素)

属性和方法含义
cells获取本行所有单元格组成的集合
rowIndex读取该行的索引
insertCell()创建并添加td元素
deleteCell()删除一个单元格,参数是单元格的索引

2.3 tableCell 元素 (td 或 th)

属性含义
cellIndex读取该单元格在行的索引
// 获取元素
var tableBox = document.querySelector('#table');
var nameInput = document.querySelector('#name');
var addressInput = document.querySelector('#address');
var phoneInput = document.querySelector('#phone');
var btn = document.querySelector('#btn');
// 获取到所有的删除按钮
var deleteBtns = document.querySelectorAll('.delete-btn');

// 点击按钮 给表格添加一行
btn.onclick = function() {
    // 创建并添加 tr 元素
    var tr = tableBox.insertRow();
    // 在 tr 中添加 td
    tr.insertCell().innerHTML = '';
    tr.insertCell().innerHTML = nameInput.value;
    tr.insertCell().innerHTML = addressInput.value;
    tr.insertCell().innerHTML = phoneInput.value;
    tr.insertCell().innerHTML = '<button class="delete-btn">删除</button>';

    // 情况输入框
    nameInput.value = addressInput.value = phoneInput.value = '';

};

// 遍历删除按钮 添加单击事件
deleteBtns.forEach(function(deleteBtn){
    deleteBtn.onclick = function() {
        tableBox.deleteRow(deleteBtn.parentElement.parentElement.rowIndex);
    };
});

3. 快速创建 img 元素

new Image();
new Image(宽度,高度);

4. document 对象

document表示整个文档,document是html元素的父节点,document是window的一个属性,document对象具有如下属性方法:

属性含义
all获取到所有元素
body获取到body元素
head获取到head元素
documentElement获取到html根元素
lastModify获取文档最后一次修改时间
title获取标题栏标题内容(可读可写)
cookie获取当前文档的cookie信息(可读可写)
方法含义
getElementById()根据id查找元素
getElementsByTagName()根据标签名称查找元素
getElementsByClassName()根据类名查找元素
getElementsByName()根据name查找元素
querySelector()查找与选择器匹配的第一个元素
querySelectorAll()查找匹配的所有元素
createElement()创建一个由标签名称指定的元素
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值