轉載請注明: TheViper http://www.cnblogs.com/TheViper
更新:fix bug http://www.cnblogs.com/TheViper/p/4629884.html
前天晚上發現上一篇iframe從光標處插入圖片(失去焦點后仍然可以在原位置插入里面的用法在ie6,7中無效,好悲催,當初只測試了ie8就以為在ie6,7上也沒問題。
昨天在github上發現了一個很好的富文本編輯器wangEditor,一看名字就是中國人寫的。這個編輯器好在支持ie6+,另外最重要的一點,它在ie6,7,8上都可以做到失去焦點后仍然可以在原位置插入圖片,而且代碼量很少。於是很好奇的看看它是怎么做的,裁剪了一下,就這些
1 var currentRange,_parentElem,supportRange = typeof document.createRange === 'function'; 2 function getCurrentRange() { 3 var selection, 4 range, 5 txt = $('editor'); 6 if(supportRange){ 7 selection = document.getSelection(); 8 if (selection.getRangeAt && selection.rangeCount) { 9 range = document.getSelection().getRangeAt(0); 10 _parentElem = range.commonAncestorContainer; 11 } 12 }else{ 13 range = document.selection.createRange(); 14 _parentElem = range.parentElement(); 15 } 16 if( _parentElem && (avalon.contains(txt, _parentElem) || txt === _parentElem) ){ 17 parentElem = _parentElem; 18 return range; 19 } 20 return range; 21 } 22 function saveSelection() { 23 currentRange = getCurrentRange(); 24 } 25 function restoreSelection() { 26 if(!currentRange){ 27 return; 28 } 29 var selection, 30 range; 31 if(supportRange){ 32 selection = document.getSelection(); 33 selection.removeAllRanges(); 34 selection.addRange(currentRange); 35 }else{ 36 range = document.selection.createRange(); 37 range.setEndPoint('EndToEnd', currentRange); 38 if(currentRange.text.length === 0){ 39 range.collapse(false); 40 }else{ 41 range.setEndPoint('StartToStart', currentRange); 42 } 43 range.select(); 44 } 45 }
這可比上一篇里面的那個從kindeditor扒下來的封裝少太多了,而且看起來也是一目了然。
怎么用呢
1 function insertImage(html){ 2 restoreSelection(); 3 if(document.selection) 4 currentRange.pasteHTML(html); 5 else 6 document.execCommand("insertImage", false,html); 7 saveSelection(); 8 } 9 avalon.bind($('post_input'),'mouseup',function(e){ 10 saveSelection(); 11 }); 12 avalon.bind($('post_input'),'keyup',function(e){ 13 saveSelection(); 14 });
和上一篇里面一樣,必須要對編輯器的div進行keyup,mouseup綁定,以便保存selection,range,方便在失去焦點后仍然可以在原來位置插入圖片。調用的時候直接insertImage(html)就可以了。這里用的不是iframe,是div contenteditable=true.
wangEditor里面的例子是插入外鏈圖片,一次只能插入一張圖片。wangEditor源碼統一用的是document.execCommand("insertImage", false,html);。但是這個方法有個問題,就是在ie6,7,8中,如果要插入多張圖片的話,只會在原來位置插入一張圖片。
先把if注釋掉

一次插入兩張圖片

這次嚴謹點,ie6

ie7

ie8

解決方法是如果是ie6,7,8的話,currentRange.pasteHTML(html); 。插入html,也就是把上面的if注釋去掉.當然插入的不再是圖片地址了,現在是包含圖片地址的整個img標簽
ie6

ie7

ie8

最后注意下,可能有時為了消除img標簽底部間距,就干脆把img標簽設置成display:block,在這里一定不能設置成display:block,否則在ie下,光標定位會出現問題。
附上例子下載
更新
發現execCommand命令中有個insertHtml,這下在非ie中,也可以和ie一樣,插入<img>標簽,不用判斷到底是在insertImage中傳入src還是整個<img>標簽了.
