DOM

152 阅读7分钟

DOM

DOM的基本概念

DOM: 文档对象模型
      其实就是操作html中标签的一些能力
比如:
  获取一个元素(标签)
  移除一个元素
  创建一个元素
  向页面添加一个元素
  给元素绑定一些事件
  .....

DoN的核心就是document对象
    document对象是Js内置的一个对象,里边存储着专门用来操作元素的各种方法

DOM:页面中的标签,我们通过JS获取到以后,就把这个对象叫做 DON 对象(DOM节点)

DOM的一些操作

1.获取元素
  1-1. 获取非常规元素
      document.documentElement  -> 获取 html 标签
      document.head             -> 获取 head 标签
      document.body             -> 获取 body 标签
  1-2. 获取常规元素
      (1).同过 ID 名获取标签
          语法: document.getElementById('ID 名')
      
      (2).通过 class 类名获取标签
          语法: document.getElementsByClassName('class 类名')
          注意:因为页面中可能会有多个元素的class相同,所以获取到的是一组元素,获取到后会把元组放到一个很想数组的元素结构中,
          但不是真正的数组,我们称之为  伪数组
          伪数组: 长得很像数组,也是通过索引排列,但是没有数组的方法
      
      (3).通过标签名来获取
          语法:document.getElementsByTagName('标签名')
          注意: 获取到的也是一个伪数组,想要准确的获取到标签元素,我们需要通过索引来帮助我们拿到
      
      *(4).按照选择器的形式来获取元素
          A. querySelector
            这个方法允许我们像写css的时候的选择器一样获取标签
            注意:这个方法只能获取到一个元素,就是满足条件的第一个元素
            语法:document.querySelector('类名')
          B. querySelectorAll
            该方法与querySelect 选择器类似,只不过会将所有满足条件的元素都获取到,获取到的也是一个伪数组
            语法:document.querySelectorAll('标签名')

操作属性

我们获取到元素以后,可以直接操作DOM的属性,然后直接把效果展示在页面

1.innerHTML
  获取元素内部的HTML解构
  我们也可以直接给这个属性重新赋值,达到修改页面的效果

2.innerText
  获取元素内部的文本(只能获取到文本,获取不到html标签)
  我们也可以直接给这个属性重新赋值,达到修改页面的效果

元素属性

1.获取(查询)元素的一些属性
  语法:元素.getAttribute('要查询的属性名')
  返回值:查询到返回属性对应的值
          查询不到返回null

2.修改元素的某些属性
  语法:元素.setAttribute('对应的属性名','对应的属性值')
  注意:如果元素没有对应的属性名,那么相当于是新增一个属性

3.删除元素的某些属性
  语法:元素.removeAttribute('要删除的属性名')

h5 自定义属性

h5  自定义属性
    data-  表示该属性是一个自定义属性
    data-  后边的内容才是属性名,当前案例中属性名为a
    =      后面的内容是属性值

每一个 元素 / DOM节点
    天生自带一个属性,叫做dataset,是一个类似对象的数据结构

案例:
<body>
<div data-a="100"></div>
<script>
  //0.获取标签
  var oDiv = document.querySelector('div')

  //1.访问元素的 dataset 属性
  console.log(oDiv.dataset.a)   //打印100

  //2.增加一个h5自定义属性
  oDiv.dataset.age = 18      
        //标签中没有这个自定义属性,所以是新增
  oDiv.dataset.a = 'QF018'  
        //标签中有这个自定义属性,所以是修改

  //3.删除
  delete oDiv.dataset.a
</script>
</body>

获取元素样式

1.获取行内元素样式
  语法:元素.style.某个属性
  注意:
    我们也可以给这个语法重新赋值,达到修改元素样式的效果(修改的是行内的样式)
    这种语法获取到的元素样式,只能获取到行内样式

2.获取非行内样式
  语法: window.getComputedStyle(元素).要查询的css属性
  注意:这种方式获取到的属性是只读的
        只读:能获取到,但是不允许修改

获取元素偏移量

  • 获取元素在页面上相对于父级 左边 和 上面的 距离 , 参考父级:
  • 其实就是假设你要给一个元素 '绝对定位' ,他就是根据谁来进行定位,那么这个元素的偏移量参考父级就是谁

1.语法: 元素.offsetParent 获取元素的相对父级

2.语法:元素.offsetLeft 获取元素距离父级元素左边的距离

3.语法:元素.offsetTop 获取元素距离父级元素顶部的距离

  <div class="box1">
    <div class="box2"></div>
  </div>
* {
      padding: 0;
      margin: 0;
    }

    .box1 {
      width: 400px;
      height: 400px;
      background-color: pink;
      position: relative;
      top: 20px;
      left: 20px;
    }

    .box2 {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      position: absolute;
      left: 100px;
      top: 200px;
    }
//0.获取元素
    var box2 = document.querySelector('.box2')

    //1.获取相对父级
    console.log(box2.offsetParent)
    //<div class="box1"><div class="box2></div></div>
    
    //2.offsetLeft 
    console.log(box2.offsetLeft)// 100

    //3.offsetTop  
    console.log(box2.offsetTop)// 200

获取元素(浏览器窗口)尺寸

元素的占地面积

1.语法1:

    元素.offsetWidth        元素宽度
    元素.offsetHeight       元素高度

2.语法2:

    元素.clientWidth        元素宽度
    元素.clientHeight       元素高度

两者区别:

    offset XXX -> 实际的宽度/高度 + padding + border
    client XXX -> 实际的宽度/高度 + padding

获取浏览器窗口尺寸

  1. window.innerXXX ---> 计算时候会包含浏览器滚动条

  2. document.documentElement.clientXXX ---> 计算的时候不会计算滚动条(只计算浏览器的可视区域)

获取元素 类名

1. className
    专门用来操作元素的 类名
      语法:元素.className
      我们也可以给他重新赋值。来达到修改元素的类名
      注意:修改时会修改所有类名

2. classList
    获取
      语法:元素.classList
    新增
      语法:元素.classList.add('新增的类名')
    删除
      语法:元素.classList.remove('要删除的类名')
      

DOM 节点

节点类型

一般来说,分为三类

  • 元素节点(标签)
    通过 getELementBy...获取到的都是元素节点
  • 文本节点(标签里的文字)
    通过 innerText 获取到的就是元素的文本节点
  • 属性节点(标签上的属性)
    通过 getAttribute 获取到的都是属性节点

获取节点

  1. 获取某一节点下的所有的 子一级 节点 获取到的是一个伪数组

语法 : 元素.childNodes

  1. 获取某一节点下的所有的 子一级 元素节点 获取到的是一个伪数组里面只有标签

语法 : 元素.children

  1. 获取某一节点下的 子一级 第一个节点

语法:元素.firstChild

  1. 获取某一节点下的 子一级 最后一个节点

语法:元素.lastChild

  1. 获取某一节点下的 子一级 第一个元素节点

语法:元素.firstElementChild

  1. 获取某一节点下的 子一级 最后一个元素节点

语法:元素.lastElementChild

   <div>
    <p>你好</p>
    <span>测试文本呢</span>
    <h1>js 最棒</h1>
  </div>
  
  <script>
  // 0.获取元紊
    var oDiv = document.querySelector('div')

    // 1. childNodes
    console.log(oDiv.childNodes)  //[text, p, text, span, text, h1, text]
    /**
     * 拿到的是一个伪数组,里边有7个节点本
     *    [0]: text 从<div>一直到<p〉中间有一个换行和一堆空格―这是一个文本节点
     *    [1]: p  这个就是p标签,他是第二个节点,这是一个元素节点
     *    [2]: text   从</p>一直到<span>中间有一个换行和一堆空格﹐这是一个文本节点
     * 
    */

    //2.children
    console.log(oDiv.children)    // [p, span, h1]

    //3.firstChild
    console.log(oDiv.firstChild)    //#text

    //4.lastChild  
    console.log(oDiv.lastChild)     //#text

    //5.firstElementChild
    console.log(oDiv.firstElementChild)   //<p>你好</p>

    //6.lastElementChild 
    console.log(oDiv.lastElementChild)    //<h1>js 最棒</h1>
  </script>

获取兄弟节点

1.获取对应的 下一个兄弟节点

语法:元素.nextSibling

2.获取对应的 上一个兄弟节点

语法:元素.previousSibling

3.获取对应的 下一个兄弟的元素节点

语法:元素.nextElementSibling

4.获取对应的 上一个兄弟的 元素节点

语法:元素.previousElementSibling

<div>
  <p>你好</p>
  <span>测试文本呢</span>
  <h1>js 最棒</h1>
</div>

<script>
    //0.获取元素
    var oSpan = document.querySelector( 'span ')
    ////[text, p, text, span, text, h1, text]

    //1.nextSibling
    console.log(oSpan.nextSibling)  //#text

    //2.previousSibling
    console.log(oSpan.previousSibling)  //#text

    //3.nextElementSibling
    console.log(oSpan.nextElementSibling)   //<h1>js 最棒</h1>

    //4.previousElementSibling
    console.log(oSpan.previousElementSibling) //<p>你好</p>
  </script>

获取父节点

1.父节点

语法 : 元素.parentNode

2.获取元素的所有属性节点

语法 : 元素.attributes

  <p>你好</p>
  <span>测试文本呢</span>
  <h1 id="h1_box" class="h1_box_cla" test="QF001" num="100">js 最棒</h1>

  <script>
    //0。获取节点
    var oH = document.querySelector('h1')

    //1. parentNode
    console.log(oH.parentNode)

    //2.attributes
    console.log(oH.attributes)

  </script>

节点属性

1.nodeType

  • 节点中的一个属性 nodeType 能够区分当前节点是什么类型
    •    1 -> 元素节点
      
    •    2 -> 属性节点
      
    •    3 -> 文本节点
      

2.nodeName 节点名称

  •      元素节点 -> 大写的标签名  如:DIV,P UL
    
  •      属性节点 -> text      (属性名)
    
  •      文本节点 -> #text
    
  1. nodeValue 节点的值
  •      元素节点 -> 没有 nodeValue,  会输出null
    
  •      属性节点 -> 对应的属性值
    
  •      文本节点 -> 对应的文本
    
  <ul text="我是ul的一个属性">
    <li>你好</li>
  </ul>
  
  
  <script>
    //0.获取元素
    var oUl = document.querySelector('ul')
    //1.元素节点
    var eleNode = oUl.firstElementChild
    //2.属性节点
    var attNode = oUl.attributes[0]
    //文本节点
    var textNode = oUl.firstChild

    console.log('元素节点: ', eleNode.nodeType)// 1
    console.log('属性节点: ', attNode.nodeType)// 2
    console.log('文本节点: ', textNode.nodeType)// 3


    console.log('元素节点: ', eleNode.nodeName)// LI
    console.log('属性节点: ', attNode.nodeName)// text
    console.log('文本节点: ', textNode.nodeName)// #text

    console.log('元素节点: ', eleNode.nodeValue)// null
    console.log('属性节点: ', attNode.nodeValue)// 我是ul的一个属性
    console.log('文本节点: ', textNode.nodeValue)// 啥也没有
  </script>

操作DOM节点(增删改查)

增删改查

  • 向页面增加一个节点,首先,你需要有一个节点

1.在 JS 中创建一个节点

语法 : document.createElement('要创建的标签名‘)

2.向页面增加一个节点

语法1:元素.appendChild(要添加的节点)

    作用:向元素的末尾添加一个节点

语法2:元素.insertBefore(要插入的节点,插入到哪个节点的前面)

 *  注意 : 两个参数都是必填
        二个参数传递正常节点时,代表插入到这个节点的前面
        第二个参数传递的是null 时,表示插入到“元素”的末尾

3.移除页面某一个节点

语法1:父节点.removeChild('要删除的子节点')

语法2:节点.remove() 直接删除对应的节点

4.修改页面的某一个节点

  • 将页面中的某一个节点进行 替换

语法:父节点.replaceChild('新节点','旧节点/要被修改的节点')

5.获取页面的某一个节点

  • 同之前获取元素的方法

6.克隆一个节点 (复制一个一模一样的标签)

语法:节点.cloneNode(参数)

    参数 : 默认是false,表示不克隆后代节点
           选填是true,表示克隆后代节点

经典案例 : 密码可视化

密码:<input type="password">
  <button id="btn">这是一个眼睛图标</button>
  <script>
    /**
     * 密码可视化
     * 
     *      1.监听btn是否被监听
     *          语法:元素.onclick = function (){}
     *      2.点击时判断 input 的 type 属性
     *          如果type == password  ->  重新赋值为text
     *          如果type === text     ->  重新赋值为password
    */

    //0.获取标签
    var btn = document.querySelector('button')
    var inp = document.querySelector('input')

    //1.监听btn
    btn.onclick = function(){
      //2.点击时判断type
      //方法1
      // if(inp.getAttribute('type') === 'password'){
      //   inp.setAttribute('type','text')
      // }else if(inp.getAttribute('type') === 'text'){
      //   inp.setAttribute('type','password')
      // }

      //方法2
      if(inp.type === 'password'){
        inp.type = 'text'
      }else if(inp.type === 'text'){
        inp.type = 'password'
      }
    }
  </script>