一切關(guān)于“問題的解決之道”的方法論都不外乎是“變通”二字的某種講法。既然這個(gè)功能不適宜用Editor.document.selection.createRange()的pasteHTML()方法來實(shí)現(xiàn),我們就不用它好了。一個(gè)變通的想法是:通過改變Editor.document.body.innerHTML的全局來實(shí)現(xiàn)。
很顯然,至少在理論上,整體改變Editor.document.body.innerHTML可以實(shí)現(xiàn)任何我們想要的HTML編輯效果。
多好,隨著靈光一閃,戰(zhàn)略上的大問題在一秒鐘之內(nèi)就被我們搞定了!接下來讓我們看看具體的實(shí)現(xiàn)方法吧:
要想通過改變Editor.document.body.innerHTML來給選中的內(nèi)容設(shè)置字號大小,首先要解決的一個(gè)問題是在Editor.document.body.innerHTML中對選中內(nèi)容所對應(yīng)的代碼進(jìn)行定位。這算不上是個(gè)超級復(fù)雜的問題,但我知道對這個(gè)問題的解答也是很多人夢寐以求的。或許能有很多種解,下面給出我Bound0的辦法。
顯然這個(gè)問題不可以像一些人想象的那樣隨隨便便地用正則或者查找之類的方法就搞定,設(shè)想我在 Bound0000000000000000000000000000000000000000000000000000中隨便選中了一個(gè)0(表示為紅色),用正則隨便查到了一個(gè)0,很難確保就是我選中的那個(gè),同樣的道理,如果是在雷同的若干段HTML代碼中選中了一段,用查找所選字符的方法是不能確保正確定位的。
這個(gè)問題的合理的解應(yīng)該能把Editor.document.body.innerHTML分成三段:partA—選中內(nèi)容之前的內(nèi)容所對應(yīng)的代碼、partB—選中內(nèi)容所對應(yīng)的代碼(就是前面例子中紅色的部分)、partC—選中內(nèi)容之后的內(nèi)容所對應(yīng)的代碼。(在全選的時(shí)候,partA和partC都是空字符串;選中內(nèi)容為空的時(shí)候,從開頭到光標(biāo)位置的內(nèi)容所對應(yīng)的代碼是partA,partB為空字符串,光標(biāo)之后的內(nèi)容所對應(yīng)的代碼是partC)
看看主要的代碼:
CODE:
function first() { //首先要取得編輯區(qū)的內(nèi)容
var oSel = Editor.document.selection.createRange(); var conts=''+oSel.htmlText //內(nèi)容選中部分對應(yīng)的代碼,首尾可能帶有多余標(biāo)簽(就是前面例子中的藍(lán)色標(biāo)簽)。 var textLength = Editor.document.body.innerText.length oSel.moveStart("character", -1*textLength) //把選擇區(qū)的開始位置往前閃,再取一次內(nèi)容 var contp=''+oSel.htmlText //選中部分及選中部分前的內(nèi)容,末尾可能帶有多余標(biāo)簽。 var conta=''+Editor.document.body.innerHTML //整個(gè)內(nèi)容
var contpa='' var partC="" var partB="" var partA=""
//接下來通過兩組循壞,用上面取得的三個(gè)內(nèi)容互相“磨”,把多余的標(biāo)簽“磨”掉。
var m=0 m=conta.indexOf(contp.substr(0,3)) //校正對齊contp和conta的開始位置,有時(shí)候conta開始處可能會有多余的<p>,造成兩者對不齊
for(var f=contp.length;f>0;f--) {if(conta.substr(m,f)==contp.substr(0, f)){contpa=contp.substr(0,f);partC=conta.substr(m+f);break}}
var k=contpa.length for(var u=conts.length;u>0;u--) {if(conts.lastIndexOf(contpa.substr(k-u))!=-1){partB=contpa.substr(k-u);partA=contpa.substr(0,k-u);break}}
if(conts.length==0)partA=contpa
//顯示按要求分好的A、B、C三段內(nèi)容。
alert(partA) alert(partB) alert(partC) }
實(shí)際使用的代碼比這個(gè)要復(fù)雜一些。因?yàn)橄胍獞?yīng)付各種特殊情況、考慮周全也不容易呢。
上面代碼所取到的conts和contp常常會包含瀏覽器自動添加的一些\r\n(回車、換行符),這會造成后面“磨”的困難,有必要先進(jìn)行格式化。但是由于對于pre、textarea、script、style和xmp這幾種標(biāo)簽的內(nèi)容來說\r\n可能是有意義的,所以不能簡單地用.replace(/[\r\n]/g,"")的辦法去除。必須既要去除瀏覽器自動添加的\r\n,又要保全pre、textarea、script和xmp這幾種標(biāo)簽的內(nèi)容。這種局面看起來確實(shí)復(fù)雜,不過好在瀏覽器不會在我們要保全的那幾種標(biāo)簽的內(nèi)容里自動添加\r\n,而這個(gè)時(shí)候原本是罪魁禍?zhǔn)椎膁ocument.selection.createRange().htmlText的標(biāo)簽自動封閉機(jī)制反倒為我們提供了方便:除非選中的內(nèi)容剛好處于一個(gè)標(biāo)簽的內(nèi)部,否則在conts中將出現(xiàn)完整成對的標(biāo)簽,這樣我們就可以比較容易地把位于pre、textarea、script、style和xmp這幾種標(biāo)簽中的內(nèi)容區(qū)分出來,只對其他內(nèi)容進(jìn)行去除\r\n的操作。而對于選中的內(nèi)容剛好處于一個(gè)標(biāo)簽的內(nèi)部的這種情況,它的具體情況可能又是五花八門的,我個(gè)人采取的辦法是把格式化和不格式化都嘗試一下,除非格式化的結(jié)果令partB長度較長(這說明瀏覽器自動添加的那些\r\n使“磨”出來的partB長度變短),否則就不格式化。
有時(shí)候?yàn)g覽器自動補(bǔ)全的標(biāo)簽并非添加在選中區(qū)域的最外圍。例如有時(shí)會把</p>結(jié)束標(biāo)簽添在</font>標(biāo)簽之前,而這里的</font>標(biāo)簽應(yīng)該是保留在partB中的,如果把</font>連同</p>一起“磨”掉就不對了。對此采取的辦法是檢查被“磨”掉的碎渣部分,把碎渣撿起來“磨”好,再裝到partB的末尾。
出處:藍(lán)色理想
責(zé)任編輯:moby
上一頁 前人的誤區(qū) 下一頁 解決之道 [下]
◎進(jìn)入論壇網(wǎng)頁制作、網(wǎng)站綜合版塊參加討論
|