Javascript - 如何删除 nodeName 或 HTML 标记但不理会内部标记?

Posted

技术标签:

【中文标题】Javascript - 如何删除 nodeName 或 HTML 标记但不理会内部标记?【英文标题】:Javascript - How to remove nodeName or the HTML tag but leave the inside markup alone? 【发布时间】:2017-06-14 11:49:45 【问题描述】:

我将用户选择的范围存储在一个变量中。

var sel, range, off, tags; 
sel = window.getSelection();
 if (sel.rangeCount) 
            range = sel.getRangeAt(0);
            var off = sel.anchorOffset;

         
         else if (document.selection && document.selection.createRange) 
            range = document.selection.createRange();
            var off = document.selection.anchorOffset;

        
return range;

html

    <div ng-mouseup="mouseUpEvent(e)" ng-keyup="keyUpEvent()" contenteditable data-element="textBlock" id="markdown-body">

        Chicken ipsum dolor sit amet, consectetur adipiscing elivolutpat volutpat. Nunc imperdiet urna et orci mattis, 
pellentesque posuere enim pellentesque. Aenean id orci et nunc venenatis vestibulum et et ligula. Morbi mollis ornare purus
 non blandit.<b> Phasellus egestas</b>, ipsum <i>sit amet finibus </i>pellentesque, <span style="color: red;">tellus urna
 lobortis tellus, id tincidunt </span>Piza house byys nget lectus. Proin pulvinar enim non mi vestibulum interdum. 

            Sed nisl enim, sagittis non vestibulum eget, congue pellentesque ipsum. Nullam nec interdum elit

    </div>

我已经找到了我的 anchorNode 和我的 focusNode。 所以我选择了节点名称“B”的节点。代表粗体。

如果我使用 element.nodeName,我的输出将是“B”。

如果我输出我的元素,我会得到&lt;b&gt; Phasellus egestas&lt;/b&gt; 我也有一个选定的范围,我选择了“asellus eges”

我想删除&lt;b&gt; 标签。并将标签添加到选择范围。 如果我取元素的 innerHTML 并替换它,那么我会被选择范围弄乱。

我看到人们建议寻找父节点,而不是选择 childNode 并删除并执行以下操作:

element[index].parentNode.removeChild(element[index]);

但如果我的 Parent 有两个具有相同 nodeName 的子节点,这将导致问题。

我已经有了选择特定 Node 的元素,如何保留 innerConnet 和 html 标记但删除 b 标记?

【问题讨论】:

你想用Phasellus egestas替换例如&lt;b&gt; Phasellus egestas&lt;/b&gt; 是的替换也是一种选择,它会给出相同的结果。如何替换和更新 DOM? 谢谢 ibrahim Mahrir,重新提出问题让我找到了答案。我将 innerHTML 克隆到一个属性,而不是使用 replaceWith(cloneInnerHTML) 并且能够替换标签名称的宽度 用 innerHTML 替换节点会弄乱我的 getSelection 。有没有办法只删除节点? 【参考方案1】:

要获取 HTML 标记之间的代码,请使用:

var inside = element.innerHTML;

如果你想让它更新源代码,试试这个:

element.outerHTML = element.innerHTML;

【讨论】:

这会给我内部 html 标签“Phasellus egestas”,但不会删除 标签 你的意思是,去掉里面的文字,同时从页面源代码中去掉标签?我已将其添加到我的答案中。【参考方案2】:

用它的第一个子元素(在本例中为文本节点)替换元素

if (element.tagName == 'B') 
  element.parentNode.replaceChild(element.firstChild, element);

在多个节点的情况下,在删除之前为每个子节点使用insertBefore

var child = element.firstChild;
while (child) 
  element.parentElement.insertBefore(child, element);
  child = child.nextSibling;


element.parentElement.removeChild(element);

【讨论】:

【参考方案3】:

在文本框中输入标签名称,然后单击代码段中的 UNWRAP 按钮。所有细节都在代码段中注释。

片段

function unWrap(wrap) 

  if (!wrap) 
    console.log('Enter a valid selector without quotes');
  

  // Reference the node to unwrap
  var removeThis = document.querySelector(wrap);

  if (removeThis == "undefined" || removeThis == false) 
    console.log('Selector doesn\'t exist in DOM.');
  

  // Reference the wrapper's parent
  var parent = removeThis.parentNode;

  // Move all of wrapper's descendants...
  while (removeThis.firstChild) 

    /* ...by taking the wrapper's first child...
    || ...and placing it in front of the wrapper.
    || ...Eventually, all of wrapper's children...
    || ...are it's siblings now.
    */
    parent.insertBefore(removeThis.firstChild, removeThis);

  

  // Once the wrapper is empty, remove it
  parent.removeChild(removeThis);

body 
  color: white;

header,
footer 
  background: cyan;
  color: black;

table 
  border: 3px solid gold;
  width: 300px;

td 
  border: 1px solid tomato;

section 
  border: 8px dashed blue;

main 
  background: #444;

b 
  background: yellow;
  color: #444;

input 
  float: right;
  width: 12ch;

.as-console 
  color: blue;
<main>
  MAIN
  <section>
    SECTION
    <header>HEADER</header>
    <p>TEXT TEXT <b>TEXT</b> TEXT TEXT</p>
    <p>TEXT TEXT <b>TEXT</b> TEXT TEXT</p>
    <p>TEXT TEXT <b>TEXT</b> TEXT TEXT</p>
    <p>TEXT TEXT <b>TEXT</b> TEXT TEXT</p>
    <p>TEXT TEXT <b>TEXT</b> TEXT TEXT</p>
    <table>

      <form id='f1' name='f1'>
        <input type='button' value='UNWRAP' onclick='unWrap(document.forms[0].txt.value)'>
        <input name='txt'>
      </form>

      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
    </table>
    <footer>FOOTER</footer>
  </section>
</main>

【讨论】:

zer00ne,当我尝试你的代码时出现错误,我也更新了我的问题。我忘了还提到我有一个 range.selection 之后在里面,我计划我的 标签 @ChrisTarasovs 我在尝试删除页脚时遇到错误,但只要包装器有一个孩子,它就应该可以工作。我必须为空元素的函数添加一个条件。尝试输入不带引号的table,然后单击按钮。 zer00ne,我已经用范围选择更新了这个问题。如果我按照你说的做,我的范围就搞砸了,我可以用 标签更新我的范围。 @ChrisTarasovs 你能告诉我们你的 HTML 吗?如果没有一些视觉参考,很难掌握您所描述的内容。【参考方案4】:

更正了@Casper Beyer 的算法,它对孩子有一些弱点。在父节点中插入子节点后,.nextSibling 在插入后传递父节点的下一个兄弟节点,而不是子节点中的下一个节点。因此,在将子项插入父项之前,我存储了一个临时的 nextSibling,然后将子项添加到父项。代码如下:

    removeSurroundingTagOnNode(node: Node, tagName: string): void 
        if (node.nodeName == 'DIV') 
            return; // root reached
        
        if (node.nodeName === tagName) 
            // remove the surrounding tag
            let child: Node = node.firstChild;
            while (child) 
                let nextChild: Node = child.nextSibling;
                node.parentNode.insertBefore(child, node);
                child = nextChild;
            
            node.parentNode.removeChild(node);
         else 
            // havn't found the tagName yet, look in the parent node
            this.removeSurroundingTagOnNode(node.parentNode, tagName);
        
    

【讨论】:

以上是关于Javascript - 如何删除 nodeName 或 HTML 标记但不理会内部标记?的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个具有不同参数的连续调用两次的javascript中为函数添加回调?

JavaScript HTML DOM 元素(节点)

JavaScript之DOM-2 读取和修改节点信息(节点信息元素的内容属性)

javascript:如何检查元素是不是可点击

运维实操——kubernetes调度nodeNamenodeSelector亲和性污点容忍删除节点

k8s --> 18 k8s常用命令