【问题标题】:Consolidate stacked DOM formatting elements - contenteditable DIV合并堆叠的 DOM 格式化元素 - contenteditable DIV
【发布时间】:2013-04-20 01:13:50
【问题描述】:

我有一个内容可编辑的 DIV,它链接/同步回文本区域。

contenteditable DIV 是一个免费的沙箱,它会在调用它们时创建格式化元素等。然而,这确实经常导致混乱的堆叠元素。

我希望能够在文本区域表单发送到服务器之前清理代码。

可能会得到如下结果:

<div>
  <b>
    <i>
        Hel
    </i>
    <i>
        l
    </i>
  </b>
  <i>
    <b>
       o World!
    </b>
  </i>
</div>

理想情况下将转换为:

<div>
  <b>
    <i>
       Hello World!
    </i>
   </b>
</div>

如果我(递归地)遍历 div 的子节点,我大概可以跟踪格式(tagName.toUpperCase() == {'B','I' ....} ) // 或执行document.queryCommandState,在此期间我可以在selectNode(thenode) 上执行document.execCommand('removeFormat',false,null)

但是,我对如何跨格式的相邻节点进行跟踪有点迷茫。

作为参考,这是我最近为 DOM 解析所做的以从 IMG 标签中删除格式:http://jsfiddle.net/tjzGg/

注意:这是一个类似的问题> jquery - consolidate stacked DOM elements 但它是关于将 useCSS 样式线合并为一种主要样式。这是一个不同的问题的原因是,我希望将文本与一种通用样式合并,但由于文本的格式设置,人为地将其拆分为多个元素。如果您使用一个内容可编辑的 div 并一次单独加粗一个字符,那么您最终将得到每个元素一个字符。

【问题讨论】:

    标签: javascript html dom formatting contenteditable


    【解决方案1】:

    我有几个解决方案,各有利弊。

    首先,我在 gmail 中玩耍时发现,如果格式样式处于相同的当前选定模式,则可内容编辑的 DIV 将“吸收”相邻节点。这个“免费赠品”允许我仅仅尝试重新组织格式化发生的顺序以清理大部分 html 汤。这不是一个完整的解决方案。理想的解决方案是具有最大的格式化模式,因为具有子集文本的父级将具有递减的数量级是进一步的嵌套模式。

    在我上面的人工示例中,结果本质上会转换为:

    <div>
       <b>
         <i> 
            Hel
            l
         </i>
        </b> 
    ....
    

    警告:仅使用文本进行了测试,没有图像。由于解决方案 1 中的节点解析和解决方案 2 中 textContent.length 的使用,我想在处理时会出现一两个错误。


    解决方案 1

    第一个在 Chrome 中有效,但在 Firefox 中调用 execCommand 将导致节点选择失去焦点并被取消选择。这是一个我似乎无法理解或编程的致命缺陷。除非我能弄清楚如何重新突出显示/选择新格式化的节点,否则这已被放弃。

    http://jsfiddle.net/tjzGg/3/

    我希望 喜欢 能够让这个与 Firefox 一起工作。关于我在哪里出错的任何建议。


    解决方案 2

    第二种方法是尝试想出一个解决 Firefox 失去焦点的解决方案。我可以处理的唯一方法是忽略选择整个节点,而是一次选择一个字符,查看其格式,核对并按特定顺序重新应用。这在两种浏览器中都有效但是然后 DOM 被拆分为每个字符的childNode。我不确定组合它们的最佳方式(textContent?)。

    http://jsfiddle.net/LDVpD/3/


    [背景:查看了 jsbeautifier、htmlsoup、html tidy、nokogiri、hpricot、jtidy ..... 我真的很惊讶没有解决方案。 GMail 也会生成“丑陋”的格式!]

    我知道有更好的解决方案 - 我很想听听一些建议。

    更新

    经过测试,很明显解决方案 2 慢得离谱(通过跟踪头部来优化它并不复杂,因为它是一种渐进的“洪水”,但仍然很慢),甚至可以轻松修改它以处理整个 textNodes 但解决方案 1 似乎是一个更好的方法,如果它只在 Firefox 中工作。


    解决方案 1+2=3:

    我发现,如果我将格式应用为一种切换方式,它会起作用,但是正如预测的那样,文本节点会根据相邻匹配格式的自然合并而增长/缩小。因此,我在睡觉时突然意识到,如果我创建了一个文本节点列表,并且从后到前,如果在应用格式化时内部 DOM(对于 Firefox !!!)正在增长/缩小,我就不在乎了。结合解决方案 2 的 textNode 列表(然后弹出尾节点),效果很好。事实上,迭代而不是递归文本节点(原始解决方案 1 方法)甚至更快。

    http://jsfiddle.net/tjzGg/4/

    注意:selectNodeContents 与 selectNode

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 2012-12-24
    • 2020-09-15
    • 2011-05-02
    相关资源
    最近更新 更多