使用 removeChild 删除 HTML 段

Remove HTML paragraph using removeChild

我写了如下代码:

     <input type="button" value="remove" onclick="remove()"/>

     <p id="p2">
        before hr 
        <hr/>
        after hr 
     </p>

  <script>
     function remove() {
        var p = document.getElementById('p2');
        p.parentNode.removeChild(p);
     }
  </script>

当我按下按钮时,只有 "before hr" 消失了 - hr 和 "after hr" 文本没有。

如果我将

更改为

:

<div id="p2">
    before hr 
    <hr/>
    after hr 
 </div>

一切正常(即我认为它应该正常工作;))

有人能解释一下原因吗?

你的代码不正确,不可能把<hr>放在<p>

里面
<p id="p2">
        before hr 
        <hr/>
        after hr 
     </p>

在好的浏览器中,浏览器会更正您的代码

 <p id="p2">
            before hr
    </p>
   <hr/>
    <p> 

       after hr 
    </p>

一种可能使用 span 或 div

 <span id="p2">
            before hr 
            <hr/>
            after hr 
         </span>  

您的HTML无效。使用 a validator.

<p> 元素可能不包含 <hr> 元素,但 <p> 元素的结束标记是可选的。

这意味着 <p> 元素被 <hr> 隐式结束 并且 </p> 标签被丢弃,因为它没有匹配一个开放的 <p>.

结果 DOM 如下所示:

 <p id="p2">before hr</p>
 <hr/>
 after hr 

由于 <hr> 元素及其后面的文本节点不在段落内,因此在删除段落时它们不会被删除。

您的精简测试用例已经精简到无法为您的内容推断出正确的语义,但也许您需要这样的东西:

<div id="p2">
    <p>before hr</p>
    <hr>
    <p>after hr</p>
</div>

来自MDN web docs on <p>

and notably will automatically close if another block-level element is parsed before the closing </p> tag.

并且 W3C list of block elements 指出 <hr> 是块元素。

所以你的代码是这样计算的:

<p id="p2">
  before hr
</p>
<hr />
<p id="p2">
  after hr
</p>

这就是为什么删除单个子项不起作用的原因。由于 ID 不是 re-created,唯一的解决方案是更改元素类型 - <div> 可以正常工作:

function remove() {
  var p2 = document.getElementById("p2");
  p2.parentNode.removeChild(p2);
}
<input type="button" value="remove" onclick="remove()" />

<div id="p2">
  before hr
  <hr/> after hr
</div>

你的问题是意料之中的...因为P标签只能包含Phrasing内容。语义不正确,浏览器会自动在 HR 标签后添加一个新的 P 元素...

正如你所说的 div 这将起作用..那将是正确的答案..

<input type="button" value="remove" onclick="remove()"/>

     <div id="p2">
        before hr 
       <hr/>

        after hr 
     </div>

  <script>
     function remove() {
        var p = document.getElementById('p2');
        p.parentNode.removeChild(p);
     }
  </script>