亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

javascript開發隨筆3 開發iframe富文本編輯器的一點體會

2024-07-21 02:53:56
字體:
來源:轉載
供稿:網友
前段時間有個需求是開發富文本編輯器,這個之前隨做過,但看了需求,發現有些地方還需google
 
就把遇到的問題記錄一下。寫這篇文章時用的TinyMCE編輯器就很強大,但畢竟是第三方的,項目也考慮了這些,如果做些自定義的東西不太方便。 
1. 判斷光標位置的元素(或者選中的部分)的樣式。光標位置改變的時候更新工具欄對應按鈕的樣式。什么情況下光標的位置會改變呢?是鍵盤方向鍵和鼠標點擊,于是就判斷鍵盤事件和鼠標事件來執行光標移動的處理。 
a. 獲得光標位置或選中元素:首先getSelection,創建range。然后獲得元素,獲取到元素之后就可以或得樣式、tagName等等,做更多的操作,運行代碼: 
復制代碼代碼如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
<head> 
<title></title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<style type="text/css"> 
p{width:600px;text-align: left;text-indent:2em;line-height:20px;font-size:12px} 
textarea{width:600px;height:100px;font-size:12px;overflow:auto} 
</style> 
</head> 
<body> 
<span style="display:block;height:150px; font-size:12px;line-height:150%">信息</span> 
<script type="text/javascript"> 
function createEditor(){ 
var iframe = document.createElement('iframe'); 
iframe.id = 'iframe'; 
iframe.frameBorder = 1; 
iframe.width = 400; 
iframe.height = 200; 
document.body.appendChild(iframe); 
return iframe; 

var bind = function(element,eventType,fn,useCapture){ 
useCapture = useCapture || false; 
if(arguments.length < 3){ 
return true 
}; 
if(window.addEventListener){ 
element.addEventListener(eventType, fn, useCapture); 
}else{ 
element.attachEvent('on'+eventType,fn, useCapture); 


//from 司徒正美 
var css = document.defaultView ? function(el,style){ 
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style) 
} : function(el,style){ 
style = style.replace(//-(/w)/g, function($, $1){ 
return $1.toUpperCase(); 
}); 
return el.currentStyle[style]; 

function bindEditor(){ 
var iframe = createEditor(); 
var ifr_win = iframe.contentWindow; 
var ifr_doc = ifr_win.document; 

var editorContent = '<span style="font-family: 黑體; font-weight: bold;">阿四大四大四</span>大<span style="font-style: italic; text-decoration: underline;">四大四大打算</span>打打<span style="font-style: italic; color: #ff0000;">雙打薩斯</span>大師'; 
ifr_doc.designMode='On';//可編輯 
ifr_doc.contentEditable = true; 
ifr_doc.open(); 
ifr_doc.writeln('<html><head><style type="text/css">body{padding:10px;margin:0;font-size:13px;font-family:宋體;text-align:left;overflow:auto;word-wrap: break-word;cursor:text;background-color: transparent; }body,p,font,div,ul,li {line-height: 1.5;}p,font,div,ul,li {line-height: 1.5;margin:0;padding:0}a{color:#548DD4}</style></head><body>'+ editorContent +'</body></html>'); 
ifr_doc.close(); 

var getRange = function(){ 
var range = window.getSelection ? ifr_win.getSelection() : ifr_win.document.selection; 
if (!range) { 
return { 
node : null, 
range : null, 
text : null 
}; 

range = range.createRange ? range.createRange() : range.getRangeAt(0); 
var text = window.getSelection ? range : range.text; 
var rangeNode = null; 
if (range.commonAncestorContainer) { 
rangeNode = range.commonAncestorContainer; 
} else { 
if (range.parentElement) rangeNode = range.parentElement(); 

return { 
node : rangeNode, 
range : range, 
text : text 


var info = document.getElementsByTagName('span')[0]; 
var getStyle = function(node){ 
//console.log(node) 
var html = ''; 
html+= '<span style="font-family:'+ css(node,'font-family') +'">字體:'+ css(node,'font-family') + '</span><br />'; 
html+= '<span style="color:'+ css(node,'color') +'">顏色:'+ css(node,'color') + '</span><br />'; 
html+= '<span style="font-style:'+ css(node,'font-style') +'">斜體:'+ css(node,'font-style') + '</span><br />'; 
html+= '<span style="font-weight:'+ css(node,'font-weight') +'">粗體:'+ css(node,'font-weight') + '</span><br />'; 
html+= '<span style="text-decoration:'+ css(node,'text-decoration') +'">下劃線:'+ css(node,'text-decoration') + '</span><br />'; 
html+= 'tagName:'+ node.tagName + ',style:'+ node.getAttribute('style') +'<br />'; 

info.innerHTML = html; 

//當光標位置改變時候執行 
var onselectionchange = function(event){ 
var e = event || window.event; 
if(!e.keyCode)e.keyCode = e.which; 
//方向鍵移動光標,獲取光標位置的dom 
if((e.keyCode >= 37 && e.keyCode <= 40 )|| e.type == "click"){ 

var node = getRange().node;//獲取光標位置元素 
if(node !== null){ 
while(node.nodeType != 1){ 
node = node.parentNode; 

getStyle(node); 




bind(ifr_doc,'click',onselectionchange,false); 
bind(ifr_doc,'keydown',onselectionchange,false); 

window.onload = function(){ 
bindEditor(); 

</script> 
</body> 
</html> 

2. ie不能保持光標位置,這個是在添加超鏈接時候出現的問題,當不使用瀏覽器內置的輸入框,光標移動其他的文本域里,ie會失去所選中的部分,無法對選中的部分加鏈接了,解決辦法就是:利用range的getBookmark和moveToBookmark,然后給iframe的document綁定onbeforedeactivate(getBookmark)、onactivate(moveTo),這2個事件的大致意思就是,當被激活和失去激活狀態。增加事件之后,就不必保存lastRang或者再其他地方設置bookmark了,可以讓ie像其他瀏覽器一樣自動保持光標位置了 
復制代碼代碼如下:

if(Util.browser.msie){ 
Util.bind(this.E.ifr_win.document, "beforedeactivate", function(){ 
var Rng = _self.getRange().range; 
_self.rangeBookMark= Rng.getBookmark(); 
}); 
Util.bind(this.E.ifr_win.document, "activate", function(){ 
var Rng = _self.getRange().range; 
Rng.moveToBookmark(_self.rangeBookMark); 
Rng.select(); 
_self.rangeBookMark = null; 
}); 

3. ie中的撤銷與重做 。 當iframe外部有彈出窗口、或者修改html撤銷、重做功能將失效。只能歸為ie的bug了。。。。也許ie沒分清iframe和頁面的document,把他們的撤銷、重做混道義了。 
如下: 
復制代碼代碼如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
<head> 
<title></title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<style type="text/css"> 
p{width:600px;text-align: left;text-indent:2em;line-height:20px;font-size:12px} 
textarea{width:600px;height:100px;font-size:12px;overflow:auto} 
</style> 
</head> 
<body> 
<span style="display:block;height:150px; font-size:12px;line-height:150%">信息</span> 
<div id="J_tool"> 
<input type="button" command="Undo" value="撤銷" unselectable="on" /> 
<input type="button" command="Redo" value="重做" unselectable="on" /> 
<input type="button" command="Bold" value="粗體" unselectable="on" /> 
<input type="button" command="Italic" value="斜體" unselectable="on" /> 
</div> 
<br /> 
<input type="button" onclick="changeLayout()" value="點擊下,ie將無法撤銷、重做" /> 
<br /> 
<script type="text/javascript"> 
function changeLayout(){ 
var popwin = document.getElementById('popwin'); 
if(!popwin){ 
popwin = document.createElement('div'); 
popwin.id = 'popwin'; 
popwin.style.cssText = 'display:none;width:300px;height:150px;background-color:#ccc;position:absolute;left:0;top:0px;text-align:center;line-height:150px;'; 
popwin.innerHTML = '改變了layoud渲染,ie將無法撤銷、重做'; 
document.body.appendChild(popwin); 
popwin.onclick= function(){this.style.display = 'none'}; 

popwin.style.display = popwin.style.display == 'none' ? 'block' : 'none'; 

function createEditor(){ 
var iframe = document.createElement('iframe'); 
iframe.id = 'iframe'; 
iframe.frameBorder = 1; 
iframe.width = 400; 
iframe.height = 200; 
document.body.appendChild(iframe); 
return iframe; 

var bind = function(element,eventType,fn,useCapture){ 
useCapture = useCapture || false; 
if(arguments.length < 3){ 
return true 
}; 
if(window.addEventListener){ 
element.addEventListener(eventType, fn, useCapture); 
}else{ 
element.attachEvent('on'+eventType,fn, useCapture); 


//from 司徒正美 
var css = document.defaultView ? function(el,style){ 
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style) 
} : function(el,style){ 
style = style.replace(//-(/w)/g, function($, $1){ 
return $1.toUpperCase(); 
}); 
return el.currentStyle[style]; 

function bindEditor(){ 
var iframe = createEditor(); 
var ifr_win = iframe.contentWindow; 
var ifr_doc = ifr_win.document; 
var editorContent = '<span style="font-family: 黑體; font-weight: bold;">阿四大四大四</span>大<span style="font-style: italic; text-decoration: underline;">四大四大打算</span>打打<span style="font-style: italic; color: #ff0000;">雙打薩斯</span>大師'; 
ifr_doc.designMode='On';//可編輯 
ifr_doc.contentEditable = true; 
ifr_doc.open(); 
ifr_doc.writeln('<html><head><style type="text/css">body{padding:10px;margin:0;font-size:13px;font-family:宋體;text-align:left;overflow:auto;word-wrap: break-word;cursor:text;background-color: transparent; }body,p,font,div,ul,li {line-height: 1.5;}p,font,div,ul,li {line-height: 1.5;margin:0;padding:0}a{color:#548DD4}</style></head><body>'+ editorContent +'</body></html>'); 
ifr_doc.close(); 
var getRange = function(){ 
var range = window.getSelection ? ifr_win.getSelection() : ifr_win.document.selection; 
if (!range) { 
return { 
node : null, 
range : null, 
text : null 
}; 

range = range.createRange ? range.createRange() : range.getRangeAt(0); 
var text = window.getSelection ? range : range.text; 
var rangeNode = null; 
if (range.commonAncestorContainer) { 
rangeNode = range.commonAncestorContainer; 
} else { 
if (range.parentElement) rangeNode = range.parentElement(); 

return { 
node : rangeNode, 
range : range, 
text : text 


var info = document.getElementsByTagName('span')[0]; 
var getStyle = function(node){ 
//console.log(node) 
var html = ''; 
html+= '<span style="font-family:'+ css(node,'font-family') +'">字體:'+ css(node,'font-family') + '</span><br />'; 
html+= '<span style="color:'+ css(node,'color') +'">顏色:'+ css(node,'color') + '</span><br />'; 
html+= '<span style="font-style:'+ css(node,'font-style') +'">斜體:'+ css(node,'font-style') + '</span><br />'; 
html+= '<span style="font-weight:'+ css(node,'font-weight') +'">粗體:'+ css(node,'font-weight') + '</span><br />'; 
html+= '<span style="text-decoration:'+ css(node,'text-decoration') +'">下劃線:'+ css(node,'text-decoration') + '</span><br />'; 
html+= 'tagName:'+ node.tagName + ',style:'+ node.getAttribute('style') +'<br />'; 
info.innerHTML = html; 

//當光標位置改變時候執行 
var onselectionchange = function(event){ 
var e = event || window.event; 
if(!e.keyCode)e.keyCode = e.which; 
//方向鍵移動光標,獲取光標位置的dom 
if((e.keyCode >= 37 && e.keyCode <= 40 )|| e.type == "click"){ 
var node = getRange().node;//獲取光標位置元素 
if(node !== null){ 
while(node.nodeType != 1){ 
node = node.parentNode; 

getStyle(node); 



bind(ifr_doc,'click',onselectionchange,false); 
bind(ifr_doc,'keydown',onselectionchange,false); 
bind(document.getElementById('J_tool'),'click',function(event){ 
event = event || window.event; 
var target = event.srcElement || event.target; 
var command = target.getAttribute('command'); 
var param = target.getAttribute('param') || ''; 
ifr_doc.execCommand(command,false,param); 
return false; 
}) 

window.onload = function(){ 
bindEditor(); 

</script> 
</body> 
</html> 

如何解決呢? 只能依靠javascript模擬撤銷與重做了。網絡這方面的資源還是不少的,就不在此詳細說明了 


注:相關教程知識閱讀請移步到編輯器頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人精品视频99在线观看免费| 人妖精品videosex性欧美| 色青青草原桃花久久综合| 色综合天天综合网国产成人网| 亚洲精品美女在线观看播放| 亚洲最新视频在线| 亚洲欧美在线看| 国产福利精品在线| 国产日韩精品电影| 欧美日韩在线免费观看| 尤物yw午夜国产精品视频明星| 国产欧美婷婷中文| 欧美精品一区三区| 亚洲一区www| 欧美电影免费播放| 亚洲自拍偷拍福利| 成人观看高清在线观看免费| 欧美激情女人20p| 青青草一区二区| 九九九热精品免费视频观看网站| 国产精品私拍pans大尺度在线| 久久久97精品| 国产成人亚洲综合| 精品一区二区电影| 亚洲aa中文字幕| 久久精品中文字幕一区| 亚洲综合在线中文字幕| 国产精品久久999| 亚洲最新视频在线| 欧美在线亚洲一区| 成人自拍性视频| 欧美成人精品在线| 日韩免费在线免费观看| 国产免费一区二区三区在线观看| 91久久久在线| 在线一区二区日韩| 日韩在线精品一区| 性色av香蕉一区二区| 亚洲欧美国产精品va在线观看| 亚洲欧洲日产国产网站| 欧美精品一本久久男人的天堂| 热久久美女精品天天吊色| 欧美一级免费视频| 久久久久久久影院| 国产mv免费观看入口亚洲| 亚洲**2019国产| 国产成人精品免费久久久久| 成人精品一区二区三区| 国产一区二区三区毛片| 自拍偷拍亚洲在线| 成人免费视频xnxx.com| 久久久久五月天| 国产精品免费在线免费| 欧美综合在线观看| 日韩在线视频线视频免费网站| 伊人久久综合97精品| 国产一区二区三区在线视频| 国产精品视频网址| 丝袜亚洲欧美日韩综合| 欧美老妇交乱视频| 奇门遁甲1982国语版免费观看高清| 日韩精品电影网| 久久亚洲国产精品| 日韩成人在线视频| 亚洲另类欧美自拍| 一区二区三区回区在观看免费视频| 亚洲美女福利视频网站| 欧美一区二区三区免费观看| 欧美性生交大片免网| 黄色一区二区在线观看| 欧美在线免费视频| 精品视频久久久久久| 狠狠色狠色综合曰曰| 黑人与娇小精品av专区| 97视频在线观看视频免费视频| 国产精品视频久久久久| 日韩欧美成人精品| 欧美精品videosex极品1| 国产成人极品视频| 狠狠做深爱婷婷久久综合一区| 成人免费视频在线观看超级碰| 在线亚洲国产精品网| 日韩av在线一区二区| 精品国产一区二区三区久久狼黑人| 国产精品白嫩美女在线观看| 欧美黑人一级爽快片淫片高清| 国产99在线|中文| 91免费观看网站| 91久久国产精品91久久性色| 欧美一级大胆视频| 亚洲精品综合精品自拍| 欧美在线观看一区二区三区| 黄色成人在线免费| www.欧美免费| 欧美香蕉大胸在线视频观看| 欧美激情亚洲另类| 日韩电影免费观看在线观看| 久久久精品国产一区二区| 国产主播精品在线| 在线电影av不卡网址| 欧美日韩国产丝袜另类| 久热精品视频在线免费观看| 久久99精品久久久久久青青91| 久久国产一区二区三区| 亚洲国产成人爱av在线播放| 中文字幕在线看视频国产欧美| 一区二区欧美日韩视频| 欧美在线视频一区| 欧美在线视频网| 久久久97精品| 最近2019年中文视频免费在线观看| 91欧美视频网站| 大桥未久av一区二区三区| 久久久久99精品久久久久| 亚洲精品一区二区在线| 国产精品精品视频一区二区三区| 国产欧美日韩免费| 日韩欧美国产免费播放| 日韩精品视频免费专区在线播放| 欧洲成人在线视频| 91在线网站视频| 亚洲999一在线观看www| 青草青草久热精品视频在线观看| 欧美黑人性猛交| 午夜精品福利在线观看| 久久精品亚洲精品| 九九久久久久99精品| 尤物九九久久国产精品的特点| 亚洲专区国产精品| 午夜精品国产精品大乳美女| 性日韩欧美在线视频| 亚洲午夜女主播在线直播| www.99久久热国产日韩欧美.com| 久久精品国产一区二区电影| 热草久综合在线| 午夜精品一区二区三区av| 日韩精品在线免费播放| 日韩中文字幕视频在线| 久久夜色撩人精品| 91精品国产自产在线| 亚洲娇小xxxx欧美娇小| 中文字幕亚洲欧美| 国产精品网站入口| 国产精品日韩欧美大师| 日韩亚洲国产中文字幕| 久久精品国产久精国产思思| 亚洲经典中文字幕| 国内免费久久久久久久久久久| 中文字幕精品www乱入免费视频| 性欧美暴力猛交69hd| 国产va免费精品高清在线| 亚洲国产成人在线视频| 91青草视频久久| 69av视频在线播放| 精品国产成人av| 日韩av大片免费看| 欧美自拍视频在线观看| 国产成人精彩在线视频九色| 日韩在线观看免费| 日本不卡免费高清视频| 97精品国产97久久久久久春色| 精品国产一区二区三区久久| 国产精品免费视频xxxx| 亚洲精品国产拍免费91在线|