美文网首页
jQuery源码解析之replaceWith()/unwrap(

jQuery源码解析之replaceWith()/unwrap(

作者: 小进进不将就 | 来源:发表于2019-04-09 09:58 被阅读0次

    前言:当我调用了$().append()后,jQuery内部发生了什么? 一样,replaceWith() 会经过 domManip()buildFragment() 的洗礼,最后调用原生JS的方法来实现。

    所以,本文只讲述 jQuery 中最后对 replaceWith() 处理的相关代码。

    想了解domManip()buildFragment()的,请看 当我调用了$().append()后,jQuery内部发生了什么?

    一、示例代码

    <body>
    <script src="jQuery.js"></script>
    <div id="divTwo">
      <p id="pTwo">这是divTwo</p>
    </div>
    <div id="divOne">
      <p>这是divOne</p>
    </div>
    
    <script>
      let divOne = document.querySelector("#divOne")
      let divTwo = document.querySelector("#divTwo")
      let pTwo = document.querySelector("#pTwo")
      
      // ===========replaceWith==============
      //注意:removedNode指向已经被移除的divTwo
      let removedNode=$("#divTwo").replaceWith("<span>永远</span>")
      console.log(removedNode,'removedNode21')
      //======相当于=====
      let spanA=document.createElement("span")
      spanA.innerText="永远"
      divTwo.parentNode.replaceChild(spanA,divTwo)
      
      // ==============unwrap================
      $("#pTwo").unwrap()
      //======相当于=====
      let pTwoFather=pTwo.parentNode
      if(pTwoFather.nodeName.toLowerCase()!=='body'){
        pTwoFather.parentNode.replaceChild(pTwo,pTwoFather)
      }
      
    </script>
    </body>
    

    二、$().replaceWith()
    作用:
    把被选元素替换为新的内容

    注意:$().replaceWith() 指向已经被移除的元素。

    源码:

        // 源码6324行
        // 把被选元素替换为新的内容
        replaceWith: function() {
          var ignored = [];
          // Make the changes, replacing each non-ignored context element with the new content
          return domManip( this, arguments, function( elem ) {
            //获取选择器的父节点
            var parent = this.parentNode;
            //$.inArray() 函数用于在数组中查找指定值,并返回它的索引值(如果没有找到,则返回-1)
            //inArray() 可以看成是indexOf()
            //如果ignored数组中没有目标元素的话
            if ( jQuery.inArray( this, ignored ) < 0 ) {
              //清除目标元素的事件
              jQuery.cleanData( getAll( this ) );
              if ( parent ) {
                //原生JS方法replaceChild(newnode,oldnode) 将某子节点替换成另一个
                parent.replaceChild( elem, this );
              }
            }
            // Force callback invocation
          }, ignored );
        }
    

    解析:
    ① 先找到目标元素的父节点 this.parentNode
    ② 使用 $.cleanData() 清除目标元素上的 事件和缓存jQuery.cleanData( getAll( this ) )
    ③ 当父节点存在时,父节点调动replaceChild(),将待替换的元素 替换到 目标元素上

    简单实现:

      //注意:removedNode指向已经被移除的divTwo
      let removedNode=$("#divTwo").replaceWith("<span>永远</span>")
      console.log(removedNode,'removedNode21')
      //======相当于=====
      let spanA=document.createElement("span")
      spanA.innerText="永远"
      divTwo.parentNode.replaceChild(spanA,divTwo)
    

    三、$().inArray()
    作用:
    查看元素在数组中的位置

    源码:

        //源码453行,查看元素在数组中的位置
        inArray: function( elem, arr, i ) {
          //indexOf:array.indexOf
          return arr == null ? -1 : indexOf.call( arr, elem, i );
        },
    

    四:$().unwrap()
    作用:
    移除被选元素的父元素(父节点是body则无效

    源码:

        //源码9798行
        //移除被选元素的父元素(父节点是body则无效)
        unwrap: function( selector ) {
          //选中目标元素的父节点(除了body)
          this.parent( selector ).not( "body" ).each( function() {
            //this表示父节点
            //即父节点被它的子节点替换
            jQuery( this ).replaceWith( this.childNodes );
          } );
          return this;
        }
    

    解析:
    是在目标元素的爷爷节点上调用 replaceWith() 方法,将父节点替换成目标节点。

    注意:目标元素的父节点是body的话,$().unwrap()方法无效。

    简单实现:

      $("#pTwo").unwrap()
      //======相当于=====
      let pTwoFather=pTwo.parentNode
      if(pTwoFather.nodeName.toLowerCase()!=='body'){
        pTwoFather.parentNode.replaceChild(pTwo,pTwoFather)
      }
    

    五、$().parent()
    作用:
    返回被选元素的直接父元素

    源码:

        //源码3245行
        //11表示文档碎片
        //返回被选元素的直接父元素
        parent: function( elem ) {
          var parent = elem.parentNode;
          return parent && parent.nodeType !== 11 ? parent : null;
        },
    

    这个一看就懂,就不解释了


    (完)

    相关文章

      网友评论

          本文标题:jQuery源码解析之replaceWith()/unwrap(

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