js 如何把 remove 的 dom 重新插入原位置?

mikechen
  • 554
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <style></style>
    <div id="app">
      <div class="parent1">
       parent1
       <div class="parent2">
         parent2
         <div class="parent3">parent3</div>
       </div>
      </div>
    </div>
  </body>
</html>

html结构如上

const parent2 = document.querySelector('.parent2');
parent2.remove();
setTimeout(()=>{
  //一秒后 我想把 parent2 插入回原处, 请问如何实现?有点类似于 vue的  v-if
},1000)
回复
阅读 377
4 个回答
✓ 已被采纳

你在remove之前先cloneNode一下,remove以后把clone的添加进去就行了。

  const parent2 = document.querySelector('.parent2');
  const parent = parent2.parentElement;
  const newParent2 = parent2.cloneNode(true);
  parent2.remove();
  setTimeout(() => {
      parent.appendChild(newParent2)
  },1000)

以下有一个实现的demo给你:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>v-show与v-if的实现</title>
</head>

<body>
    <div v-show="model.isShow" class="show-div">这里是否显示元素</div>
    <button type="button" onclick="model.isShow = true">显示</button>
    <button type="button" onclick="model.isShow = false">隐藏</button>
    <!-- <div v-if="model.isRemove" class="if-div">这里是否移除元素</div> -->
    <input type="text" value="数据" v-if="model.isRemove" class="if-div">
    <button type="button" onclick="model.isRemove = true">添加</button>
    <button type="button" onclick="model.isRemove = false">移除</button>
    <script>
        var element = document.querySelector('.if-div');
        var next = element.nextElementSibling;
        var node = element.cloneNode(true);
        var model = {
            isShow:true,
            isRemove:false
        }
        function updateShow(el,bool) {
            return el.style.display = bool ? 'block' : 'none';
        }
        function updateRemove(el,bool){
            return bool && !el ? document.body.insertBefore(node,next) : !bool && el ? el.remove() : null;
        }
        var attr = document.querySelector('.show-div').getAttribute('v-show');
        updateShow(document.querySelector('.show-div'),attr)
        Object.defineProperty(model,'isShow',{
            set:function(val){
                updateShow(document.querySelector('.show-div'),val);
            }
        });
        var attr = document.querySelector('.if-div').getAttribute('v-if');
        updateShow(document.querySelector('.if-div'),attr)
        Object.defineProperty(model,'isRemove',{
            set:function(val){
                updateShow(document.querySelector('.if-div'),val);
            }
        });
    </script>
</body>

</html>
已参与了SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入。

这种最好是用display来实现,不然你要记录dom的位置才行较为复杂,这里给出一种方式(有缺陷的,仅限移除一个,多处移除会有问题)

const parent2 = document.querySelector('.parent2');
    const father = parent2.parentElement;
    // 找出dom所处节点位置
    const index = [...father.childNodes].findIndex(node => node === parent2);
    parent2.remove();
    setTimeout(()=>{
      // 一秒后 我想把 parent2 插入回原处, 请问如何实现?有点类似于 vue的  v-if
// 移除的位置是最后一个时直接append
     if(index==father.childNodes.length) return father.appendChild(parent2)
  
      // 因为移除后,后面的节点占据了移除的节点位置,故相等即可
         father.insertBefore(parent2, father.childNodes[index]);
      
    },1000)
已参与了 SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入

不好整。因为你缺少排序规则。vue中可以是因为本身他的模版就是排序。

你其实可以参照下面这样理解,他是把dom结构重新生成了。(当然,他没有这么暴力)所以他生成的是有序的。

image.png

你这个如果不考虑这些,你可以拿一下前后的dom,然后直接给他 after 或者 before 进去。如果插入的时候前后都不在了,那么就只能 append 了。当然,这里算法你可以自由修改。比如说最开始存储一下排序,然后插入的时候去比对最合适的位置。

已参与了 SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入。
你知道吗?

宣传栏