javascriptがエッセイを開発しました。3.iframeリッチテキストエディタを開発しました。


出会った問題をメモしてください。この文章を書く時に使うTinyMCEのエディタはとても強いですが、やはり第三者のものです。プロジェクトもこれらを考慮しました。もしカスタマイズしたものを作るのは不便です。1.カーソル位置の要素(または選択した部分)のスタイルを判断します。カーソル位置が変わるとツールバーの対応ボタンのスタイルが更新されます。カーソルの位置はどうなりますか?キーボードの方向キーとマウスクリックで、キーボードイベントとマウスイベントを判断してカーソル移動の処理を行います。a.カーソル位置または選択要素を得る:まずレンゲをget Selectionし、レンゲを作成する。要素を取得して、要素を取得したらスタイル、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>
。ieはカーソル位置を維持できません。これはハイパーリンクを追加する時に発生する問題です。ブラウザ内の入力枠を使用しないと、他のテキスト領域にカーソルを移動し、ieは選択された部分を失います。選択された部分にリンクできませんでした。解決方法は、レンゲのget BookmarkとmoveToBook markを利用して、iframeのdocumentにオンベフォートビュー、オンactivateをバインドしてください。この2つのイベントの大まかな意味は、アクティブ化され、不活性化された状態を意味します。イベントを追加すると、lastRangを保存したり、他の場所にbook markを設置する必要がなくなり、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;
});
}
。ieの中のキャンセルとやり直しができます。iframeの外部にポップアップウィンドウがある場合、または修正)が取り消され、やり直し機能が無効になります。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シミュレーションでキャンセルとやり直ししかできません。ネットのこの方面の資源はまだ多くて、ここで詳しく説明しませんでした。