2

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

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”。

如果我输出我的元素,<b> Phasellus egestas</b> 我也会得到一个选定的范围,并且我选择了“asellus eges”

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

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

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

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

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

4

4 回答 4

1

在文本框中输入 tagName,然后单击UNWRAPSnippet 中的按钮。所有细节都在片段中注释。

片段

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>

于 2017-01-29T02:55:14.103 回答
0

更正了@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);
        }
    }
于 2021-11-06T17:35:33.480 回答
0

将元素替换为其第一个子元素(本例中为文本节点)

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);
于 2017-01-29T02:39:41.413 回答
0

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

var inside = element.innerHTML;

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

element.outerHTML = element.innerHTML;
于 2017-01-29T02:20:51.790 回答