2013-04-26 101 views
1

我有一个contenteditable DIV链接/同步回textarea。巩固堆叠DOM格式化元素 - contenteditable DIV

contenteditable DIV是一个免费的所有沙箱,它将在被调用时创建格式化元素等。然而,这通常会导致凌乱的堆叠元素。

我希望能够在之前清理代码textarea表单被发送到服务器。

有可能喜欢的东西就结了以下内容:

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

这将理想转化为:通过DIV我的的childNodes

<div> 
    <b> 
    <i> 
     Hello World! 
    </i> 
    </b> 
</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,并且每个单独的一个字符都是一个字符,那么每个元素最后只会有一个字符。

回答

1

我有几个解决方案,有其优点和缺点。

首先,我发现当在gmail中玩耍时,如果格式样式处于相同的当前选定模式,可用的DIV将“吸收”相邻节点。这个'免费'允许我只是试图重新组织格式化的顺序来清理大部分的html汤。这不是一个完整的解决方案。理想的解决方案是将最大的格式化模式作为父级,而子集文本将具有越来越大的嵌套模式。

在我的上述人工例的结果将固有地被转换成:

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

警告:将其用纯文本,无图像测试。我会想象有一个或溶液中的溶液1和使用textContent.length的适当处理,以节点解析2.


解决方案1 ​​当两个错误:

率先在作品Chrome,但在Firefox中调用execCommand将导致节点选择失去焦点并成为未选中状态。这是一个致命的缺陷,我似乎无法理解或编程。除非我能弄清楚如何重新选择/选择新格式化的节点,否则这一点已经被抛弃。

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

我会才能够获得这一个与Firefox的工作。任何关于我在哪里出错的建议。


解决方案2

第二种方法是设法想出的Firefox失去焦点的解决方案。我能处理的唯一方法是忽略选择整个节点,而是一次选择一个字符,查看它的格式,核心并以特定顺序重新应用。这适用于浏览器,但是 DOM然后被分割为每个字符的childNode。我不确定将它们结合的最佳方式(textContent?)。

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


[背景:看着jsbeautifier,htmlsoup,HTML整齐,引入nokogiri,角度来说,Hpricot,jtidy .....我真的很惊讶,也没有这方面的解决方案了。 GMail也会产生'丑陋'格式!]

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

更新

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


溶液1 + 2 = 3:

我发现,如果我应用的格式,以切换所预测的文本节点将增长它将然而工作的装置/收缩基于天然合并相邻的匹配格式。所以,睡觉时,我明白了,如果我创建了一个文本节点列表,并且从后向前走,我可以不在意内部DOM(对于Firefox !!!)在格式化时正在增长/缩小。结合解决方案2的textNode列表(然后弹出尾节点),这很好。事实上,迭代而不是递归文本节点(原始解决方案1方法)更快。

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

NB:本selectNodeContents VS selectNode

+1

NB:溶液2从@ TIM-按下码在启发:http://stackoverflow.com/questions/6240139/highlight-text-range-使用javascript感谢提姆! – 2013-04-26 21:01:29