Monday, June 29, 2009 - 文章

【茶包射手專欄】IFrame中的TextArea、TextBox無法輸入文字

被一個問題搞到暴怒!

我寫的一個網頁採用BlockUI的方式顯示一個嵌在IFrame裡的子網頁,以進行一些額外的資料輸入操作,操作完成後則以$.unblockUI()收掉子網頁,將控制權交回原網頁。

起初有一個使用者跟我抱怨,IFrame子網頁裡的Textarea,在重覆開啟關閉後,子網頁的Textarea、Textbox就都無法輸入文字(點選後不會顯示文字輸入游標)。試著在自己公司的電腦上進行過同樣的操作,並沒有發生無法輸入的狀況,加上其他使用者都無人回報類似錯誤,因此被我判定為少數Client環境問題怪異的個案,未再深究。

不料,今天在家裡寫網頁時,家裡的Vista x64+IE8也冒出同樣狀況: 重覆開啟子網頁後,Textarea、Textbox便無法再取得焦點輸入文字。使用FF、Chrome開啟該網頁操作,並不會有任何問題... orz

媽呀,這個設計模式已被我應用在好幾個專案裡,要是IE用起來有問題,對我來說將是一埸災難。更何況,網頁其他操作正常,就只有TextArea、TextBox在搞自閉,這是什麼鳥狀況,虧IE8可以搞出來。

讀到這裡,想必眾多Web Developer已然義憤填膺,對IE的新仇舊恨湧上心頭,蘊釀好情緒,準備要和我一起高聲吶喊 "我操你X的IE" 了吧?

且慢,李組長眉頭一皺,覺得案情並不單純...

深入做了幾個實驗,發現無法輸入的Textarea,click事件是活著的,disabled/readonly屬性也未被設定;而同網頁上的Button、Checkbox、Radio Button盡皆正常,這實在太詭異了。

於是我將可以重製問題的網頁盡可能簡化以利研究,變成以下的樣子:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="../js/jquery.js" type="text/javascript"></script>
    <script src="../js/jquery.blockUI.js" type="text/javascript"></script>
    <script type="text/javascript">
        function ShowIFrame(url) {
            var frmHtml = 
            "<iframe style='width: 100%; height:100%;' src='" + url + "'></iframe>";
            $.blockUI({
                css: { width: '200px', height: '200px' },
                message: frmHtml
            });
        }
        $(function() {
            $("#btnShow").click(function() {
                ShowIFrame(location.href + "?x=2");
            });
            $("#btnClose").click(function() {
                parent.eval("$.unblockUI();");
            });
            if (parent.window != window)
                $("#btnShow").hide();
            else {
                $("#btnClose").hide();
                $("#ta").hide();
            }
 
        });
    </script>
</head>
<body>
<input type=button value='Open SubWin' id="btnShow"/>
<input type=button value='Close SubWin' id="btnClose"/>
<textarea id="ta"></textarea>
</body>
</html>

一開始我寫成ShowIFrame(location.href),結果遇上了IE的IFrame遞迴防呆而失效。說來好笑,這個意外讓我因禍得福,在研究為什麼IFrame裡一直是一片空白的過程中,我用IE8 Dev Tools在空白頁的HTML Source中看到一個可疑的註記!

<META content=WIMRCAXYME name=SKYPE_FRAMEID>

Skype? 我的網頁被Add-on加料了! 會不會TextArea的問題也與Add-on有關? 要驗證這個問題最快的方法就是開啟Accessories/System Tools/Internet Explorer (No Add-ons),在沒有Add-on的狀態下開啟IE,再試了一次問題網頁,欄位無法輸入的症狀不藥而瘉。如此,便可確定問題出在Add-on身上。

很快地找到Skype Add-on,予以停用,苦惱數小時的TextArea失效問題迎刃而解。

換句話說,在本次事件中,IE無罪,問題出在Add-on上;若沒有李組長明察秋毫(遠目),IE恐怕會承受這不白之冤。不過我想,IE此刻的心情應該像被罵慣了的何大人,山西布政司放的屁算他頭上也懶得辯解吧... (話雖如此,IE常跟其他瀏覽器行為不同,還是讓我很想揍它)

原本提供擴充應用空間的Add-on設計美意,隨著各家廠商開發出五花八門的外掛,安裝在各式各樣的環境組合中,常演變出難以預期的結果。依微軟自己的統計,有很大的比例,IE的Crash主因常出在外掛上,而非IE本體,這也是為什麼程式集中會特別提供一個IE無外掛執行模式的原因。

因此,大家未來在遇到IE有光怪陸離行為時,記得先用無外掛模式執行一次,先排除Add-on是元凶的可能性,再對IE爆粗口繼續追查,應可事半功倍。

Posted 29 June 2009 09:11 AMJeffrey | 5 comment(s)
Filed under:
瀏覽器的IFrame無窮迴圈防呆

在射茶包的過程中,發現了一個有趣的瀏覽器行為。

程式碼如下,按下Button會在IFrame元素中開啟目前所在網頁。會寫成這種架構是打算讓一個網頁同時扮種兩種角色,不必為了一個小測試搞出兩個HTML檔案來。實際的測試中,我用if (parent != window)判別網頁是否在IFrame中被開啟,執行不同的功能。這裡只為了突顯瀏覽器的行為特性,我把程式碼簡化到最少。

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe id="f" src=""></iframe><br />
<input type="button" value="showFrame" 
onclick="document.getElementById('f').src=location.href;" />
</body>
</html>

我本來預期按下Button後,IFrame中會出現同一個網頁,結果不然!

使用IE8進行測試,按下Button後,啥事也沒發生,IFrame中空白一片,由網頁屬性發現它仍維持about:blank,也就是src並未被改變。如果把src設定改為http://www.google.com http://www.bing.com(身為MVP,偶爾也要從事一下政令宣導莒光教學咩)則行為正常。看來,問題出在location.href。接著我把location.href改成httq://localhost/lab/recursive.htm,依然無效,但再改成recursive.htm?x=1,則可以順利開啟。

經過推敲,我覺得這是一種安全機制,防止網頁內嵌自己,內嵌那一分又再內嵌了自己,形成無窮迴圈會吃光資源。打個比喻,如果將DV的即時影像輸出到電視上,再用DV去拍電視,畫面就會變成一層包一層,層層相包無窮無盡的電視框。還想像不出來的人,我們請基努李維親自示範一下類似的效果。

就像程式的遞迴呼叫Recursive有相對的防呆,瀏覽器也要設法防止這種內嵌無窮迴圈發生! 好奇心起,用各家瀏覽器做了一下測試,發現有三種結果:

IE、Opera: 完全不允許內嵌自己,iframe.src = location.href 無反應。

Chrome、Safari: 只能呼叫一層,內嵌的那一層便不再允許內嵌自己。

Firefox: 會出現錯誤訊息--uncaught exception: [Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIDOMHTMLIFrameElement.src]" nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: httq://localhost/Lab/Recursive.htm :: onclick :: line 1" data: no]

以上是我的心得報告。

Posted 29 June 2009 01:30 AMJeffrey | 6 comment(s)
Filed under: ,

搜尋

Go

<June 2009>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication