You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何移除选中文本的<b>标签,避免误删父级<div>节点

Toggle Tags for Selected Text (Add/Remove)

Let's fix your bold toggle functionality properly—your current issue with deleting the parent <div> happens because range.commonAncestorContainer targets the lowest shared parent of your selected content, not the <b> tag itself. Here's a robust solution to handle both adding and removing <b> tags correctly:

Step-by-Step Solution

First, replace your existing click handler with a dedicated toggleBold() function that checks if the selected text is already wrapped in <b> before deciding to add or remove the tag:

Full Working Code

function toggleBold() {
  const selection = window.getSelection();
  if (!selection.rangeCount) return; // Exit if no text is selected

  const range = selection.getRangeAt(0);
  let targetBold = null;

  // Check if the entire selection is wrapped in a single <b> tag
  const anchorBold = selection.anchorNode?.parentElement?.closest('B');
  const focusBold = selection.focusNode?.parentElement?.closest('B');

  // Ensure both ends of the selection are in the same <b> tag
  if (anchorBold && focusBold && anchorBold === focusBold) {
    targetBold = anchorBold;
  }

  if (targetBold) {
    // Remove the <b> tag (unwrap the text)
    const parent = targetBold.parentNode;
    // Move all child nodes out of the <b> tag into its parent
    while (targetBold.firstChild) {
      parent.insertBefore(targetBold.firstChild, targetBold);
    }
    // Delete the empty <b> tag
    parent.removeChild(targetBold);
    // Restore the selection to the original text
    selection.removeAllRanges();
    selection.addRange(range);
  } else {
    // Add the <b> tag to the selected text
    const boldNode = document.createElement('b');
    try {
      // Use surroundContents if selection is a single contiguous node
      range.surroundContents(boldNode);
    } catch (err) {
      // Handle cases where selection spans multiple nodes (surroundContents fails here)
      const selectedContent = range.extractContents();
      boldNode.appendChild(selectedContent);
      range.insertNode(boldNode);
      // Update selection to the newly bolded text
      selection.removeAllRanges();
      const newRange = document.createRange();
      newRange.selectNodeContents(boldNode);
      selection.addRange(newRange);
    }
  }
}

Update your HTML to use this new function:

<div contenteditable="true" id="input" class="inputblock" onclick="toggleBold()" onkeypress="changeNodeType(event)" data-text="Please paste your text here."></div>

Key Fixes & Explanations

  1. Why Your Original Remove Code Failed
    Your use of range.commonAncestorContainer returns the lowest parent element that contains the entire selection. If you selected text directly inside the <div contenteditable>, this container is the <div> itself—so calling remove() deleted the whole parent instead of the <b> tag.

  2. Targeting the Correct Tag
    We use Element.closest('B') to traverse up from the selected text's nodes and find the nearest wrapping <b> tag. We verify both ends of the selection are in the same <b> to ensure we only unwrap the intended bolded content.

  3. Safe Unwrapping
    Instead of deleting nodes blindly, we move all text/content inside the <b> tag up to its parent, then remove the now-empty <b> element. This preserves the text while removing the formatting.

  4. Robust Bold Addition
    We added a try/catch block to handle cases where the selection spans multiple nodes (e.g., text across line breaks or other inline elements). The fallback uses extractContents() to safely wrap non-contiguous selections in <b>.

Optional Enhancement

If you need to handle selections that span multiple <b> tags, you can extend the code to iterate over all <b> elements in the selection range and unwrap each one individually.

内容的提问来源于stack exchange,提问作者Junge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:16:46