Javascript 合并堆叠的DOM格式元素-contenteditable DIV
我有一个contenteditable DIV,它链接/同步回textarea contenteditable DIV是一个免费的沙盒,它将在调用时创建格式化元素等。但是,这通常会导致混乱的堆叠元素 我希望能够在将textarea表单发送到服务器之前清理代码 最终可能会出现以下情况:Javascript 合并堆叠的DOM格式元素-contenteditable DIV,javascript,html,dom,formatting,contenteditable,Javascript,Html,Dom,Formatting,Contenteditable,我有一个contenteditable DIV,它链接/同步回textarea contenteditable DIV是一个免费的沙盒,它将在调用时创建格式化元素等。但是,这通常会导致混乱的堆叠元素 我希望能够在将textarea表单发送到服务器之前清理代码 最终可能会出现以下情况: <div> <b> <i> Hel </i> <i> l </i> &
<div>
<b>
<i>
Hel
</i>
<i>
l
</i>
</b>
<i>
<b>
o World!
</b>
</i>
</div>
赫尔
L
哦,世界!
理想情况下,可将其转换为:
<div>
<b>
<i>
Hello World!
</i>
</b>
</div>
你好,世界!
如果我(递归地)遍历div的子节点,我大概可以跟踪格式(tagName.toUpperCase()={'B','I'…})
//或者执行document.queryCommandState
,在此期间我可以对选择节点(thenode)
执行document.execCommand('removeFormat',false,null)
然而,我对如何跟踪格式的相邻节点有点迷茫
以下是我最近为DOM解析所做的工作,以从IMG标记中删除格式:
注意:这是一个类似的问题>,但它是关于将
useCSS
样式行合并到一个主样式中。这是一个不同问题的原因是,我希望用一个通用样式合并文本,但由于文本的格式,人为地将其拆分为多个元素。如果您使用contenteditable div,并且每次单独加粗一个字符,那么每个元素将只包含一个字符。我有两种解决方案,它们各有优缺点
首先,我在gmail中玩的时候发现,如果格式样式与当前选择的模式相同,contenteditable DIV将“吸收”相邻节点。这个“免费赠品”允许我仅仅尝试重新组织格式化发生的顺序,以清理大部分html文档。这不是一个完整的解决方案。理想的解决方案是使用最大的格式化模式,因为具有子集文本的父级将具有更小的大小,而进一步的嵌套模式
在我上面的人工示例中,结果将固有地转换为:
<div>
<b>
<i>
Hel
l
</i>
</b>
....
赫尔
L
....
警告:这只测试了文本,没有图像。我可以想象,由于解决方案1中的节点解析和解决方案2中的textContent.length的使用,在处理时会出现一两个错误
解决方案1: 第一种方法在Chrome中有效,但在Firefox中调用
execCommand
会导致节点选择失去焦点,变为未选择。这是一个致命的缺陷,我似乎无法理解或编程。除非我知道如何重新突出显示/选择新格式化的节点,否则此操作已被放弃
我希望能够让这一款与Firefox一起使用。有没有关于我哪里出了问题的建议
解决方案2: 第二种方法是尝试提出一种解决Firefox失去焦点的方法。我能处理这个问题的唯一方法是忽略选择整个节点,而是一次选择一个字符,查看其格式,按特定顺序使用nuke并重新应用。这在两种浏览器中都可以使用,但是DOM会被拆分为每个字符的
childNode
。我不确定将它们结合在一起的最佳方式(文本内容?)
[背景:看看jsbeautifier、htmlsoup、HTMLTidy、nokogiri、hpricot、jtidy……我真的很惊讶,在这方面还没有解决方案。GMail也会生成“丑陋”的格式!] 我知道有更好的解决办法——我很想听听一些建议 更新 经过测试,很明显,解决方案2的速度慢得离谱(通过跟踪头部来优化它并不复杂,因为它是一个渐进的“洪水”,但仍然非常慢),甚至可以很容易地修改它来处理整个textNodes,但解决方案1似乎是一个更好的方法,如果它只在Firefox中工作的话
解决方案1+2=3: 我发现,如果我应用格式作为切换的一种手段,它将工作,但正如预测的那样,文本节点将根据相邻匹配格式的自然合并而增长/收缩。因此,我在睡觉时突然意识到,如果我创建了一个文本节点列表,并从后向前移动,我就不会在意DOM(对于Firefox!!!)在应用格式时是否在内部增长/收缩。结合解决方案2的textNode列表(然后弹出尾部节点),这非常有效。事实上,迭代而不是递归文本节点(原始解决方案1方法)速度更快
注意:selectNodeContents vs selectNode我有两种解决方案,各有利弊 首先,我在gmail中玩的时候发现,如果格式样式与当前选择的模式相同,contenteditable DIV将“吸收”相邻节点。这个“免费赠品”允许我仅仅尝试重新组织格式化发生的顺序,以清理大部分html文档。这不是一个完整的解决方案。理想的解决方案是使用最大的格式化模式,因为具有子集文本的父级将具有更小的大小,而进一步的嵌套模式 在我上面的人工示例中,结果将固有地转换为:
<div>
<b>
<i>
Hel
l
</i>
</b>
....
赫尔
L
....
警告:这只测试了文本,没有图像。我可以想象,由于解决方案1中的节点解析和解决方案2中的textContent.length的使用,在处理时会出现一两个错误
解决方案1: 第一个在Chro工作