项目中需用户自定义表单,类似于富文本编辑器,在IE6,IE7没有问题,但在IE8下就歇菜,每每给客户演示,总遇到该问题,再三向客户解释并承诺尽快解决。
但要解决这个问题,谈何容易。
曾花了一周多时间也没有解决该问题,郁闷啊。
忽有一日,网上曾见一文,解决思路:当点击插入点后,马上把该点作一个锚点,选中控件后把控件html贴于上述锚点。该方案一直被我奉为圭臬,然而可能终不得其法,故均无功而返,甚为狼狈。
再次发扬蚂蚁啃骨头的精神,终于在下文的帮助下解决了这个顽疾!
selection.createRange() not working in IE8的解决方法
[ 预备警司.10078 @ 2009-09-26 09:35:55 ]
selection.createRange() not working in IE8的解决方法
最近,随着windows7的日益临近,很多人的IE浏览器操作系统的升级,一并进入到IE8。
在测试生产系统在IE8里的兼容性时发现,一个在线编辑器无法正常使用,这个编辑器类似于许多Web Editor,但与 UFQIE 不同的是,它是基于“控件”的,控件在这里可以理解为,普通的Web Editor插入一个一个的元素,字符对象等等,而控件化的,插入的是控件,可以对控件对象进行“属性"编辑,呈现效果由解析引擎执行控件后得到——这是其最具有特色的地方。
该编辑器在 IE7之前的版本都运行良好,在IE8中进行操作时,发现无法往一个 editable 的 div对象里插入“控件”对象,完成这个动作的方法是: insertImg , 在这个方法里:
if(document.selection.type == "Text"
|| document.selection.type == "None")
{
var sRange = document.selection.createRange();
itemindex++;
var itemname = obj.name + "::" + itemindex;
sRange.pasteHTML("<img src='" + "images/item/pic-" + obj.name + ".gif" + "' onDBLClick='itemAttrEditor.window.editItemAttrs(this);' name='"+itemname+"'> ");
}
使用了 document.selection.createRange() 的方法, 跟踪测试,发现这个无法在 IE8 下面正常执行并得到预期的效果,而且相应的报错。
后来经过搜索,发现网上说这个是 IE8 的一个bug,有个解决帮是:
You can also try the new proprietary meta tag in your documents
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
Suggested reading
http://blogs.msdn.com/ie/archive/2008/06/10/introducing-ie-emulateie7.aspx
于是赶紧测试一下,发现非预期的,即便是在头部加入这个meta,浏览器被识别为 IE7, 但上面的 createRange 仍就不好使。
另外发现一个建议性的是:
in ie8 YOU NEED to select editable area becuase there is no other way.
具体怎么 select ,并没有给出,于是在上面的代码中,我尝试性的加入:
if(document.selection.type == "Text"
|| document.selection.type == "None")
{
//window.alert('insert action fired! type:['+document.selection.type+']');
document.getElementById('oDiv').focus();
//-- focus in the target div with id='oDiv' , add when under IE8
var sRange = document.selection.createRange();
itemindex++;
var itemname = obj.name + "::" + itemindex;
sRange.pasteHTML("<img src='" + "images/item/pic-" + obj.name + ".gif" + "' onDBLClick='itemAttrEditor.window.editItemAttrs(this);' name='"+itemname+"'> ");
//window.alert('insert action done! itemname:['+itemname+'] sRange:['+sRange+']');
}
else
{
window.alert('insert action failed: select.type:['+document.selection.type+']');
}
ducument.getElementById('oDiv').focus();
//-- IE7 and below, only handle like this
保存,刷新,然后再次测试时,即可顺利进行,也就是说,在IE8下进行 selection.createRange() 时,需先将 target 进行 focus in操作,然后就可顺利进行,而IE7以下,似乎是往默认的 editable 的div去.
附注:加上如下两句
var doc = document.frames.designer1.document || document.frames.designer1.contentDocument; //IE || W3C
doc.designMode = 'on';
可解决IE8不支持 pasteHTML、parentElement等方法的问题。