美文网首页
js归纳总结——DOM操作

js归纳总结——DOM操作

作者: BULL_DEBUG | 来源:发表于2018-05-03 11:00 被阅读226次

    关于dom操作,分创建、增、删、改、查、属性操作、事件操作来总结一下

    创建

    1.createElement:通过传入标签来创建一个dom

    demo

    var node=document.createElement('div')
    node.innerHTML='我是新增的node'
    document.body.appendChild(node)
    
    2.createTextNode:用来创建一个文本节点

    demo

    var node=document.createTextNode('我是新增的文本节点')
    document.body.appendChild(node)
    
    3.cloneNode:克隆一个节点,有一个参数,true支持深度克隆,false不支持深度克隆

    demo

      <div id="div1">我是一个dom
        <span>我是一个子节点</span>
      </div>
      <script type="text/javascript">
      var cn = document.querySelector('#div1').cloneNode()
      var cn2 = document.querySelector('#div1').cloneNode(true)
      console.log(cn)
      console.log(cn2)
      </script>
    
    //浅拷贝的结果为
    <div id="div1"></div>
    
    //深拷贝的结果为:
    <div id="div1">我是一个dom
        <span>我是一个子节点</span>
    </div>
    
    4. createDocumentFragment: 用来插入一段dom

    这个方法的运用,可以减少页面的重绘与回流问题,能批量的插入dom
    demo

      var temp = document.createDocumentFragment()
      var a = document.createElement('div')
      a.innerHTML = 'It\'s a'
      var b = document.createElement('span')
      b.innerHTML = 'It\'s b'
      temp.appendChild(a)
      temp.appendChild(b)
      document.body.appendChild(temp)
    

    添加到body之前,都没有真正的加入到dom tree里面,避免了重绘与回流

    1.appendChild

    A.appendChild(B):将B添加到A子元素的最后一个位置,如下
    默认的dom结构

      <div id="parent">
        <span>我是一开始就有的子节点</span>
      </div>
    执行以下的js之后
    
      var parent = document.querySelector('#parent')
      var child = document.createElement('div')
      child.innerHTML = '我是子节点'
      parent.appendChild(child)
    <div id="parent">
      <span>我是一开始就有的子节点</span>
      <div>我是子节点</div>
    </div>
    
    2.insertBefore

    parent.insertBefore(newNode, exitsNode):将newNode添加到exitsNode的前面
    默认dom结构

    <div id="me">
        <div>child</div>
        <div>child2</div>
        <div>child3</div>
        <div>child4</div>
        <div>child5</div>
        <div>child6</div>
        <div>child7</div>
      </div>
    <input type="number">
    <button>新增一个孩子</button>
    执行以下的js代码,填入一个数字,点击按钮之后
    
      function addNode() {
        var index = document.querySelector('input').value
        var tempDom = document.createElement('div')
        tempDom.innerText = '我是新增的孩子'
        var me = document.querySelector('#me')
        var children = me.querySelectorAll('div')
        me.insertBefore(tempDom, children[index])
      }
      document.querySelector('button').addEventListener('click', addNode)
    <div id="me">
        <div>child</div>
        <div>child2</div>
        <div>child3</div>
        <div>我是新增的孩子</div>
        <div>child4</div>
        <div>child5</div>
        <div>child6</div>
        <div>child7</div>
      </div>
    

    注:如果第二个参数不存在或者异常,则会插入到最后

    3.insertAdjacentElement

    它包括两个参数,其中第二个参数是要加的子节点,核心在于第一个参数,有如下的取值

    beforebegin:把第二个参数加到当前节点的前面
    afterend:把第二个参数加到当前节点的后面
    afterbegin:把第二个参数加到当前节点的第一个子节点位置
    beforeend:把第二个参数加到当前节点的最后一个节点的位置
    一开始我看到这个也是懵逼的,其实记这个可以掌握一定的技巧,以beforebegin,和afterbegin来记,首先,begin肯定是在前面,before肯定也是在前面,就是两个前面,就在节点前加,我就不类推了

    1.removeChild

    parent.removeChild(child),删除parent下的child节点,并且返回这个节点
    dom结构如下

     <div id="deleteDemo">
        <div>第一个子节点</div>
        <div>第二个子节点</div>
        <div>第三个子节点</div>
        <div>第四个子节点</div>
      </div>
      <input type="number" id="txtDeleteIndex" />
      <button id="btnDelete">删除一个孩子</button>
    执行以下的js代码,输入一个数字,并点击按钮
    
     function deleteNode() {
        var index = document.querySelector('#txtDeleteIndex').value
        var deleteDemo = document.querySelector('#deleteDemo')
        var children = deleteDemo.querySelectorAll('div')
        var removeChild = children[index] && deleteDemo.removeChild(children[index])
        console.log(removeChild)
      }
      document.querySelector('#btnDelete').addEventListener('click', deleteNode)
    <div id="deleteDemo">
        <div>第一个子节点</div>
        
        <div>第三个子节点</div>
        <div>第四个子节点</div>
      </div>
    
    2.replaceChild

    parent.replaceChild(newNode,oldNode),将oldNode替换为newNode
    dom如下

     <div id="replaceNodeDemo">
        <div>第一个子节点</div>
        <div>第二个子节点</div>
        <div>第三个子节点</div>
        <div>第四个子节点</div>
      </div>
      <input type="number" id="txtReplaceIndex" />
      <button id="btnReplace">替换一个孩子</button>
    执行以下的js代码,输入一个数字,并点击按钮
    
    function replaceNode() {
        var index = document.querySelector('#txtReplaceIndex').value
        var replaceNodeDemo = document.querySelector('#replaceNodeDemo')
        var children = replaceNodeDemo.querySelectorAll('div')
        var newNode = document.createElement('div')
        newNode.innerHTML = '我是替换之后的节点'
        var replaceChild = children[index] && replaceNodeDemo.replaceChild(newNode, children[index])
        console.log(replaceChild)
      }
      document.querySelector('#btnReplace').addEventListener('click', replaceNode)
    <div id="replaceNodeDemo">
        <div>第一个子节点</div>
        <div>第二个子节点</div>
        <div>我是替换之后的节点</div>
        <div>第四个子节点</div>
      </div>
    

    修改dom,一般是修改dom的属性,dom的html, text, 表单的值等

    1.setAttribute

    A.setAttribute(property, value):设置属性property的值为value
    代码

    <div id="divSetAttribute"></div>
      <label for="txtProperty">属性:</label>
      <input id="txtProperty" />
      <br />
      <label for="txtValue">属性值:</label>
      <input id="txtValue" />
      <button id="btnProperty">设置属性</button>
      <script type="text/javascript">
      var divSetAttribute = document.querySelector('#divSetAttribute')
      var txtProperty = document.querySelector('#txtProperty')
      var txtValue = document.querySelector('#txtValue')
      var btnProperty = document.querySelector('#btnProperty')
    
      function setAttribute() {
        divSetAttribute.setAttribute(txtProperty.value, txtValue.value)
      }
      btnProperty.addEventListener('click', setAttribute)
      </script>
    
    2.innerHTML:获取或者设置dom的dom内容

    dom结构如下

      <div id="parent">
        <div>第一个子节点</div>
        <div>第二个子节点</div>
        <div>第三个子节点</div>
        <div>第四个子节点</div>
      </div>
    获取parent的innerHTML,结果为
    
       <div>第一个子节点</div>
       <div>第二个子节点</div>
       <div>第三个子节点</div>
       <div>第四个子节点</div>
    
    3.innerText:获取或者设置dom的文本内容

    dom结构如下

      <div id="parent">
        <div>第一个子节点</div>
        <div>第二个子节点</div>
        <div>第三个子节点</div>
        <div>第四个子节点</div>
      </div>
    
    获取parent的innerText,结果为
    
    第一个子节点
    第二个子节点
    第三个子节点
    第四个子节点
    注意与innerHTML的区别
    
    4.value:获取或者设置input, select的value
      <select id="s1">
        <option value="2">中国</option>
        <option  selected="true" value=3>日本</option>
        <option value="4">韩国</option>
      </select>
    <script>
    document.querySelector('#s1').querySelectorAll('option')[document.querySelector('#s1').selectedIndex].value
    </script>
    

    查询dom,这一块的api比较丰富,可能会有遗漏

    1.document.getElementById(id):古老的方法,根据id获取元素,不推荐
    2.document.getElementsByTagName(tagName):古老的方法,根据dom的类型获取元素,不推荐
    3.document.getElementsByClassName(className):古老的方法,根据className获取元素,不推荐
    document.getElementsByName(name):古老的方法,根据name获取元素,不推荐
    4.document.getElementsByTagNameNS():没用过

    ----------------------------------------------分割线----------------------------------------------
    接下来,要重点介绍几个目前常用的api

    1.document.querySelector(css选择器):根据css选择器来获取dom,如果有多个,返回第一个

    dom

      <div class="test">1</div>
      <div class="test">2</div>
      <div class="test">3</div>
    执行以下代码
    document.querySelector('.test')
    返回
    <div class="test">1</div>
    
    2.document.querySelectorAll(css选择器):返回所有满足条件的元素

    以上面的例子为例,如果使用querySelectorAll,那么返回值就是三个元素,这两个api比较相似,只是一个返回一个dom,一个返回多个dom,不展开了

    3.获取子节点children

    dom代码

        <div id="div1">
            It's me
            <span>child</span>
            <div>
                child2
                <p>leaf</p>
            </div>
        </div>
    执行以下代码之后
    
    document.querySelector('#div1').children
    得到了两个节点,分别是
    
    <span>child</span>
    和
    
    <div>
         child2
         <p>leaf</p>
    </div>
    

    由此可见,children获取的是dom元素

    4.获取所有子节点childNodes

    还是上面的dom结构,来执行以下代码

    document.querySelector('#div1').childNodes
    返回了五个元素
    
    nodes[0] =It's me
    nodes[1] =<span>child</span>
    nodes[2] =换行符
    nodes[3] =<div>
                child2
                <p>leaf</p>
            </div>
    nodes[4] =换行符
    

    很明显,它不仅返回了dom子元素,还返回了文本子元素

    5.获取父节点parentNode和parentElement

    两者大体差不多,区别和children和childNodes类似,不赘述了

    6.获取兄弟节点previousSibling、previousElementSibling、nextSibling、nextElementSibling

    推荐使用带Element的,大多数情况下,好像都不需要文本节点

    7.获取首尾节点firstChild、firstElementChild、lastChild、lastElementChild

    区别参考上一条

    8.getComputedStyle

    该方法是window下的一个方法,用来计算一个dom元素生成好之后的style,很全,不过因为chrome下的调试很方便,很少用到这个方法

    9.getBoundingClientRect

    这个方法我经常用到,在以前的博文中也有提到,它是用来获取边距的,很有用

    属性操作

    1.setAttribute:设置dom的属性

    A.setAttribute(name,value),上面有提到,不赘述

    2.getAttribute:得到dom的属性

    A.getAttribute('id') 获取dom A的属性id

    3.removeAttribute移除属性

    A.removeAttribute(id) 移除id属性

    事件

    1.添加事件:事件的添加,一般三种方式,直接绑定dom,通过js赋值,通过addEventListener

    代码

     <div id="div1" onclick="alert(1)">
        我是用来测试的
      </div>
      <script type="text/javascript">
      var div1 = document.querySelector('#div1')
      div1.onclick = function() {
        alert(2)
      }
      div1.addEventListener('click', function() {
        alert(3)
      })
      </script>
    

    以上代码分别通过三种方式绑定了事件,点击的结果是,弹出了2和3,并没有弹出1,这是因为,当js中直接给onclick赋值时,把直接绑定在dom上的事件覆盖了,假如下面还有一个onclick的赋值,那么它也会覆盖alert(2),但是add这种方式并不会覆盖,而是会追加,我们再把代码修改一下验证

      <div id="div1" onclick="alert(1)">
        我是用来测试的
      </div>
      <script type="text/javascript">
      var div1 = document.querySelector('#div1')
      div1.onclick = function() {
        alert(2)
      }
      div1.onclick = function() {
        alert('2和3之间')
      }
      div1.addEventListener('click', function() {
        alert(3)
      })
      div1.addEventListener('click', function() {
        alert(4)
      })
      </script>
    

    修改之后,弹出的结果是‘2和3之间’,3,4,由此可见,以上结论正确

    2.移除事件

    对于直接绑定在dom上的事件,可以采用removeAttribute来移除
    对于赋值on这种的,可以重新赋值为null
    对于add的,这种稍微复杂一点,此时首先在add时,不能直接绑定匿名方法 了,要定义一个具名的方法,移除时也要绑定上此方法,代码如下

      <div id="div1">
        我是用来测试的
      </div>
      <script type="text/javascript">
      var div1=document.querySelector('#div1')
      function Test(){
        alert(133)
        div1.removeEventListener('click',Test)
      }
      div1.addEventListener('click',Test)
      </script>
    

    以上点击事件,只会执行一次

    附更全总结:http://javascript.ruanyifeng.com/dom/node.html

    相关文章

      网友评论

          本文标题:js归纳总结——DOM操作

          本文链接:https://www.haomeiwen.com/subject/xxrkrftx.html