【原生DOM】DOM编程

26 篇文章 0 订阅
10 篇文章 0 订阅

DOM编程

目录

  • 前置知识
  • 网页就是一棵DOM树
  • JS如何操作这棵树
  • DOM元素
  • 节点的增删改查
  • DOM操作是跨线程的
  • Property VS Attribute

一、前置知识

  1. 理解简单的JS语法
  2. JS的七种数据类型:number、string、bool、symbol、undefined、null、Object
  3. JS五个falsy值:''、undefined、null、0、NaN
  4. 简单的CSS布局

二、网页是一棵DOM树

  • 代码+图解
      <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>DOM树</title>
      </head>
      <body>
        <header>
          <h1>文字1</h1>
        </header>
        <main>
          <h2>文字2</h2>
          <p>文字3<span>文字4</span>文字5</p>
        </main>
      </body>
    </html>
    

DOM树


三、JS如何操作这棵树?

  • 使用document操作网页
  • 这就是DOM(Document Object Model)文档对象模型

四、DOM元素

  • 获取元素(标签)
    
      document.getElementById('xxx');
      .
      document.getElementsByTagName('div')[0];
      .
      document.getElementsByClassName('red')[0];
      .
      document.querySelector(''); | 需要遵守选择器的样式书写 如:'#id_1''.class_1'.
      document.querySelectorALL(); |同上
    
  • 获取特定元素
      1、获取html元素
        document.documentElement
    
      2、获取head元素
        document.head
    
      3、获取body元素
        document.body
    
      4、获取窗口 |窗口不是元素
        window
    
      5、获取所有元素
        document.all  
    
    window.all: 是第6个falsy值 原因:因为window.all最早是IE发明的,早期的前端为了区分IE和其他浏览器,就一般如下设置。为了区分是IE还是非IE浏览器。
      if(window.all){
        console.log("这些代码只能在IE里面运行");
      }
      else{
        console.log("这些代码只能在非IE里面运行");
      }
    

  • 问题来了:获取到的元素到底是个啥?
    1. 显然获取到的元素是个对象
    2. 抓一只div对象来看看都有啥
       console.dir(div);
      
    3. div的6层原型链
      div的六层属性
      div的原型链

  • 节点?元素?傻傻分不清楚

    使用 nodeType方法可以打印出节点的值

    1. 1表示元素ELement,也叫标签Tag
    2. 3表示文本Text
    3. 8表示注释Comment
    4. 9表示文档Document
    5. 更多节点值

五、节点的增删改查


1、增

  • 创建一个标签节点
      let div1=document.createElement('div');
      document.createElement('style');
      document.createElement('script');
      document.createElement('li');
    
  • 创建一个文本节点
      text1=document.createTextNode('你好');
    
  • 插入创建的节点:坑1:一个元素不能同时出现在(插入)两个地方,除非复制一份。
      div1.appendChild(text1); | 在div1标签里面插入文本节点text1
    
      document.body.appendChild(div1); | 在body里面插入div1标签
    
      document.head.appendChild(div1); | 在head里面插入div1标签
    

2、删

  • 删除节点:坑2:删除之后的节点被移除DOM树,但还在内存中,依然可以调用它再将其添加回来
      旧方法 | parentNode.removeChild('待删除的儿子节点')
    
      新方法 | 待删除的节点.remove();
    

3、改

  • 写标准属性:注意:js中不识别'-'这个字符,所以遇到'-'就将'-'后面第一个字母大写,如:background-color --> backgroundColor
    class | div.style.className='red blue'; --> 全覆盖
    改class | div.classList.add('red');
    改style | div.style='width:100px;color:blue'; --> 全覆盖
    改style | div.style.width='200px'; --> 推荐
    改data-*属性 | div.dataset.x='frank';
    
  • 读标准属性:下面两种方法都可以读属性,但某些情况下的值可能会不同。
      默认方法 | div.classList/a.href
      getter/setter方法 | div.getAttribute('class')/a.getAttribute('href');
    
  • 改文本内容
      div.innerText='你好,世界!';
      div.textContent='你好,世界!';
    
  • 改HTML内容
      div.innerHTML='<strong>重要的内容</strong>';
    
  • 改标签
      div.innerHTML=''; | 先清空内容
      div.appendChild(div2); | 再添加内容
    
  • 改父元素?
      newParent.appendChild(div); | div的父元素变成newParent,并且从原来的地方消失。
    

4、查

  • 查爸爸
      node.parentNode | node.parentElement
    
  • 查爷爷
      node.parentNode.parentNode
    
  • 查子代:坑1:当子代变化时,两者也会实时变化,例如遍历的数组长度length
      node.childNodes | node.children
    
  • 查兄弟姐妹
      node.parentNode.childNode | 注意要排除自己
      node.parentNode.children | 注意要排除自己
    
  • 查看老大、老幺
      node.firstChild
      node.lastChild
    
  • 查看上一个节点元素
      node.previousSibling
    
  • 查看下一个节点元素
      node.nextSibling
    
  • 遍历一个div里面的所有元素
      travel = (node,fn)=>{
        fn(node);
        if(node.children){
          for(let i=0;i<node.children.length;i++){
            travel(node.children[i],fn);
          }
        }
      }
    
      travel(div,(node)=>{
        console.log(node);
      })
    

六、DOM操作是跨线程的

  • 跨线程操作

    1. JS引擎不能操作页面,只能操作JS
    2. 渲染引擎不能操作JS,只能操作页面
    3. 例如执行如示代码:document.body.appendChild(div1) JS 是如何改变页面的?
  • 跨线程通信

    1. 当浏览器发现JS在body里面加了一个div对象
    2. 浏览器就会通知渲染引擎在页面里也新增一个div元素
      DOM跨线程
  • 插入新标签的完整过程

    1. 在div1放入页面之前
       对div1进行的所有操作都是在JS线程中进行的
      
    2. 在div1放入页面之时
       浏览器发现了JS的意图,通知渲染线程在页面中渲染div1对应的元素
      
    3. 把div1放入页面之后
       当你想对div1再次进行操作时,都会有可能触发重新渲染
      
  • 属性同步

    1. 标准属性:如id,className,title等
    2. data-*属性
    3. 非标准属性:除开1,2两点的其他自定义属性
    4. 自动属性同步
       <!DOCTYPE html>
       <html>
       <head>
         <meta charset="utf-8">
         <title>JS Bin</title>
       </head>
       <body>
       <div id="test" x="test" data-x="test">
         <p>id 一开始为 test,后来改为 frank
         <p>你会发现页面中 id 变为 frank
         <p>data-x 属性一开始为 test,后来改为 frank
         <p>你会发现页面中的 data-x 变成了 frank
         <p>x 属性一开始为 test,后来改为 frank
         <p>你会发现页面中的 x 还是 test
       </div>
       <script>
         let div1 = document.querySelector('#test')
         div1.id = 'frank' // 同步过去了
         div1.dataset.x = 'frank' // 同步过去了
         div1.x = 'frank' // 没有同步过去
         div1.style.border = '1px solid red'
       </script>
       </body>
       </html>
      
      属性同步

七、Property VS Attribute

  • property属性

    JS 中div1的所有属性,叫做div1的property

  • attribute属性

    渲染引擎中div1对应标签的属性,叫做attribute

  • 二者的区别

    1. 大部分时候,同名的property和attriubte值相等。
    2. 但如果不是标准属性,两者的值只会在一开始的时候相等
    3. attribute: 只支持字符串类型

七、Property VS Attribute

  • property属性

    JS 中div1的所有属性,叫做div1的property

  • attribute属性

    渲染引擎中div1对应标签的属性,叫做attribute

  • 二者的区别

    1. 大部分时候,同名的property和attriubte值相等。
    2. 但如果不是标准属性,两者的值只会在一开始的时候相等
    3. attribute: 只支持字符串类型
    4. property: 支持字符串、布尔等类型
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值