javascript - 如何避免部分选择破坏 block 级 HTML 元素?

标签 javascript html dom ckeditor

简而言之,问题是:给定一个所见即所得编辑器(CKEditor),您想要制作一个执行文本转换的插件 - 选择一段文本并操作其中的文本(例如大写)。示例:

this is paragraph one

this is paragraph two

如果粗体代表您的选择,结果将是

this is paragraph ONE

THIS is paragraph two

这里的问题是,即使选择不包含完整标签,选择也将是完整的 HTML 片段。所选 HTML 为:

<p>one</p> <p>this</p>

注意第一个和最后一个 <p>标签。当您在选择的 html 中进行 dom 遍历时,应用文本转换并替换 html,它将使用这些部分标签,因此您的结果将变为:

this is paragraph

ONE

THIS

is paragraph two

我检查了是否可以将第一个和最后一个部分标记与其 dom 父级“合并”,但是选择对象是隔离的,它没有来自原始上下文的兄弟级或父级。

还尝试找到一个选项来检索没有这些自动固定标签的选择,但没有运气。

在 CKEditor 文档中,他们提到了 walker object - 但是,它会自动从选择扩展到完整的封闭标记,这意味着选择仅用作最小边界。

此外,由于选择对象是隔离的,因此不可能仅更改其中的 dom 节点文本值 - 需要替换原始 dom 片段(至少在 CKEditor 的情况下)。

我尝试尽可能不坚持使用 CKEditor api,但目前我也没有看到任何替代方案。这真的是一个难题还是我遗漏了一些东西?

最佳答案

一种解决方案是使用浏览器引擎用标签来标记所选区域(据我所知,这是 native 操作)。这与您将选择设置为粗体或斜体相同 - 但这里它将是一个临时包装。然后你遍历 DOM 并替换临时标签中的内容 - 最后删除标签(保留内容)。

这确保您可以将转换应用到精确的选择上,并且通过删除标签,您不会破坏原始 DOM。步骤简而言之:

  1. 在选择上应用标记(使用浏览器或所见即所得 API)
  2. 查找所有临时标签:
    • 递归遍历标签的子级
      • 如果标签是文本节点,则应用转换
      • 否则递归遍历
    • 收集标签的左同级文本节点 + 标签的 html + 右同级文本节点
    • 将标记的父级 html 替换为之前的编译内容(=删除临时标记)

不太优雅但有效。这是受到 @Andrew_Mast 关于包裹在跨度中的想法的启发。

关于javascript - 如何避免部分选择破坏 block 级 HTML 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33684943/

相关文章:

javascript - 这段js代码有什么错误

javascript - 如何在 React Native 中进行条件导航?

html - 字体图标后垂直对齐文本

html - Bootstrap 3 中的列填充问题

javascript - 使用jQuery Redux隐藏选择列表中的选项

javascript - DOMNodeInserted DOMNodeRemoved 与 MutationObserver 的等价物?

javascript - jquery 我使用 .css() 将最小高度缩放到窗口高度的错误在哪里

javascript - 在 jsPDF 从 PNG 到 JPEG 的转换中显示透明背景

Javascript - 设置浏览器 Cookie

JavaScript:document.documentElement.innerHTML 未显示所有元素