Javascript:DOM详解

671 阅读6分钟

Javascript DOM定义:

DOM即(Document Object Model):文档对象模型,用来将标记型文档封装成对象,并将标记型文档中的所有内容(标签、文本、属性等)都封装成对,。即标记型文档的一种解析方式。因为封装为对象就可以对其中的属性和行为进行调用,以便于对这些文档及文档中的内容进行更方便的操作。是W3C制定的标准接口规范,是一种处理HTML和XML文件的标准API。

DOM解析方式:将标记型文档解析为一颗dom树,而树中的内容都封装为节点对象。 按照标签的层次关系体现出标签的所属,形成一个树状结构。所以我们将DOM解析文档形成的document对象称为dom树,而树中的标签以及文本甚至属性称为节点。这个节点也称为对象标签通常也称为页面中的元素

DOM 以树结构表达 HTML 文档:
image.png

注意:这个DOM解析的好处是可以对树中的节点进行任意操作,如增删查改。但也有弊端:这种解析需要将标记型文档加载进内存。意味着如果文档体积很大时较为浪费空间。

DOM共三个节点:元素节点、属性节点、文本节点,接下来详细罗列如果操控这些节点。

1. DOM节点的获取

document.getElementById():根据id获取节点
document.getElementsByClassName():根据class获取节点,获取的是一个数组
document.getElementsByName():根据name属性获取节点,获取的是一个数组
document.getElementsByTagName():根据元素标签获取节点,获取的是一个数组

document.querySelector():返回文档中匹配指定 CSS 选择器的一个元素
document.querySelectorAll():返回文档中匹配指定 CSS 选择器的所有元素,获取的是一个数组

document.firstChild:获取元素的首个子节点
document.lastChild:获取元素的最后一个子节点
document.childNodes:获取元素的子节点列表(childNodes 属性返回所有的节点,包括文本节点、注释节点)
document.children:获取元素的子节点列表(children 属性只返回元素节点)
node.previousSibling:获取当前节点的前一个节点
node.nextSibling:获取当前节点的后一个节点
node.parentElement:获取元素的父节点
node.parentNode:获取元素的父节点

// 示例:
document.querySelector("p").childNodes[0].nodeValue// 获取p标签下第一个子节点的值,nodeValue节点的值,nodeType指节点类型,nodeName标签名称或文本内容

2. DOM节点的增删改

// 1.创建节点
document.createElement():创建元素节点
document.createAttribute():创建属性节点
document.createTextNode():创建文本节点
 
// 示例:
var div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";
document.body.appendChild(div);

// 2.插入节点,s必须是节点
node.appendChild(s):向节点的子节点列表末尾添加一个新的子节点
node.insertBefore(s):向节点的子节点列表最前面加一个新的子节点

// 示例:
// 找到需要插入元素的节点
let node = document.getElementsByClassName("viewport")[0];
// 创建一个新的元素节点,虚拟节点 此节点创建时还没被渲染到页面中
let newNode = document.createElement("div"); //div标签名称
// 给此元素节点加内容
newNode.innerHTML = '<a>测试</a>';
// 也可以通过创建文字节点,再加到newNode中。
const text = document.createTextNode(",创建文字节点方式加内容")
// 向元素节点中插入一个文本节点
newNode.appendChild(text);
// 将此新元素节点插入
node.appendChild(newNode);

// 简单的方法insertAdjacentHTML:直接插入html模板
// 等同appendChild,此方法可以直接插入html模板,而其他的必须是节点
// 可以插入四个位置:beforebegin、afterbegin、beforeend、afterend
node.insertAdjacentHTML('afterbegin','<li>woshishui</li>');
// 或者innerHTML
node.innerHTML = '<a>测试</a>';

// 3.替换节点
node.replaceChild(para,child):将某个子节点替换成另一个,用para替代child
 
// 4.复制节点
node.cloneNode(true):复制某个节点,返回调用该方法的节点的一个副本
// 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
// 如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点

// 5.删除节点
node.removeChild():删除指定节点

// 示例:
var divNode3 = document.getElementById("div3");
//方法一:删除节点,参数为true时,连同子节点也一起上删除,此方法在IE中有效 
divNode3.removeNode(true);
//方法二:使用父节点删除(推荐)
divNode3.parentNode.removeChild(divNode3);

3. 设置/修改DOM元素内容

  • document.write():只能将文本内容追加到body前面的位置
  • innerText:文本中包含的标签不会被解析
  • innerHtml:文本中包含的标签会被解析
  • textContent:可以解析script和style标签的内容
   document.write('新内容<p>新标签</p>')
   var box = document.getElementById('box');
   box.innerHTML = '新内容<p>新标签</p>';
   box.innerText = '新内容';
   box.textContent = '新内容';

4. 设置/修改DOM元素属性

  • 操作元素常用属性

获取: DOM对象.属性名
设置: DOM对象.属性名 = 新值

//1. 获取属性
const prop = document.getElementById(testbt).className//2. 设置属性示例:
const img = document.getElementById(testbt);
img.setAttribute('className', 'sample_type');
img.className = 'sample_type'; //比上一方式兼容性好
img.src='';
img.width=100px;

// 设置节点属性,getAttribute()和setAttribute()方法不属于document对象
// 所以不能通过document对象调用,它只能通过元素节点对象调用。
object.setAttribute():创建或改变元素节点的属性
removeAttribute(): 删除元素节点的属性  
//document.createAttribute()是指直接操作document对象的
  • 操作元素样式属性

DOM对象.style.样式属性 = 新值;

const img = document.getElementById(testbt);
img.style.border = "1px solid red"
img.style.color = '#00f';
img.backgroundColor = 'red'; //只能是驼峰式,不可以是中划线格式

5. DOM扩展使用

  • childNodes的属性

    nodeType:共有12种可取值,但只有3中具有实用价值。

      元素节点的nodeType属性值是1
      属性节点的nodeType属性值是2
      文本节点的nodeType属性值是3
      注释节点的nodeType属性值是8 
      不是有效节点没有返回 直接"undefined" 
      该属性只读
    

    nodeName:返回当前节点的节点名称 节点的名字:大写的标签--标签,小写的属性名---属性,#text---文本

    nodeValue:返回或设置指定节点的节点值。 标签---null,属性--属性的值,文本--文本内容

    <p>我是p里面的value</p>
    // 获取p标签里的值:
    document.querySelector("p").childNodes(0).nodeValue
    
  • document信息

    
    // 取得对<html>的引用
    var html = document.documentElement;
    // true
    alert(html === document.childNodes[0]);
    //true
    alert(html === document.firstChild);
    //取得对<body>的引用
    var body = document.body;
    //取得对<!DOCTYPE>的引用
    var doctype = document.doctype;
    
    //取得文档标题
    var originalTitle = document.title;
    //设置文档标题
    document.title = "New page title";
    //取得完整的URL
    var url = document.URL;
    //取得域名
    var domain = document.domain;
    //取得来源页面的URL
    var referrer = document.referrer;
    
  • addEventListener()

    // 可以监听元素,也可以监听window
    document.querySelector("p")[0].addEventListener('click',(e) => console.log(e),true)
    

    其预设监听点bubbling,预设值capture:false
    可以手动修改为true,则监听点是capturing
    e.target:可以是父target,也可以是子target(变化的)
    e.currentTarget:指向监听元素的本身(不变)

image.png