单位里有一套新闻发布系统,是很早以前的了,一直在用,eWebEditor是什么版本的也搞不清了,但肯定是老版本。
前一段时间也出了问题,在IE8上按钮失效,经过百度之后,解决方案几乎全都一样,都是五花八门的判断IE版本然后执行对应的匿名方法。
出问题的是editor.js中的这句:if (element.YUSERONCLICK) eval(element.YUSERONCLICK + "anonymous()");
而解决方案,无一例外的都是两种
1、
1 if(navigator.appVersion.match(/MSIE (7|8)\./i)!=null || navigator.appVersion.match(/MAXTHON/i)=='MAXTHON') 2 { 3 if (element.YUSERONCLICK) eval(element.YUSERONCLICK + "onclick(event)"); 4 }else{ 5 if (element.YUSERONCLICK) eval(element.YUSERONCLICK + "anonymous()"); 6 }
该方案用版本检测的方法,针对不同IE版本,调用不同函数名称来解决,但问题在于IE的后续版本流行起来的话又要加入版本号来判断了,如果IE又修改了函数名就会判断起来更麻烦了。
2、
if (element.YUSERONCLICK) { try { eval_r(element.YUSERONCLICK + "onclick(event)"); } catch (e){ eval_r(element.YUSERONCLICK + "anonymous()"); } }
该方法不检测IE版本号,而是通过try/catch来模糊区分版本号,同样问题,当IE又变更函数名的时候,就又要嵌套一层try/catch了。
3、这就是我设计的解决方案了
翻遍网络,似乎只有这两种解决方案,看来是转来转去的成了标准解决方案了。个人看法,这两种方法代码过多不说,而且还无法应对IE升级后有可能再次变更函数名的问题。仔细分析这段有问题的代码就会发现,其实element.YUSERONCLICK属性里存放的是一段function的定义,alert一下就会看到代码字符串如下:
function anonymous() { //这里是执行代码 }
完整地来看,就是用eval来执行一个js代码片段如下:
function anonymous() { //这里是执行代码 } anonymous()
由于IE的升级变化,导致anonymous()函数名发生变化,但我们在代码里把函数名作为常量字符串使用时,这种变化就不能适应了。
当然我们也可以用提取字符的方法把函数名从代码段里分割出来,然后拼凑起代码段来执行,虽然方法没问题,但还不够简洁。
其实利用JS的动态特性,我们完全可以在不必知道函数名也不必动态提取函数名的情况下直接正确的执行该函数
最终代码会比源代码还节省代码字节,只需将函数名替换成一对括号就可以解决了:
if (element.YUSERONCLICK) eval("(" + element.YUSERONCLICK + ")()");
这样一处理,不但没增加代码,反而减肥了,而且不论IE升级版本后函数名变成什么都无所谓了,只要IE不取消这个匿名功能函数就会一劳永逸。
4、关于本文的后记
时隔两年之后的今天(2014-10-20)由于又处理了一起老版本ewebeditor的匿名函数故障,再次翻出了自己的博文。无聊之际到维普网搜了一下关键字“ewebeditor”,眼前一亮发现了一篇论文引用了本博文中的解决方案,时间是在本博文整理完毕不久的同年(2012年)。
晕啊,有同学引用了本文居然一直不知道啊。
特此备注一下,满足一下小小的虚荣心,好歹咱的博文也是参考文献了,上档次了,噢耶Y。
论文:《硅谷》2012年 第18期 《eWebEditor在IE新版本下按钮失效问题的解决方法》