当前位置: 代码迷 >> Web前端 >> IE在线编辑器器 Undo / Redo 失效有关问题及解决方案
  详细解决方案

IE在线编辑器器 Undo / Redo 失效有关问题及解决方案

热度:514   发布时间:2012-09-27 11:11:17.0
IE在线编辑器器 Undo / Redo 失效问题及解决方案
今天遇到个问题,我的MocolaEditor之前有效的 Undo / Redo 功能突然失效了,这应该是编写HTML在线编辑器的PG都会遇到的一个问题。

先看看这个问题是什么:

<script>
function onchange(){
info.innerText=editor.innerText;
}
</script>
</HEAD>
<BODY>
<div  style="width:500px;height:500px;border:1px solid #cccccc" contenteditable="true" ></div>
<div  style="width:500px;height:50px;padding:4px;background-color:#F0f0f0"></div>
</BODY>
运行上面这段代码,你会发现,你的编辑器 将无法 Undo和Redo。



为什么会这样?



原因在于 info.innerText=editor.innerText; 这一脚本,改变了当前HTML渲染。起初我以为编辑器放在IFrame里就没事了,结果发现,放哪里都一样。



<script>
function onchange(){
info.innerText=Editor.document.body.innerText;
}
window.onload=function(){
Editor.document.designMode="ON";
Editor.document.onkeyup=onchange;
}
</script>
</HEAD>
<BODY>
<iframe  style="width:500px;height:500px;border:1px solid #cccccc"></iframe>
<div  style="width:500px;height:50px;padding:4px;background-color:#F0f0f0"></div>
</BODY>
Google的Writly (http://docs.google.com),有相同的问题。他的操作界面的弹出窗口都是用 div 来实现的。这样在显示和关闭的时候 必然会做一些Dom的操作,结果是只要弹出过窗口,Undo/Redo就失效了。

问题到此,应该很清楚了。那么如何解决呢?

既然浏览器的Undo/Redo不行了,那我就自己来写一个Undo/Redo方法。

每次文档发生改变的时候,我们可以把其HTMLCode 和 Selection 选区一起保存。存入一个数组里,只要数据都存好了,想undo/redo都是很轻松的事情了。

小Tips: 可以通过 document.selection.createRange().getBookmark()方来 来保存选区状态。
    Undo的时候用 document.selection.createRange().moveToBookmark()方法来恢复选区。

以下是网上找的一段Undo/Redo 类。Typeing是为了对打字进行一些特殊处理,因为没有必要每输入一个字就增加一个UndoStep,这样太浪费内存空间了。 这里还需要对document.onkeydown函数做一些配合处理。

var CMSUndo=new Object();
CMSUndo.UndoLevels=new Array();
CMSUndo.CurrentStep=0;
CMSUndo.MaxLevel=20;
CMSUndo.Typing=false;
CMSUndo.TypingCount=CMSUndo.TypingMaxCount=25;
CMSUndo.SaveUndoStep=function(){
 if(EMode == "Code") return;
 this.UndoLevels[this.CurrentStep]=this.GetSaveData();
 this.CurrentStep++;
 this.UndoLevels=this.UndoLevels.slice(0,this.CurrentStep);
 if(this.UndoLevels>this.MaxLevel) this.UndoLevels.shift();
 this.CurrentStep=this.UndoLevels.length;
}
CMSUndo.Redo=function(){
 if(this.CurrentStep<this.UndoLevels.length-1) this.ApplyUndoLevel(this.UndoLevels[++this.CurrentStep]);
}
CMSUndo.Undo=function(){
 if(this.UndoLevels.length<1) return;
 if(this.CurrentStep==this.UndoLevels.length) this.SaveUndoStep();
 if(this.CurrentStep>0) this.ApplyUndoLevel(this.UndoLevels[--this.CurrentStep]);
}
CMSUndo.ApplyUndoLevel=function(cStep){
 EditorDesignContent.body.innerHTML=cStep.htmlcode;
 if(cStep.selrange) {
  var range=EditorDesignContent.selection.createRange()
   range.moveToBookmark(cStep.selrange)
   range.select();
   onEditContentSelChange();
 }
 this.TypesCount=0;
 this.Typing=false;
}
CMSUndo.GetSaveData=function(){
 var cStep=new Object();
  cStep.htmlcode=EditorDesignContent.body.innerHTML;
  if (EditorDesignContent.selection.type=='Text') cStep.selrange=EditorDesignContent.selection.createRange().getBookmark();
 return cStep;
}

原文:http://www.mockte.com/rewrite.php/read-30.html
  相关解决方案