DOM编程

DOM编程(Document Object Model)

如何获取元素(标签)

获取任意元素

  • 简单写法

    • window.idxxx
    • idxxx
  • 兼容ie专用

    • document.getElementByld('id')
    • document.getElementsByTagName('div')[0]
    • document.getElementsByClassName('class')[0]
  • 工作用

    • document.querySelector('80%情况下css选择器咋写就咋写')
    • document.querySelectorAll('.red')[0]

获取特定元素

  • 获取根元素html元素: document.documentElement
  • 获取head元素: document.head
  • 获取body元素: document.body
  • 获取窗口(不是一个元素):window
  • 获取所有元素:document.all

看一个div对象的原型链

console.dir(div1)看原型链

  • 自身属性: className、id、style 等等
  • 第一层原型HTMLDivElement.prototype: 这里面是所有div共有的属性,不用细看
  • 第二层原型HTMLElement.prototype: 这里面是所有HTML标签共有的属性,不用细看
  • 第三层原型Element.prototype: 这里面是所有XML、HTML 标签的共有属性,你不会以为浏览器 只能展示HTML吧
  • 第四层原型Node.prototype: 这里面是所有节点共有的属性,节点包括XML标签文本注释、 HTML标签文本注释等等
  • 第五层原型EventTarget.prototype: 里面最重要的函数属性是addEventListener
  • 最后一层原型就是Object.prototype了

图示

  • Subtopic

节点Node

元素Element(标签Tag)节点--1

文本Text节点--3

注释Comment节点--8

文档Document节点--9

节点Node的增删改查

增节点

  • 创建一个标签节点

    • document.createElement('标签名')
    • let div1 = document.createElement('div')
  • 创建一个文本节点

    • text1 = document.createTextNode("你好")
  • appendChild() 方法

    • 添加新的子节点
    • node.appendChild(node)
    • 一个元素不可以出现在两个地方,除非复制
  • 标签里面插入文本

    • div1. appendChild(text1) 必须加文本节点的名字,不可以加文本的内容
    • div1.innerText='你好' Node原型提供的接口
    • div1.textContent ='你好' Element提供的接口
  • 插入页面中

    • 默认处于js线程中
    • 必须插入head或者body中才生效document.body.appendChild(div)
    • 或者已在页面中的元素.appendChild(div)

删节点

  • 旧方法: parentNode.removeChild(childNode)
  • 新方法: childNode.remove() 直接删除

  • 改节点的标准属性

    • 改class

      • div.className= 'red blue' (全覆盖)
      • div.className += 'blue' (增加)
      • div.classList.add('blue')(增加)
    • 改style

      • div.style = ' 100px; color: blue;'(全覆盖)
      • 改style的一部分: div.style.width = '200px'
      • 大小写: div.style.backgroundColor = 'white' C大写表示-c
    • 改data-*属性

      • div.dataset.x = 'frank'(没人用了)
    • 读标准属性

      • div.classList / a.href(会给你把路径补充完整)前面加http
      • div.getAttribute('class') / a.getAttribute('href')(原封不动的给你)
  • 改节点的事件处理函数

    • div.onclick默认为null

      • 默认点击div不会有任何事情发生
      • 但是如果你把div.onclick改为一个函数fn,那么点击div的时候,浏览器就会调用这个函数
      • 并且是这样调用的fn.call(div, event)
      • div会被当做this
      • event则包含了点击事件的所有信息,如坐标
      • div.addEventListener 是div.onclick的升级版
  • 改子节点

    • 改文本内容

      • div.innerText = 'xxx'
      • div.textContent= 'xxx'
    • 改HTML内容

      • div.innerHTML = '重要内容'
    • 改标签

      • div.innerHTML = ''//先清空
      • div.appendChild(div2) //再加内容
    • 改父节点

      • newParent.appendChild(div)
      • 直接这样就可以了,直接从原来的地方消失

查节点

  • 查自己

    • node
  • 查爸爸

    • node.parentNode
    • node.parentElement
  • 查爷爷

    • node.parentNode.parentNode
  • 查子代

    • 所有

      • node.childNodes(会把你不想要的空格也当成一个文本子节点)
      • node.children(这个不会,只是元素节点,优先使用)
      • 当子代变化时,两者也会实时变化
      • document.querySelectorAll('.red')[0]不会实时更新
    • 一个

      • node.children[0]
      • 查看第一个node.firstChild
      • 查看最后一个node.lastChild
  • 查兄弟姐妹

    • 查所有兄弟姐妹

      • node.parentNode.childNodes但自己也在里面,要排除自己和所有文本节点
      • node.parentNode.children但自己也在里面,要排除自己
      • 排除自己:要用for循环遍历所有子节点,然后把自己排除出去
    • 查特定的兄弟姐妹

      • 查看上一个哥哥/姐姐node.previousSibling(节点兄弟,可能为文本节点)
      • 查看上一个哥哥/姐姐node.previousElementSibling(元素兄弟)
      • 查看下一个弟弟/妹妹node.nextSibling(节点兄弟,可能为文本节点)
      • 查看下一个弟弟/妹妹node.nextElementSibling(元素兄弟)
    • 查看一个节点里所有的元素

      • 数据结构 遍历div里面所有元素

DOM操作是跨线程的

各线程各司其职

  • JS引擎不能操作页面,只能操作JS
  • 渲染引擎不能操作JS,只能操作页面

跨线程通信

  • document.body.appendChild(div1)---这是一句跨线程的DOM操作
  • 当浏览器发现JS在body里面加了个div1对象
  • 浏览器就会通知渲染引擎在页面里也新增一个div元素
  • 新增的div元素所有属性都照抄div1对象

插入新标签的完整过程

  • 在div1放入页面之前

    • 你对div1所有的操作都属于JS线程内的操作
    • let div1 = document.createElement('div')
      div1.textContent = 'hi'
  • 把div1放入页面之时

    • document.body.appendChild(div1)
    • 浏览器会发现JS的意图,就会通知渲染线程在页面中渲染div1对应的元素
  • 把div1放入页面之后

    • 你对div1的操作都有可能会触发重新渲染
    • div1.id = 'newid'可能会重新渲染,也可能不会
    • div1.title= 'new'可能会重新渲染,也可能不会
    • 如果你连续对div1多次操作,浏览器可能会合并成一 次操作,也可能不会(之前在动画里提到过)
  • 属性同步

    • 标准属性

      • 对div1的标准属性的修改,会被浏览器同步到页面中
      • 比如id、className、 title 等
    • data-*属性 同上

    • 非标准属性

      • 对非标准属性的修改,则只会停留在JS线程中,不会同步到页面里
      • 比如x属性,示例代码
    • 启示

      • 如果你有自定义属性,又想被同步到页面中,请使用
      • data-作为前缀
  • Property V.S. Attribute

    • property属性:JS线程中div1对象的所有属性,叫做div1的property

    • attribute也是属性:渲染引擎中div1元素的属性,叫做attribute

    • 区别

      • 大部分时候,同名的property和attribute值相等
      • 但如果不是标准属性(把div1放入页面之后只有标准属性会同步),那么它俩只会在一开始时相等(把div1放入页面之时,全过去)
      • 但注意attribute只支持字符串,而property支持字符串、布尔等类型
作者:过程是风景
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/justcho/p/13472564.html