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

首頁 > 網站 > 軟件應用 > 正文

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

2024-09-06 19:16:51
字體:
來源:轉載
供稿:網友
就把遇到的問題記錄一下。寫這篇文章時用的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
69久久夜色精品国产69乱青草| 国产极品精品在线观看| 久久久www成人免费精品张筱雨| 国产69精品久久久久99| 色悠悠久久久久| 538国产精品一区二区在线| 热久久99这里有精品| 欧美日韩国产一区二区| 日韩黄色高清视频| 中文字幕av一区二区| 国产精品电影网| 欧美大秀在线观看| 国产午夜精品全部视频在线播放| 国模精品一区二区三区色天香| 久久精品99国产精品酒店日本| 国产精品日韩在线播放| 久久激情五月丁香伊人| 欧美激情在线狂野欧美精品| 国产精品69久久久久| 亚洲成人激情在线| 97国产suv精品一区二区62| 国产精品国产三级国产专播精品人| 久久久亚洲国产天美传媒修理工| 日韩中文在线不卡| 亚洲美女免费精品视频在线观看| 欧美黑人一区二区三区| 亚洲成年网站在线观看| 久久久综合av| 亚洲在线视频观看| 国产精品专区h在线观看| 欧美激情在线一区| 国产精品精品久久久久久| 久久精品99久久久香蕉| 亚洲精品自拍视频| 亚洲成人xxx| 亚洲人成毛片在线播放| 国产精品一区专区欧美日韩| 国产亚洲欧洲在线| 亚洲第一在线视频| 欧美色道久久88综合亚洲精品| 久久电影一区二区| 亚洲视频精品在线| 国产精品露脸自拍| 久久91亚洲精品中文字幕奶水| 国产精品国产三级国产aⅴ9色| 狠狠躁夜夜躁久久躁别揉| 久久精品久久久久| 久久夜精品va视频免费观看| 国产欧美一区二区三区久久| 日韩动漫免费观看电视剧高清| 亚洲伊人一本大道中文字幕| 国产又爽又黄的激情精品视频| 亚洲jizzjizz日本少妇| 色综合伊人色综合网站| 亚洲美女免费精品视频在线观看| 久久91亚洲精品中文字幕奶水| 亚洲人成亚洲人成在线观看| 在线一区二区日韩| 欧美电影《睫毛膏》| 69久久夜色精品国产69乱青草| 91夜夜揉人人捏人人添红杏| 爽爽爽爽爽爽爽成人免费观看| 一区二区亚洲欧洲国产日韩| 久久精品电影一区二区| 欧美日韩中文字幕日韩欧美| 日韩精品在线播放| 81精品国产乱码久久久久久| 91高清在线免费观看| 欧美在线免费看| 亚洲一区久久久| 中文日韩在线视频| 奇米四色中文综合久久| 日韩精品极品毛片系列视频| 一本久久综合亚洲鲁鲁| 欧美日在线观看| 日韩精品福利在线| 国产有码在线一区二区视频| 亚洲专区在线视频| 日韩欧美精品免费在线| 精品国产依人香蕉在线精品| 亚洲最大福利视频网站| 色综合亚洲精品激情狠狠| 久久久久久18| 18一19gay欧美视频网站| 精品美女国产在线| 亚洲精品久久久久久久久久久| 国产日本欧美一区| 日韩精品丝袜在线| 好吊成人免视频| 国产一区二区三区中文| 欧美中文字幕在线观看| 亚洲午夜久久久影院| 欧美性生活大片免费观看网址| 亚洲综合精品伊人久久| 欧美午夜精品久久久久久浪潮| 亚洲伦理中文字幕| 日韩69视频在线观看| 亚洲欧美成人网| 97在线视频免费看| 亚洲国产成人在线播放| 精品爽片免费看久久| 7777免费精品视频| 日韩精品视频中文在线观看| 欧美综合国产精品久久丁香| 欧美日本国产在线| 日韩成人在线视频观看| 日韩精品在线免费| 国产亚洲成av人片在线观看桃| 精品香蕉在线观看视频一| 久热国产精品视频| 精品视频www| 久热在线中文字幕色999舞| 国产精品日韩av| 日本中文字幕久久看| 欧美大码xxxx| 亚洲专区在线视频| 成人www视频在线观看| 57pao成人国产永久免费| 操日韩av在线电影| 精品高清一区二区三区| 欧美一级淫片videoshd| 欧美xxxx做受欧美.88| 国产精品视频一区国模私拍| 黑人与娇小精品av专区| 精品国产老师黑色丝袜高跟鞋| 5252色成人免费视频| 欧美午夜精品伦理| 91精品视频在线免费观看| 亚洲欧美在线磁力| 日韩av电影在线播放| 在线视频欧美日韩| 亚洲欧美日韩图片| 92国产精品久久久久首页| 日韩在线中文字幕| 全球成人中文在线| 欧美最猛黑人xxxx黑人猛叫黄| 91久久在线视频| 亚洲天堂av电影| 国产精品专区第二| 97国产真实伦对白精彩视频8| 欧美另类极品videosbest最新版本| 国产91亚洲精品| 欧美日韩亚洲视频一区| 国产精品欧美亚洲777777| 亚洲品质视频自拍网| 久久视频在线视频| 91国产精品视频在线| 精品亚洲一区二区三区在线观看| 欧美高清在线播放| 欧美日韩一区免费| 国产成人精品999| 欧美精品在线第一页| 国产精品一区二区av影院萌芽| 91免费看片网站| 一区二区在线视频播放| 日韩在线观看高清| 欧美电影免费看| 欧美激情视频在线| 黄色成人av在线| 亚洲最大中文字幕| 亚洲在线观看视频网站| 亚洲精品自拍视频| 亚洲人在线观看| 欧美性xxxx极品hd欧美风情|