应用自定义样式时拆分HTML标签

3
当您使用所见即所得编辑器并选择文本并应用例如粗体时,浏览器将使用<span style="font-weight:bold">标签包装所选内容(假设您已调用document.execCommand("useCSS", false)和/或document.execCommand("styleWithCSS", true))。现在,如果您选择其中的子集并再次应用粗体,它将拆分原始粗体标记为以下内容
<span style="font-weight:bold">Something</span>
Not selected 
<span style="font-weight:bold">Selected</span>

在我正在开发的产品中,我们支持一系列所见即所得(WYSIWYG)功能,包括一些execCommand不直接支持的功能(例如添加一个文本级别(类)以应用字体和字号),我们遇到了嵌套标签的问题。有没有办法告诉浏览器从样式中删除当前范围,并在内容后关闭先前的标记并打开新的标记?
我在execCommand参考中没有立即看到相关内容。
我们使用rangy 1.2.3取得了一些成功,但我不知道是否有一些命令我没找到。
当您添加多个样式时,情况会变得更加复杂,因为在上面的示例中添加粗体和斜体,然后在中间删除粗体将产生三个span,其中两个带有粗体和斜体文本,而中间只有斜体。
目前,我们限制编辑器的使用仅限于Chrome浏览器。

1
是的,强制用户使用标记语言可能是更稳定的解决方案,但使用该应用程序的人不熟悉它,因此我们必须为他们提供所见即所得编辑器来创建他们的材料。 - Thomas Jones
1
我计划在Rangy中编写一个模块来完成这个任务,去年已经有了一定的进展,但实际上可能需要几个月才能准备好。 - Tim Down
@skyline3000 如果我们只想取消加粗,那么这将起作用。然而,更复杂的例子是取一部分加粗、斜体文本并取消加粗其中间部分。这将产生一个加粗斜体部分,一个仅斜体部分以及一个加粗斜体部分,按顺序排列。遗憾的是,删除格式会删除所有内容。 - Thomas Jones
你所要求的与这个示例之间有什么区别? - Assaf Shemesh
可能是Rangy(JS / jQuery)split node的重复问题。 - bfavaretto
显示剩余3条评论
1个回答

0

如果您的问题是混乱的输出,但呈现正确,那么您应该从编辑器不可知的角度来解决它,因为这会影响所有HTML,尤其是rangy和其他所见即所得编辑器/用户格式化代码。

减少混乱的最快方法是限制用户可用的标记选项:

  • 限制(如果不禁用)具有大量代码的字体或其他样式/元素
  • 考虑专门针对此困境设计的解决方案,例如BBCode或Markdown语法

如果您无法更换编辑器,因为客户需要来自MS Word的红色/蓝色文本,则PHP Tidy应该足够了,因为它甚至可以处理MS Office的HTML导出!以下函数配置了merge-spans应该就可以解决问题了。

function tidyHTML($input){
    $tidy = new tidy();
    $config = array(
        'ascii-chars' => true,
        'bare' => true,
        'clean' => true,
        'drop-empty-paras' => true,
        'drop-proprietary-attributes' => true,
        'hide-endtags' => true,
        'indent' => true,
        'logical-emphasis' => true,
        'merge-spans' => true,
        'show-body-only' => true,
        'word-2000' => true,
        'wrap' => false
    );
    return $tidy->repairString($input, $config);
}
echo tidyHTML($wysiwyg_output);

可以在这里找到选项的文档。


这并不是一个特别有帮助的答案。它针对的是HTML/Javascript,而不是PHP。此外,这不仅仅是关于显示正确的混乱HTML,更多的是避免标签嵌套导致无效显示的情况,例如<span class="level1">ABC <span class="level2"> DEF</span> GHI</span>应该是<span class="level1">ABC</span> <span class="level2">DEF</span> <span class="level1">GHI</span>。这个特定的例子可以通过rangy的undoToSelection level1在应用level2之前解决,但还存在更具体的情况。 - Thomas Jones
此外,上面的评论中指出,BBCode和Markdown(或任何标记语法)都不适用。 - Thomas Jones
很抱歉,我有点难以理解您的问题,并且在上面没有看到BBCode / Markdown的提及...无论如何,这里侧边栏有一个问题(https://dev59.com/CGXWa4cB1Zd3GeqPKS1r),它似乎与您的问题相同,提供了链接的解决方案:http://help.dottoro.com/external/examples/ljcvtcaw/execCommand_3.htm。 - Alastair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接