2013-04-26 62 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