首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

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

2012-09-27 
IE在线编辑器器 Undo / Redo 失效问题及解决方案今天遇到个问题,我的MocolaEditor之前有效的 Undo / Redo

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

热点排行