javascript
JavaScript Iframe富文本编辑器中的光标定位
最近在項目中碰到一個比較棘手的問題:
在iframe富文本編輯器中,有個工具欄,這個工具欄在iframe標簽之外,工具欄上有一個按鈕,點擊該按鈕向iframe正在編輯中的光標處插入一個圖片,圖片會插入到當前光標所在的位置。但由于需求的需要,點擊該按鈕后需要彈出一個詳細選項浮動層,選擇詳細的類型后再插入,如此,問題來了,當我點擊了該按鈕,浮動層顯示出來后,iframe已經失去焦點,并不知道之前正在編輯的位置,所以編輯器默認把圖片插入到編輯器內容的最前邊(內部處理),編輯器及浮動層需求如下圖:
解決嘗試
一、利用模態彈出框
首先聲明這種方式是可行的,因為模態對話框會保持iframe編輯器的編輯狀態,模態對話框的返回值可直接插入到之前正在編輯的光標位置,就像上面圖中其他按鈕一樣,它們通過點擊事件直接插入。但是對于上述需求,只是在該按鈕位置添加了一個子類型選擇列表框,用模態窗口顯然得不到更好的人性化體驗,這也不是我們所想要的。
這時候如果能保存之前光標的編輯位置就好了,的確,在按鈕的點擊事件中,彈出浮動層的同時也保存好光標的位置,然后選擇了詳細類型后再將光標還原到原來的位置插入圖片信息,經過嘗試和摸索,令人欣喜的是,這種方式是可行的。
二、保存光標位置,選擇后還原(1)
這種方法主要通過document的selection對象來實現,在按鈕的點擊事件處理程序中,獲取當前光標據文檔開頭的位置(即長度),然后保存,在選擇了子類型后,根據之前保存的位置還原光標,然后插入圖片信息,代碼片段如下:
1 //記錄光標的位置,以備后續還原使用 2 var LastPos = 0; 3 //保存當前光標的位置 4 function SaveCusorPos() { 5 //獲取編輯器焦點 6 var wobj = document.getElementById("myiframe").contentWindow; 7 wobj.focus(); 8 if (document.selection) { 9 //ie,利用范圍進行計算 10 var sText = wobj.document.selection.createRange(); 11 //清除掉當前選中的內容 12 if (sText.htmlText != undefined && sText.htmlText != "") { 13 wobj.document.selection.clear(); 14 } 15 //選擇當前光標位置到文檔開頭之間的內容(以字符為單位) 16 sText.moveStart('character', -wobj.document.body.innerHTML.toString().length); 17 //計算選擇內容的長度 18 LastPos = sText.text.length + FliterHtmlTag(sText.htmlText) + 1; //; //sText.htmlText.length; // 19 } 20 else if (wobj.selectionStart || wobj.selectionStart == "0") { 21 //firefox,直接讀取編輯位置 22 LastPos = wobj.selectionStart; 23 } 24 }上述代碼不難理解,在ie中需要用范圍計算當前光標位置距離文檔開頭的距離,而在firefox中,直接可以用編輯對象獲取當前的編輯位置,下面是光標還原的代碼:
1 //把光標還原到之前保存的位置 2 function SetCusorPos() { 3 //獲取編輯器對象焦點 4 var wobj = document.getElementById("myiframe").contentWindow; 5 wobj.focus(); 6 if (wobj.document.body.setSelectionRange) { 7 //firefox,直接通過函數定位光標 8 wobj.document.body.setSelectionRange(LastPos, LastPos); 9 } 10 else if (wobj.document.selection.createRange()) { 11 //ie,用selection對象進行選擇 12 var range = wobj.document.selection.createRange(); 13 range.collapse(true); 14 //將選擇區域的開始位置和結束位置都移動到之前保存的點 15 range.moveEnd('character', LastPos); 16 range.moveStart('character', LastPos); 17 //定位光標的位置 18 range.select(); 19 } 20 }在不同的瀏覽器中,處理方式均不一樣,不過有一點是相通的,它們都是通過將選取的開始位置和結束位置重合來定位光標。
經測試,這種方式是可行的,但它只能在純文本處理的時候有用(IE中),問題在于這個保存點的計算,通過選區Text的length獲取的長度是只是這個選區的文字長度,它并不能過濾多媒體元素(如圖片、音視頻等),這些元素在這個length中并沒有包括,故存在多媒體元素的時候,這個光標保存點是不準的,會在實際位置的前面插入。此外,選區還有另外一個屬性htmlText,獲取它的長度又如何呢!?答案也是不行,這個長度包含了選區中html標簽的所有字符,比如換行,段落等都被計算在內,這個光標保存點比實際的要大的多,會在實際位置的后面插入。
二、保存光標位置,選擇后還原(2)
上述兩種方法都有自己的缺陷,經過摸索和查閱相關資料,在IE中有第三種方法可以實現此功能,就是selection對象的getBookmark和moveToBookmark兩個方法,前者獲取一個對象,這個對象記錄了當前編輯器中光標的位置信息,后者根據這個位置信息還原光標的位置。代碼如下:
1 //存儲之前光標位置信息的對象 2 var ieSelectionBookMark = null; 3 //保存當前光標的位置 4 function SaveCusorPos() { 5 //編輯器獲取焦點 6 var wobj = document.getElementById("myiframe").contentWindow; 7 wobj.focus(); 8 if (document.selection) { 9 //獲取當前光標的位置 10 var rangeObj = wobj.document.selection.createRange(); 11 ieSelectionBookMark = rangeObj.getBookmark(); 12 } 13 } 14 //把光標還原到之前保存的位置 15 function SetCusorPos() { 16 //編輯器獲取焦點 17 var wobj = document.getElementById("myiframe").contentWindow; 18 wobj.focus(); 19 if (ieSelectionBookMark) { 20 //還原光標的位置 21 var rangeObj = wobj.document.selection.createRange(); 22 rangeObj.moveToBookmark(ieSelectionBookMark); 23 rangeObj.select(); 24 ieSelectionBookMark = null; 25 } 26 }上述代碼改寫了第二種方法中的兩個函數,比較簡潔,但這種方式在IE8中測試通過,其他不同版本瀏覽器中有待進一步驗證,其他瀏覽器如firefox,利用第二種方式就可以實現。
?
如今瀏覽器五法八門,各自對標準的支持也不一樣,導致了前端開發者做了大量的工作來彌補兼容性,不管怎樣,相信會越來越好~~~
轉載于:https://www.cnblogs.com/freshfish/p/3432907.html
總結
以上是生活随笔為你收集整理的JavaScript Iframe富文本编辑器中的光标定位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PhotoShop更改图片背景色
- 下一篇: Backup状态