最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • DOM操作总结

    正文概述 掘金(A_A)   2021-05-28   695
    知识点
    • DOM 本质
    • DOM 节点操作
    • DOM 结构操作
    • DOM 性能

    前言

    各种框架层出不穷,但DOM操作一直都会是前端工程师的基础,必备知识。
    只会Vue和React等框架,而不懂DOM操作的前端程序员们。。。DOM操作总结

    DOM的本质?

    Do you know?

    DOM操作总结

    首先,先了解一下什么是xml 。 上代码:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
    </note>
    

    XML (可扩展标记语言 EXtensible Markup Language)

    XML 是一种标记语言, 被设计用来传输和存储数据,而非显示数据(HTML就被设计用来显示数据)

    XML使用的标签没有被预定义,你需要自行定义标签。

    SGML、HTML、XML、XHTML、HTML5 之间的关系,知道否?

    HTML是一种特殊的XML。它遵循W3C的规定,各种规定,必须先写什么,怎么写什么。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div>
            <p>跟着W3C标准,有饭吃。。。ヽ( ̄▽ ̄)ノ</p>
        </div>
    </body>
    </html>
    

    DOM操作总结

    那么如果是一个字符串对象(html一大坨)的话,让浏览器,js处理是非常不方便的。
    如何查询,如何操作等等比较麻烦。所以浏览器拿到代码之后。。。

    DOM可以理解为浏览器把拿到的html代码,结构化一个浏览器能识别并且js可操作的一个模型而已(也就是DOM结构树)

    DOM操作总结

    树结构什么的不要我讲了吧

    DOM 节点操作

    获取 DOM 节点

    • 通过元素类型的方法来操作:
    1. **document.getElementById(); //id名,在实际开发中较少使用,选择器中多用class id一般只用在顶级层存在 不能太过依赖id
      **
    2. **document.getElementsByTagName(); //标签名
      **
    3. **document.getElementsByClassName(); //类名
      **
    4. **document.getElementsByName(); //name属性值,一般不用
      **
    5. **document.querySelector(); //css选择符模式,返回与该模式匹配的第一个元素,结果为一个元素;如果没找到匹配的元素,则返回null
      **
    6. **document.querySelectorAll() //css选择符模式,返回与该模式匹配的所有元素,结果为一个类数组
      **

    注意:

    • 前缀为document,意思是在document节点下调用这些方法,当然也可以在其他的元素节点下调用哦!
    • querySelector()querySelectorAll()两个方法为静态的,不是实时的,保存的是当时的状态,是一个副本,即:在以后的代码中通过方法使所选元素发生了变化,但该值依然不会改变,因此使用有局限性,一般不用,除非就想得到副本

    DOM操作总结

    • 根据关系树来获取节点(遍历节点树):

    根据前面,我们已经知道:DOM(文档对象模型)可以将任何HTML、XML文档描绘成一个多层次的节点树。所有的页面都表现为以一个特定节点为根节点的树形结构。html文档中根节点为document节点。

    DOM操作总结

    所有节点都有nodeType属性,代表节点的不同类型,通过nodeType属性可以来判断节点的类型。

    经常使用的节点主要有以下几种类型:

    1. Element类型(元素节点):nodeType值为 1
    2. Text类型(文本节点):nodeType值为 3
    3. Comment类型(注释节点):nodeType值为 8
    4. Document类型(document节点):nodeType值为 9

    其规定的一些常用的属性有:

    • document.body document.head 分别为HTML中的 <body> <head>
    • document.documentElement<html>标签

    所有的节点都有 hasChildNodes()方法,用来判断有无子节点 有一个或多个子节点时返回true

    通过一些属性可以来遍历节点树:

    1. parentNode //获取所选节点的父节点,最顶层的节点为#document
    2. childNodes //获取所选节点的子节点们
    3. firstChild //获取所选节点的第一个子节点
    4. lastChild //获取所选节点的最后一个子节点
    5. nextSibling //获取所选节点的后一个兄弟节点 列表中最后一个节点的nextSibling属性值为null
    6. `previousSibling` //获取所选节点的前一兄弟节点 列表中第一个节点的`previousSibling`属性值为`null`

    注意:
    由于文档中的节点类型较多,遍历子节点的结果很多时候并不能得到我们想要的结果。
    小心哦!!空文本也是文本节点!
    使用遍历元素节点则很方便。

    DOM操作总结

    • 基于元素节点树的遍历(遍历元素节点树):
    1. parentElement //返回当前元素的父元素节点(IE9以下不兼容)
    2. children // 返回当前元素的元素子节点
    3. firstElementChild //返回的是第一个元素子节点(IE9以下不兼容)
    4. lastElementChild //返回的是最后一个元素子节点(IE9以下不兼容)
    5. nextElementSibling //返回的是后一个兄弟元素节点(IE9以下不兼容)
    6. previousElementSibling //返回的是前一个兄弟元素节点(IE9以下不兼容)

    注意:
    这些获取节点的方式,返回值要么是一个特定的节点,要么是一个集合HTMLCollection,这个节点的集合是一个类数组。

    HTML中的 attribute 和 JavaScript中的 property

    attribute

    **attribute是HTML标签中定义的属性(修改html属性,会改变html结构),它的值只能是字符串。
    attribute 有三个方法:setAttribute() , getAttribute(), removeAttribute()
    **

    property

    property是JavaScript为元素对象定义的属性(修改对象属性,不会体现到html结构中)property 属性可以看作 DOM 对象的键值对,用点操作符修改。它也可以和其他的 JavaScript 对象一样添加自定义的属性以及方法。property 的值可以是任何的数据类型,对大小写敏感。

    attribute 和 property 共同拥有的属性

    虽然Attribute和Property定义的属性分别在不同层面上,但是有以下几个属性是共享的:
    id class lang dir title

    <div id="div" class="class" lang="lang" dir="dir"  user="user" >
    
    
     var ele = document.getElementById('id');
     
     console.log(ele.getAttribute('id'))    // id
     console.log(ele.getAttribute('class')) // class
     console.log(ele.getAttribute('lang'))  // lang
     console.log(ele.getAttribute('dir'))   // ltr
     console.log(ele.getAttribute('title')) // title
     console.log(ele.getAttribute('user'))  // user
    
     ele.user1= 'user1'
     console.log(ele.id)                    // id
     console.log(ele.className)             // class
     console.log(ele.lang)                  // lang
     console.log(ele.dir)                   // ltr
     console.log(ele.title)                 // title
     console.log(ele.user1)                 // user
    
     console.log(ele.user)                  // undefined
     console.log(ele.getAttribute('user1')) // null
    

    自定义的 property 不会出现在 html 代码中,只存在 js 中。因此,ele.getAttribute(‘user1’) 结果为:null

    html 标签的5个标准特性:id,title,lang,dir,className(在DOM中以property方式操作这几个特性会同步到html标签中)。所以即使在html中没有指定id、title等,也会默认赋予一个空串,通过property属性(点操作符)可以访问。 而除此之外在html中设置的其他属性是不能通过Property访问到的(除了attribute特有的属性)。因此,ele.user 结果为:undefined

    注意:
    有一些比较特殊的情况:

    - input 元素的 value

    var input1 = document.getElementById('input1'); // 获取id为'input1' 的input元素
    input1.setAttribute('value', 'test');  // 用setAttribute()方法设置value属性为'test'
    console.log(input1.value); // test
    
    a.value = 'change';   // property方式设置value
    console.log(a.getAttribute('value')); // test
    

    用点操作符修改 value 值,并不会同步到 attribute 上;但是通过 setAttribute 修改属性值,会同步到 property 上。

    - 表单

    <input type='radio' checked='checked' id='radio'>
    <script>
      var radio = document.getElementById('radio');
      console.log(radio.getAttribute('checked')); // 'check'
      console.log(radio.checked); // true
    </script>
    

    一些表单元素,对于这些特殊的 attribute 节点,只要存在该节点,对应的 property 就为true,disabled 类似

    - href

    <a href='a.html' id='web'> </a>
    <script>
      var radio = document.getElementById('web');
      console.log(web.getAttribute('href')); // 'a.html' 
      console.log(web.href); // 绝对路径
    </script>
    

    attribute 取得是相对路径;property 取得是绝对路径。

    建议:

    尽量使用property,因为property可能会在js的一些机制中避免DOM的重新渲染,而attribute一旦改了html结构,则一定会引起DOM重新渲染。

    以下两种情况用attribute:

    1. 自定义 attribute 标签,因为它不能同步到 property 上。
    2. 访问内置的 html 标签的 attribute,如 input 的 value(可以用来检验 value 值是否改变)

    DOM 结构操作

    • 新增/插入节点
    • 获取子元素列表,获取父元素
    • 删除子元素

    各种DOM操作,请读者自由发挥,耍起来哟~~
    一定要记得多敲敲!!!

    DOM操作总结

    示例:主要代码如下

    <div id="div1" class="container">
    	<p id="p1">一段文字 1</p>
        <p>一段文字 2</p>
        <p>一段文字 3</p>
    </div>
    <div id="div2">
        <img src="https://img-blog.csdnimg.cn/20200201200740869.jpg"/>
    </div>
    
    const div1 = document.getElementById('div1')
    const div2 = document.getElementById('div2')
    
    // 新建节点
    const newP = document.createElement('p')
    newP.innerHTML = 'this is newP'
    // 插入节点
    div1.appendChild(newP)
    
    // 移动节点
    const p1 = document.getElementById('p1')
    div2.appendChild(p1)
    
    // 获取父元素
    console.log( p1.parentNode )
    
    // 获取子元素列表
    const div1ChildNodes = div1.childNodes
    console.log( div1.childNodes )
    const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => {
        if (child.nodeType === 1) {
            return true
        }
        return false
    })
    console.log('div1ChildNodesP', div1ChildNodesP)
    
    // 删除子元素
    div1.removeChild( div1ChildNodesP[0] )
    

    DOM 性能

    DOM 操作非常“昂贵”,避免频繁的DOM操作。

    • 对DOM 查询做缓存

      // 不缓存 DOM 查询结果 for (let = 0; i < document.getElementsByTagName('p').length; i++) { // 每次循环,都会计算 length, 频繁进行 DOM 查询 }

      // 缓存 DOM 查询结果 const pList = document.getElementsByTagName('p') const length = pList.length for (let i = 0; i < length; i++) { // 缓存 length, 只进行一次 DOM 查询 }

    • 将频繁操作改为一次性操作

      const list = document.getElementById('list')

      // 创建一个文档片段,此时还没有插入到 DOM 结构中 const frag = document.createDocumentFragment()

      for (let i = 0; i < 20; i++) { const li = document.createElement('li') li.innerHTML = List item ${i}

      // 先插入文档片段中
      frag.appendChild(li)
      

      }

      // 都完成之后,再统一插入到 DOM 结构中 list.appendChild(frag)

      console.log(list)

    复习回顾

    DOM操作总结

    DOM 是哪种数据结构

    • 树(DOM树)

    DOM 操作的常用API

    • DOM 节点操作
    • DOM 结构操作
    • attribute 和 property 操作

    attribute 和 property 的区别

    • attribute:修改html属性,会改变html结构
    • property:修改对象属性,不会体现到html结构中
    • 两者都有可能引起DOM重新渲染

    一次性插入多个DOM节点,考虑性能

    • 你可以翻上去再瞧瞧

    起源地下载网 » DOM操作总结

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元