單位里有一套新聞發布系統,是很早以前的了,一直在用,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新版本下按鈕失效問題的解決方法》