# DOM 操作

# CRUD

#

创建 DOM 节点
document.write() 方法,向文档中写入 HTML 字符串
document.createElement() 方法,创建元素节点
cloneNode() 克隆节点
element.innerHTML 属性,设置元素节点内的内容
element.outerHTML 属性,替换当前整个元素节点
插入 DOM 节点
parent.appendChild(targetNode) 方法,追加子节点
parent.insertBefore(targetNode,baseNode) 方法,在 parent 的 baseNode 子节点前插入

#

删除 DOM 节点
element.parentNode.removeChild() 去除某个字节点

#

修改 DOM 节点
elememt.src, element.href, element.title 修改元素的 HTML 属性
ele.innerText, ele.innerHTML, ele.outerHTML 修改普通元素的内容
formEle.value,formEle.type, formEle.disabled 修改表单元素的 HTML 属性
ele.style 修改元素的 CSS 样式
classList.add(), classList.remove(), classList.toggle() 修改元素的类名
className

修改 DOM 属性
setAttribute() 设置自定义属性
getAttribute() 获取自定义属性
removeAttribute() 删除自定义属性

#

获取 DOM 节点
ById() sByClassName() sByTagName() 根据 ID、类名、标签名获取 DOM 元素
querySelector() querySelectorAll() 根据 CSS 选择器获取 DOM 元素
parentNode、children 根据父子节点关系获取
previousElementSibling、nextElementSibling 获取相邻同级节点

# MutationObserver 接口

MutationObserver 接口,可以在 DOM 被修改时异步执行回调。

使用 MutationObserver 可以观察整个文档、 DOM 树的一部分,或某个元素。此外还可以观察元素属性、子节点、文本,或者前三者任意组合的变化。

它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

  • 构造器

MutationObserver 的实例要通过调用 MutationObserver 构造函数并传入一个回调函数来创建:

let observer = new MutationObserver(() => console.log('DOM was mutated!'));

observer实例的方法有

  • disconnect()

  • observe()

  • takeRecords()

  • 基本用法

 // 选择需要观察变动的节点
const targetNode = document.getElementById('some-id');
// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };

// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver((mutationRecords) => {
  console.log(mutationRecords)
});

// 以上述配置开始观察目标节点
observer.observe(targetNode, config);

// 之后,可停止观察
setTimeout(() => observer.disconnect(), 10 * 1000)

每个回调都会收到一个 MutationRecord 实例的数组。 MutationRecord 实例包含的信息包括发 生了什么变化,以及 DOM 的哪一部分受到了影响。

  • 复用

多次调用 observe()方法,可以复用一个 MutationObserver 对象观察多个不同的目标节点。此 时, MutationRecord 的 target 属性可以标识发生变化事件的目标节点。

let observer = new MutationObserver((mutationRecords) => {
  console.log(mutationRecords.map((x) => x.target))
});

// 向页面主体添加两个子节点
let childA = document.createElement('div'),
childB = document.createElement('span');
document.body.appendChild(childA);
document.body.appendChild(childB);
// 观察两个子节点
observer.observe(childA, { attributes: true });
observer.observe(childB, { attributes: true });
// 修改两个子节点的属性
childA.setAttribute('foo', 'bar');
childB.setAttribute('foo', 'bar');

# IntersectionObserver 接口

IntersectionObserver 接口提供了一种异步观察目标元素与其祖先元素或顶级文档视窗 (viewport) 交叉状态的方法。

祖先元素与视窗 (viewport) 被称为**根 (root)。

  • 构造器
let observer = new IntersectionObserver(callback[, options]);

observer实例的方法有

  • disconnect()

  • observe()

  • takeRecords()

  • unobserve() 使 IntersectionObserver 停止监听特定目标元素

  • 基本使用

let observer = new IntersectionObserver(function(entries) {
  if (entries[0].intersectionRatio <= 0) return;
  loadItems(10);
  console.log('Loaded new items');
});

const element = document.querySelector('.scrollerFooter')
// start observing
observer.observe(element);
// 停止观察
observer.unobserve(element);

// 关闭观察器
observer.disconnect();

# ResizeObserver 接口

Resize Observer API 提供了一种高性能的机制,通过该机制,代码可以监视元素的大小更改,并且每次大小更改时都会向观察者传递通知。

  • 构造器
const observer = new ResizeObserver(callback)
observer.observe(element)
  • 基本使用
const resizeObserver = new ResizeObserver(entries => {
  for (let entry of entries) {
    if(entry.contentBoxSize) {
      entry.target.style.borderRadius = Math.min(
        100, 
        (entry.contentBoxSize.inlineSize/10) +
        (entry.contentBoxSize.blockSize/10)
        ) + 'px';
    } else {
      entry.target.style.borderRadius = Math.min(
        100,
        (entry.contentRect.width/10) +
        (entry.contentRect.height/10)
        ) + 'px';
    }
  }
});

resizeObserver.observe(document.querySelector('div'));