前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jQuery源码解析之replaceWith()/unwrap()

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

作者头像
进击的小进进
发布2022-03-28 14:51:15
6120
发布2022-03-28 14:51:15
举报

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

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

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

一、示例代码

代码语言:javascript
复制
<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() 指向已经被移除的元素。

源码:

代码语言:javascript
复制
    // 源码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(),将待替换的元素 替换到 目标元素上

简单实现:

代码语言:javascript
复制
  //注意: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() 作用: 查看元素在数组中的位置

源码:

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

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

源码:

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

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

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

简单实现:

代码语言:javascript
复制
  $("#pTwo").unwrap()
  //======相当于=====
  let pTwoFather=pTwo.parentNode
  if(pTwoFather.nodeName.toLowerCase()!=='body'){
    pTwoFather.parentNode.replaceChild(pTwo,pTwoFather)
  }

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

源码:

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 webchen 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档