MozTW 討論區
https://forum.moztw.org/

開啟網頁當機
https://forum.moztw.org/viewtopic.php?f=2&t=14732
1 頁 (共 1 頁)

發表人:  sandy [ 2006-06-30, 22:41 ]
文章主題 :  開啟網頁當機

When browsing the url "http://www1.payeasy.com.tw/diy/product/basic/index.shtml. The boswser gets no responds.

however, it can work by IE.

發表人:  arphen [ 2006-07-01, 11:43 ]
文章主題 : 

sandy 寫:
When browsing the url "http://www1.payeasy.com.tw/diy/product/basic/index.shtml. The boswser gets no responds.

however, it can work by IE.


問題出在第453行:
代碼:
 setInterval('stay()');


我認為應是作者用錯了,應改用setTimeout()才對:
代碼:
 setTimeout('stay()');


由此也意外地發現一個問題,setInterval()的定義如下:
代碼:
window.setInterval(expression/function, milliseconds)


目前我找得到的資料並未言明milliseconds參數是可省略的,但IE/Firefox/Opera居然都可接受不帶時間參數的寫法,可是三者表現並不相同:

IE 6.0:setInterval('xxx')只執行一次就停掉,這個作法還可以接受。

Opera 9.0:不會執行,我認為這是最安全的作法。

Firefox 1.5.0.4:把setInterval('xxx')當作setInterval('xxx', 0),我認為這個作法最危險。

以下是測試內容:
代碼:
<html>
<head>
  <script>
  function test(){
    var d=document.getElementById('myd');
    if(d) d.innerHTML = Math.random();
  }
  </script>
</head>

<body>

  <div id="myd">

  <script>
  // IE 6: execute just one time
  // Opera 9: don't execute
  // Firefox 1.5: execute as fast as possible repeatedly
  setInterval('test()');

  // IE 6: execute just one time
  // Opera 9: execute as fast as possible repeatedly;
  // Firefox 1.5: same with opera
  setInterval('test()', 0);

  // IE 6: execute every 1ms repeatedly
  // Opera 9: same with IE
  // Firefox 1.5: same with IE
  setInterval('test()', 1);
  </script>

</body>
</html>

發表人:  訪客 [ 2006-07-01, 17:00 ]
文章主題 : 

arphen 寫:
因為它會以等比級數,

理論上,此例不會以等比級數形成無窮迴圈
arphen 寫:
快速形成無數個無窮迴圈

這應屬Fx沒做好防呆措施。
arphen 寫:
迅速地把CPU玩死。

此則作業系統的scheduling缺失。

發表人:  arphen [ 2006-07-01, 18:00 ]
文章主題 : 

Anonymous 寫:
理論上,此例不會以等比級數形成無窮迴圈


代碼:
function xxx(){
  setInterval('xxx', n);
}
setInterval('xxx', n);

第n單位時間,會有2^n個timer會執行xxx(),即:1,2,4,8,16,...
這應是等比數列,非等比級數,在此更正,多謝指教。

發表人:  訪客 [ 2006-07-01, 22:08 ]
文章主題 : 

arphen 寫:
代碼:
function xxx(){
  setInterval('xxx', n);
}
setInterval('xxx', n);


第n單位時間,會有2^n個timer會執行xxx(),即:1,2,4,8,16,...
這應是等比數列,非等比級數,在此更正,多謝指教。

補充說明:
1.1, 2,4,8,16 為一個等比數列,而 1+2+4+8+16 則為一個等比級數。
2.照理如此遞迴方式,應會引發stack overflow
3.你的說明有誤:
若如所言
引言回覆:
Firefox 1.5.0.4:把setInterval('xxx')當作setInterval('xxx', 0)來玩,

豈非 2^n = 2^0,只會執行一次?顯然不合你實測結果。

比較合理的推測是,每毫秒執行一次,亦即:
[code]
function xxx(){
setInterval('xxx',1);
}
setInterval('xxx',1);
[code]
第n單位時間(毫秒),會有2^n個timer會執行xxx()
亦即倍數增加

發表人:  arphen [ 2006-07-01, 23:26 ]
文章主題 : 

Anonymous 寫:
比較合理的推測是,每毫秒執行一次,亦即:
代碼:
function xxx(){
  setInterval('xxx',1);
}
setInterval('xxx',1);

第n單位時間(毫秒),會有2^n個timer會執行xxx()


整理一下:

在Firefox裡使用setInterval('xxx'),效果類似setInterval('xxx',1),幾乎1毫秒就呼叫一次xxx(),而xxx()每執行一次,又會新增一個timer,如此在第n毫秒會有2^n個timer。

依此推算,只要1/10秒的時間,就會產生2^100 = 1267650600228229401496703205376 個timer。

實際上Firefox可能在更短的時間內就被一堆timer給拖住跑不動了。

發表人:  訪客 [ 2006-07-02, 11:46 ]
文章主題 : 

arphen 寫:
sandy 寫:
When browsing the url "http://www1.payeasy.com.tw/diy/product/basic/index.shtml. The boswser gets no responds.

however, it can work by IE.


問題出在第453行:
代碼:
 setInterval('stay()');


我認為應是作者用錯了,應改用setTimeout()才對:
代碼:
 setTimeout('stay()');



關於作者是否用錯了(應該用setTimeout('stay()')?),還是Fx如何處理未帶入足夠的參數的setInterval有誤?不便妄加臆測。
但是,事實上將 stay() 中的 document.all 改成 document.getElementById 之後,CPU looping 的現象不再,看起來結果呈現正常。

代碼:
function stay(){
 var ny;
 ny=y+document.body.scrollTop;
 distance=ny-div_y;
 if(div_y!=ny){div_y+=(distance/30);}
 document.getElementById['div1'].style.top=div_y;  // <---right如果不要顯示右邊浮水印請在最前面加上//  若要顯示則不加//
    //document.getElementById['div2'].style.top=div_y;  // <---left如果不要顯示左邊浮水印請在最前面加上//  若要顯示則不加//
 setInterval('stay()');
}

發表人:  arphen [ 2006-07-02, 12:13 ]
文章主題 : 

有人提過類似的問題:
https://bugzilla.mozilla.org/show_bug.cgi?id=261633

發表人:  arphen [ 2006-07-02, 12:28 ]
文章主題 : 

Anonymous 寫:
關於作者是否用錯了(應該用setTimeout('stay()')?),還是Fx如何處理未帶入足夠的參數的setInterval有誤?不便妄加臆測。
但是,事實上將 stay() 中的 document.all 改成 document.getElementById 之後,CPU looping 的現象不再,看起來結果呈現正常。
代碼:
function stay(){
 var ny;
 ny=y+document.body.scrollTop;
 distance=ny-div_y;
 if(div_y!=ny){div_y+=(distance/30);}
 document.getElementById['div1'].style.top=div_y;  // <---right如果不要顯示右邊浮水印請在最前面加上//  若要顯示則不加//
    //document.getElementById['div2'].style.top=div_y;  // <---left如果不要顯示左邊浮水印請在最前面加上//  若要顯示則不加//
 setInterval('stay()');
}



這樣改不對,getElementById是函數,不可當陣列來用,用javascript console看就知了。
代碼:
Error: document.getElementById.div1 has no properties
Line: 451

因為執行到這一行就錯了,所以沒有機會跑到setInterval('stay()'),當然不會有停止反應的情形,使你誤認為正常。

發表人:  訪客 [ 2006-07-02, 15:30 ]
文章主題 : 

arphen 寫:
Anonymous 寫:
關於作者是否用錯了(應該用setTimeout('stay()')?),還是Fx如何處理未帶入足夠的參數的setInterval有誤?不便妄加臆測。
但是,事實上將 stay() 中的 document.all 改成 document.getElementById 之後,CPU looping 的現象不再,看起來結果呈現正常。
代碼:
function stay(){
 var ny;
 ny=y+document.body.scrollTop;
 distance=ny-div_y;
 if(div_y!=ny){div_y+=(distance/30);}
 document.getElementById['div1'].style.top=div_y;  // <---right如果不要顯示右邊浮水印請在最前面加上//  若要顯示則不加//
    //document.getElementById['div2'].style.top=div_y;  // <---left如果不要顯示左邊浮水印請在最前面加上//  若要顯示則不加//
 setInterval('stay()');
}



這樣改不對,getElementById是函數,不可當陣列來用,用javascript console看就知了。
代碼:
Error: document.getElementById.div1 has no properties
Line: 451

因為執行到這一行就錯了,所以沒有機會跑到setInterval('stay()'),當然不會有停止反應的情形,使你誤認為正常。


你是對的,那是一個很明顯的錯誤;應該是document.getElementById('div1')。所以,CPU 依舊 looping。
不過在我的機器始終維持50%的CPU佔用率,看來XP的 scheduling 發揮作用。

發表人:  訪客 [ 2006-07-02, 16:46 ]
文章主題 : 

所以,stay()應該改成:
代碼:
function stay(){
 var ny;
 ny=y+document.body.scrollTop;
 distance=ny-div_y;
 if(div_y!=ny){div_y+=(distance/30);}
document.getElementById('div1').style.top=div_y;  // <---right如果不要顯示右邊浮水印請在最前面加上//  若要顯示則不加//
//document.getElementById('div2').style.top=div_y;  // <---left如果不要顯示左邊浮水印請在最前面加上//  若要顯示則不加//
 setTimeout('stay()');
}

發表人:  arphen [ 2006-07-03, 09:58 ]
文章主題 : 

Anonymous 寫:
你是對的,那是一個很明顯的錯誤;應該是document.getElementById('div1')。所以,CPU 依舊 looping。
不過在我的機器始終維持50%的CPU佔用率,看來XP的 scheduling 發揮作用。


雖然如此,但Firefox還是掛了。
圖檔

附加檔案:
stay.gif [17.5 KiB]
被下載 372 次

發表人:  arphen [ 2006-07-03, 10:13 ]
文章主題 : 

其實stay()做的事很單純-將右方的廣告欄(div1)保持在頁中。為避免捲頁後廣告欄跑掉,必須持續呼叫stay()來檢查及調整div1位置。

須持續呼叫函數的情況,用setInterval()只需叫用一次:
代碼:
<html>
<head>
  <script>
  function test(){
    var d=document.getElementById('myd');
    if(d) d.innerHTML = Math.random();
  }
  </script>
</head>

<body onload="setInterval('test()',1)">
  <div id="myd">
</body>
</html>


用setTimeout()則必須持續呼叫-在test()內再次叫用,不斷loop:
代碼:
<html>
<head>
  <script>
  function test(){
    var d=document.getElementById('myd');
    if(d) d.innerHTML = Math.random();
    setTimeout('test()',1);
  }
  </script>
</head>

<body onload="setTimeout('test()',1)">
  <div id="myd">
</body>
</html>


另外,因為各家瀏覽器對省略時間參數的作法未必相同,最好明確指定時間參數比較保險。

發表人:  sandy [ 2006-07-10, 23:32 ]
文章主題 :  firefox能快點解決掉這些問題

謝有人解釋了那麼多, 基本上我對程式碼完全不懂, 因為剛開始用firefox, 卻沒想到它會有這種問題,另外我在其它網頁上也發現有些網頁開不起來(在ie才行), 只希望firefox能快點解決掉這些問題, 不然我想還是會有人會回去去用IE的.

p.s 我還是願意給firefox一點時間.

發表人:  arphen [ 2006-07-20, 22:01 ]
文章主題 : 

sandy 寫:
When browsing the url "http://www1.payeasy.com.tw/diy/product/basic/index.shtml. The boswser gets no responds.

however, it can work by IE.


真是天下文章一大抄,這個站用了一模一樣的東西!
http://shopping.windmill.com.tw/

1 頁 (共 1 頁) 所有顯示的時間為 UTC + 8 小時
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/