相关文章推荐
老实的橙子  ·  HTML、CSS 和 DOM ...·  2 月前    · 
还单身的松球  ·  jquery ...·  2 月前    · 
不拘小节的山羊  ·  使用内存工具 (“堆快照”分析类型) ...·  2 周前    · 
谈吐大方的弓箭  ·  LUA调试环境(一)_lua ...·  1 年前    · 
严肃的鼠标  ·  cron 表达式详解-腾讯云开发者社区-腾讯云·  1 年前    · 
个性的山寨机  ·  IIS写权限漏洞-菜刀工具-腾讯云开发者社区 ...·  1 年前    · 
大鼻子的小虾米  ·  Java ...·  1 年前    · 
Code  ›  (五)DOM | 微信开放社区
node dom
https://developers.weixin.qq.com/community/develop/article/doc/0002e48b99485857935a42b1e51c13
道上混的紫菜汤
1 年前

交流专区
服务市场
微信学堂
文档
小程序
  • 常用主页

    小程序

    小游戏

    企业微信

    微信支付

  • 服务市场
    微信学堂
    文档
登录
评论

置顶 (五)DOM 精选 热门

贝塔 2020-05-14
2595 浏览
0 评论

DOM

DOM

理解包含不同层次节点的DOM
使用不同的节点类型
克服浏览器兼容性问题以及各种陷阱

DOM描绘了一个层次化的节点数,允许开发人员添加 移除 修改页面的一部分

1.1 节点层次

DOM可以将HTML或XML描绘成一个多层节点构成的结构。
节点拥有不同的类型,每种类型表示文档中不同的信息,每个节点拥有各自的特点,数据和方法,另外与其他节点也存在某种关系。
总共有12种节点类型。

1.1.1 Node类型

DOM1级定义了一个Node接口,该接口将由DOM中所有节点类型实现。
js中的所有节点类型都继承自Node类型,因此所有节点类型都享有共同的属性和方法。
每个节点都有一个 nodeType属性 ,用于表明节点的类型。

比较nodeType 和 Node.ELEMENT_NODE 常量 如果二者相等 则意味着taobao确实是一个元素

<div id="taobao">taobao</div>
console.log(Node.ELEMENT_NODE) // 1
console.log(Node.ATTRIBUTE_NODE)  // 2
console.log(Node.TEXT_NODE) // 3
console.log(Node.CDATA_SECTION_NODE) // 4
console.log(Node.ENTITY_REFERENCE_NODE) //5
console.log(Node.ENTITY_NODE) //6
console.log(Node.PROCESSING_INSTRUCTION_NODE) //7
console.log(Node.COMMENT_NODE) // 8
console.log(Node.DOCUMENT_NODE) //9
console.log(Node.DOCUMENT_TYPE_NODE)//10
console.log(Node.DOCUMENT_FRAGMENT_NODE) //11
console.log(Node.NOTATION_NODE) //12
let taobao = document.getElementById("taobao")
console.log(taobao.nodeType) // 1
if(taobao.nodeType == Node.ELEMENT_NODE){
    console.log('taobao is an ELEMENT')
  • nodeName 和 nodeValue属性
  • 对于元素节点
    nodeName 中保存的始终都是元素标签名
    nodeValue始终都是null

    console.log(taobao.nodeValue)  // null
    console.log(taobao.nodeName) // 元素的标签名   DIV
    每个节点都有一个childNodes属性,其中保存着NodeList对象,NodeList是一个类数组对象。
    访问NodeList中的节点,可以通过方括号,也可以通过item()
    let all = document.getElementById("all")
    console.log(all.childNodes) // 其中保存着NodeList对象,NodeList是一个类数组对象。
    console.log(all.childNodes.length)
    console.log(all.childNodes[1]) // 方括号和item(效果一样)
    console.log(all.childNodes.item(1))
    

    父节点 parentNode
    兄弟节点 previousSibling nextSibling
    第一个孩子节点
    最后一个孩子节点

    console.log(taobao.parentNode) // 父亲节点
    console.log(taobao.previousSibling)  // 上一个兄弟节点
    console.log(taobao.nextSibling)      // 下一个兄弟节点
    console.log(all.childNodes[0]) //第一个孩子节点
    console.log(all.firstChild)    // 第一个孩子节点
    let nodeArr = Array.prototype.slice.call(all.childNodes , 0);  // 将类数组对象转为数组
    console.log(all.childNodes[all.childNodes.length - 1]) // 最后一个孩子节点
    console.log(all.lastChild)  //最后一个孩子节点
    appendChild()
    在childNodes末尾添加一个节点,返回新增的节点。如果传入到appendChild()中的节点已经是文档的一部分了,那会将该节点移到新位置
    insertBefore()
    传入两个参数,要插入的节点,作为参照的节点。插入节点后,被插入的节点会变成参照节点的一个preciousSiblings节点
    如果参照节点是null,那么效果和appendChild()一样
    replaceChild()
    传入两个参数,要插入的节点和要替换的节点
    removeChild()
    只接一个参数,要移除的节点
    上面四个方法操作的都是某个节点的子节点,所以必须先取得父节点

    ownerDocument()
    该属性表示整个文档的文档节点。

    // 操作节点
    let all = document.getElementById("all")
    let xianyu = document.getElementById("xianyu")
    let tianmao = document.getElementById("tianmao")
    all.appendChild(tianmao)
    all.insertBefore(tianmao , xianyu)
    all.replaceChild(tianmao , xianyu)
    all.removeChild(tianmao)
    cloneNode()
    接受一个布尔值,表示是否深复制
    true 深复制 会赋值整个节点以及其子节点数
    false 浅赋值,只复制节点本身
    let anotherXianyu = xianyu.cloneNode(true); // 深复制
    let anotherXianyu1 = xianyu.cloneNode(false); // 浅复制
    console.log(anotherXianyu)
    console.log(anotherXianyu1)
    

    1.1.2 Document类型

    js通过Document类型表示文档。在浏览器中,document是HTMLDocument的一个实例,表示整个页面。
    而且document是window对象的一个属性,因此可以通过全局对象来访问。
    Document节点具有下列特征

    console.log(document.nodeName)  // #document
    console.log(document.nodeValue) // null
    console.log(document.parentElement) // null
    console.log(document.parentNode) // null
    console.log(document.ownerDocument) //null
    
  • 文档的子节点
  • document.documentElement  // <html>
    document.body // <body>
    
    console.log(document.title)
    console.log(document.URL)
    console.log(document.domain)
    getElementById()
    
    document.getElementById("")
    document.getElementsByName("")
    document.getElementsByTagName("")
    

    DOM一致性检测

    document.open()
    document.write()
    document.writeln()
    document.close()

    1.1.3 Element类型

  • HTML元素
    每个HTML元素都有以下特性
    id title dir className lang
  • <div id="id" class="black" dir="ltr" title="标题" lang="en">中国</div>
    let ele = document.getElementById("id") 
    console.log(ele.id) // 
    console.log(ele.className) // black
    console.log(ele.dir) // 文字对齐方式
    console.log(ele.lang) // en
    console.log(ele.title) // 标题
    setTimeout(()=>{
        ele.className = "red";
        ele.dir="rtl"
    } , 1000)
    通常直接获得特性,只有在获取自定义属性时才会用getAttribute()
    
    <div id="id" class="black" dir="ltr" title="标题" lang="en" myName="wujie">中国</div>
    let ele = document.getElementById("id") 
    console.log(ele.getAttribute("id"))
    console.log(ele.getAttribute("class"))
    console.log(ele.getAttribute("title"))
    console.log(ele.getAttribute("dir"))
    console.log(ele.getAttribute("lang"))
    // 获取自定义属性
    console.log(ele.getAttribute("myName"))  //wujie
    console.log(ele.myName)  // undefined
    setAttribute() 既可以设置HTML特性,也可以设置自定义属性
    
    <div id="id" class="black" dir="ltr" title="标题" lang="en" myName="wujie">中国</div>
    let ele = document.getElementById("id") 
    ele.setAttribute("class" , "red");
    ele.setAttribute("title" , "新标题");
    ele.myTitle = '我的标题'; // 直接设置自定义特性是不行的
    console.log(ele.getAttribute("myTitle")) // null
    ele.setAttribute("myTitle" , "我的标题")
    console.log(ele.getAttribute("myTitle")) // 我的标题
    

    彻底删除特性 以及特性的值
    removeAttribute()

  • attributes属性
    Element 类型时唯一使用attributes属性的DOM 节点类型。
    attributes包含元素的每一个特性以及部分方法
  • attributes通常用来遍历元素的所有属性

    document.createElement()可以创建元素
    这个方法只接受一个参数,就是元素的标签名 appendChild
    insertBefore
    replaceChild
    把元素放进

    let ele = document.getElementById("id") 
    let div = document.createElement("div")
    div.className = "red";
    div.innerHTML = "createElement"
    ele.appendChild(div)
    
  • 元素的子节点
    由于文本 注释 等等也算子节点 ,所以获取元素的子节点时需要注意。
  • let ul = document.getElementsByTagName("ul")[0]
    let ulChildArr = Array.prototype.slice.call(ul.childNodes , 0)  // 将childNodes转为数组
    console.log(ulChildArr) // [text, li, text, li, text, li, text]
    // 过滤掉其他节点 只留下元素节点 即 nodeType 为1 的节点
    let ulChildEleArr = ulChildArr.filter((item , index , arr) => {
        return item.nodeType == '1'
    console.log(ulChildEleArr)  // [li, li, li]
    

    1.1.4 Text类型

    nodeType 为 3
    nodeValue 为文本
    nodeName 为 #text
    parentNode 是一个 Element

    <div id="txt-div">这是一个文本</div>
    // 文本节点
    let txtDiv = document.getElementById("txt-div");  
    // [text, div, text]
    let textNode = txtDiv.childNodes[0]
    console.log(textNode.nodeName) // #text
    console.log(textNode.nodeType) // 3
    console.log(textNode.nodeValue) // 这是一个文本
    console.log(textNode.parentNode)
    
    // 例如动态加入一个 
    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = './node.js';
    document.appendChild(script)
    

    1.2.2 动态样式

    与动态脚本类似 不过<link>需要加到<head></head>里面

    // 封装成函数
    function loadStyle(url){
        let style = document.createElement("link")
        style.rel = "stylesheet";
        style.type = "text/css";
        style.href = url;
        let head = document.getElementsByTagName("head")[0];
        head.appendChild(style)
    

    1.2.3 操作表格

    1.2.4 使用NodeList

    理解 NodeList 以及其近亲 NameNodeMap HTMLCollection是理解DOM的关键
    NodeList是动态的,每次访问NodeList都会运行一次基于文档的查询

    1.3 小结

    DOM由各种节点组成,简要总结如下

  • 最基本的节点是Node,用于抽象的表示文档中独立的一部分,所有其他类型都继承自Node
  • Document类型表示整个文档。在js中,document是Document的一个实例,
    使用document对象,有很多方式可以查询和取得节点
  • Element类型表示文档中所有HTML或XML元素
    理解DOM就是理解DOM对性能的影响,DOM操作是js中开销最大的部分。
    而因访问NodeList导致的问题最多,因为NodeList是动态的,每次访问NodeList都会运行一次基于文档的查询
    所以尽量要减少DOM操作
  •  
    推荐文章
    老实的橙子  ·  HTML、CSS 和 DOM 中的空白符是如何处理的 - Web API | MDN
    2 月前
    还单身的松球  ·  jquery 监听dom元素发生变化_jquery domnodeinserted
    2 月前
    不拘小节的山羊  ·  使用内存工具 (“堆快照”分析类型) 记录堆快照 - Microsoft Edge Developer documentation | Microsoft Learn
    2 周前
    谈吐大方的弓箭  ·  LUA调试环境(一)_lua opencv-CSDN博客
    1 年前
    严肃的鼠标  ·  cron 表达式详解-腾讯云开发者社区-腾讯云
    1 年前
    个性的山寨机  ·  IIS写权限漏洞-菜刀工具-腾讯云开发者社区-腾讯云
    1 年前
    大鼻子的小虾米  ·  Java 实现PHP的openssl_encrypt()_熊先生的博客的博客-CSDN博客
    1 年前
    今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
    删除内容请联系邮箱 2879853325@qq.com
    Code - 代码工具平台
    © 2024 ~ 沪ICP备11025650号