Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 合并堆叠的DOM格式元素-contenteditable DIV_Javascript_Html_Dom_Formatting_Contenteditable - Fatal编程技术网

Javascript 合并堆叠的DOM格式元素-contenteditable DIV

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> &

我有一个contenteditable DIV,它链接/同步回textarea

contenteditable DIV是一个免费的沙盒,它将在调用时创建格式化元素等。但是,这通常会导致混乱的堆叠元素

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

最终可能会出现以下情况:

<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工作