MozTW 討論區

各項 Mozilla 相關軟體與技術討論
現在的時間是 2025-08-05, 04:02

所有顯示的時間為 UTC + 8 小時





發表新文章 回覆主題  [ 22 篇文章 ]  前往頁數 12  下一頁
發表人 內容
 文章主題 : javascript 計數器
文章發表於 : 2007-04-13, 16:59 
離線

註冊時間: 2006-03-28, 10:27
文章: 26
請問一下,我用javascript 寫了一個計數器,在IE可以正常運作,但是firefox卻不能,不知為什麼?以下是我寫的程式:

代碼:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>無標題文件</title>
<script language="javascript">


function startClock(){
   var time = new Date();
   var hours = time.getHours() + ":";
   var minutes = time.getMinutes() + ":";
   var seconds = time.getSeconds();
   show.innerHTML = hours + minutes + seconds;
   timer = setTimeout("startClock()",5000);
}
</script>
</head>
<body onload="startClock()">
<body>
<div id="show"></div>   
</body>
</html>


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-13, 17:53 
改成:
代碼:
var show = document.getElementById("show");
show.innerHTML ...


但是原來的程式碼可能造成 memory leak,
建議修改如下:
代碼:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
<title>無標題文件</title>
<script language="javascript">

var tConfig = {
   timer:null,
   now:null,
   show:null
}

function startClock(){
   tConfig.now = new Date();
   tConfig.show = document.getElementById("show");
   tConfig.show.innerHTML = tConfig.now.getHours() + ":" + tConfig.now.getMinutes() + ":" + tConfig.now.getSeconds();
   if(tConfig.timer) clearTimeout(tConfig.timer);
   tConfig.timer = setTimeout("startClock()",1000);
   return false;
}
</script>
</head>
<body onload="startClock()">
<body>
<div id="show"></div>   
</body>
</html>


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-13, 18:36 
離線

註冊時間: 2006-03-28, 10:27
文章: 26
回來如此,謝謝訪客的回答。 :D

另外,有沒有人可以推薦一下javascript的書,要firefox和ie都可正常執行的。

再次感謝。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-13, 18:58 
離線

註冊時間: 2004-08-30, 11:30
文章: 67
Anonymous 寫:
但是原來的程式碼可能造成 memory leak,


想請教一下
會造成 leak 的原理是...?
我自己也常這樣寫...@@a


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-TW; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-14, 16:23 
BabySatan 寫:
Anonymous 寫:
但是原來的程式碼可能造成 memory leak,


想請教一下
會造成 leak 的原理是...?
我自己也常這樣寫...@@a


1.可能造成 pending timer
2.遞迴呼叫函數可能未「正常結束」
...

簡單的測試:
1.開啟瀏覽器清除 cookies & cache
2.只開啟原程式碼或修改後的版本
兩者的差異為前者會造成瀏覽器使用的記憶體持續增加,
修改後的版本則無此現象。

若瀏覽器的 javascript 引擎,「回收」做的夠好,理論上此種現象應會降至最低。但是,由程式自行處理,是建議的「習慣」。

此例影響並不十分明顯,若函數中有較複雜的處理時,瀏覽器很容易被「餵飽」甚至「脹死」。如果通篇 html 中盡是相同的「自生自滅」scripts,比較老實的瀏覽器,就可能立即「暴斃」。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-14, 16:30 
flyzc 寫:
回來如此,謝謝訪客的回答。 :D

另外,有沒有人可以推薦一下javascript的書,要firefox和ie都可正常執行的。

再次感謝。


一般坊間書籍,多數以 IE 為範例平台,容易養成不良習慣,或相互抄襲,參考價值不高。
這裡資訊豐富,適合入門參考。
http://www.w3schools.com/js/default.asp


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-15, 23:06 
離線

註冊時間: 2004-08-30, 11:30
文章: 67
Anonymous 寫:
1.可能造成 pending timer
2.遞迴呼叫函數可能未「正常結束」
...

簡單的測試:
1.開啟瀏覽器清除 cookies & cache
2.只開啟原程式碼或修改後的版本
兩者的差異為前者會造成瀏覽器使用的記憶體持續增加,
修改後的版本則無此現象。

若瀏覽器的 javascript 引擎,「回收」做的夠好,理論上此種現象應會降至最低。但是,由程式自行處理,是建議的「習慣」。

此例影響並不十分明顯,若函數中有較複雜的處理時,瀏覽器很容易被「餵飽」甚至「脹死」。如果通篇 html 中盡是相同的「自生自滅」scripts,比較老實的瀏覽器,就可能立即「暴斃」。


唔...真是意外
你說的這個我懂
但沒想到會是 recursive 的問題
之前曾經為了測試 setTimeout() 是否會造成 recursive 而寫了一段小程式:
代碼:
var c='';
function f()
{
   if(c && c.length>=10)
   {
      alert(c);
      return;
   }
   c=c+'a';
   setTimeout('f()',1000);
   c=c+'b';
}
f();

照理說
如果 setTimeout() 會造成 recursive 的話
alert() 所顯示的訊息應該是 aaaaabbbbb
但是在這個例子中卻是 ababababab
也就是說看起來 setTimeout() 並不會造成 recursive
而是類似 do-loop 加上 sleep() 的效果(註)

但在看過 anonymous 修改了原 po 的程式碼後
我把我自己以前寫的小時鐘程式拿來修改並測試
發現真的如 anonymous 所說
在修改前, stack 似乎沒有釋放
雖然速度不快,但記憶體使用量的確在緩慢攀升
但在修改變數的 scope 後,記憶體使用量變成完全不會上升

所以說
加上了 setTimeout() 的 function
他的原理只不過相當於是在 function 結束前
依據 setTimeout() 設定的時間加上個 sleep()
並把 setTimeout() 要呼叫的 function 放到 sleep() 之後囉?
以我上面這段 code 為例,就變成:
代碼:
var c='';
function f()
{
   if(c && c.length>=10)
   {
      alert(c);
      return;
   }
   c=c+'a';
   c=c+'b';
   sleep(1000);
   f();
}
f();

是類似這樣嗎?

註:為了便於理解及討論
  文章內容中所提到的 sleep() 皆為 pseudo code
  JavaScript 中並無提供此 function / method


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-TW; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-16, 09:22 
離線
[網站管理員]
頭像

註冊時間: 2004-09-27, 09:24
文章: 1685
也可以 document.getElementById("show").innerHTML = '...'

_________________
korp + korp 中文站(沒精神更新)


回頂端
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-16, 15:09 
BabySatan 寫:
之前曾經為了測試 setTimeout() 是否會造成 recursive 而寫了一段小程式:


1.在函數中呼叫函數本身即已構成「遞迴」呼叫。

2.原本函數中「宣告使用」的局域變數,應在函數結束後釋放。
可是這樣的遞迴呼叫,明顯致使 javascript 引擎未能 clean-up 因遞迴呼叫所產生的「記憶體殘留」。

3.照說類似此例的應用,是不該使用 setTimeout() 而應以 setInterval 取代之。

4.setTimeout() 與 setInterval() 這兩個函數經常會被「不當」使用,此例即為典型。

5.第一個改版只是將「損害」降低,以下是建議的寫法:
代碼:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function showClock(){
   var now = new Date();
   var output = now.getHours() + ":";
   output += now.getMinutes() + ":";
   output += now.getSeconds();
   var show = document.getElementById("show").innerHTML = output;
   return false;
}
</script>
</head>
<body  onunload="if(showInterval) clearInterval(shoInterval);">
<script type="text/javascript">
   var showInterval = setInterval("showClock()", 1000);
</script>
<body>
<div id="show"></div>   
</body>
</html>


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-16, 20:20 
離線
頭像

註冊時間: 2005-02-24, 19:15
文章: 1037
來自: Taiwan
Anonymous 寫:
1.在函數中呼叫函數本身即已構成「遞迴」呼叫。
2.原本函數中「宣告使用」的局域變數,應在函數結束後釋放。
可是這樣的遞迴呼叫,明顯致使 javascript 引擎未能 clean-up 因遞迴呼叫所產生的「記憶體殘留」。
3.照說類似此例的應用,是不該使用 setTimeout() 而應以 setInterval 取代之。
4.setTimeout() 與 setInterval() 這兩個函數經常會被「不當」使用,此例即為典型。
5.第一個改版只是將「損害」降低,以下是建議的寫法:
代碼:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function showClock(){
   var now = new Date();
   var output = now.getHours() + ":";
   output += now.getMinutes() + ":";
   output += now.getSeconds();
   var show = document.getElementById("show").innerHTML = output;
   return false;
}
</script>
</head>
<body  onunload="if(showInterval) clearInterval(shoInterval);">
<script type="text/javascript">
   var showInterval = setInterval("showClock()", 1000);
</script>
<body>
<div id="show"></div>   
</body>
</html>

...
代碼:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var showInterval = null;
function showClock(){
   var now = new Date();
   var output = now.getHours() + ":";
   output += now.getMinutes() + ":";
   output += now.getSeconds();
   var show = document.getElementById("show").innerHTML = output;
   return false;
}
function actionClock() {
  showInterval = setInterval("showClock()", 1000);
}
function clearClock() {
  if(showInterval != null) clearInterval(shoInterval);
}
window.addEventListener("load", actionClock, false);
window.addEventListener("unload", clearClock, false);
</script>
</head>
<body>
<div id="show"></div>   
</body>
</html>

_________________
Amauds's Firefox
曾經妳以為最可靠的依賴;其實從未曾真實的存在過。
圖檔圖檔


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
 個人資料  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-17, 14:01 
Amauds 寫:
...
window.addEventListener("load", actionClock, false);
window.addEventListener("unload", clearClock, false);
...

如果在非使用 setInterval () 情況下,像是以自訂函數處理類似應用,建立「event listener」確屬高級技巧。

幸運的是, setInerval() 正是使用「建立 event listener」的方法,再加個 listerner 不免有畫蛇添足之疑。
而clearInterval() 則意在釋放 listener,更無須再為 clearInterval() 建立一個 listener。

一般程式員常無法適切辨別何時該使用 setTimeout() 或 setInterval() ,
也不敢放手使用 setInterva(),而常以 setTimeout() 取代之。
甚至,許多熟手也視 setInterval() 為「邪魔」,新手通常則敬而遠之。
的確,若未能正確認識 setInterval() 之前,奉勸還是少碰微妙。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-17, 16:02 
Anonymous 寫:
如果在非使用 setInterval () 情況下,像是以自訂函數處理類似應用,建立「event listener」確屬高級技巧。
幸運的是, setInerval() 正是使用「建立 event listener」的方法,再加個 listerner 不免有畫蛇添足之疑。
而clearInterval() 則意在釋放 listener,更無須再為 clearInterval() 建立一個 listener。

不太清楚是否同一人回覆,先前的 code 中,
clearInterval 寫在 body 標籤中,
你所指的「無須再為 clearInterval() 建立一個 listener」
能否請你說得更明白一些?
Anonymous 寫:
一般程式員常無法適切辨別何時該使用 setTimeout() 或 setInterval() ,
也不敢放手使用 setInterva(),而常以 setTimeout() 取代之。
甚至,許多熟手也視 setInterval() 為「邪魔」,新手通常則敬而遠之。
的確,若未能正確認識 setInterval() 之前,奉勸還是少碰微妙。

雖然不太清楚什麼是正確的用法,
不過個人倒是蠻愛用 setInterval() 的。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-17, 16:12 
Anonymous 寫:
setInerval() 正是使用「建立 event listener」的方法,再加個 listerner 不免有畫蛇添足之疑。
而clearInterval() 則意在釋放 listener,更無須再為 clearInterval() 建立一個 listener。

喔!突然想到了,這是否意謂著,
要使用 setInterval() 時一定得像前述 code 一般,
硬寫在 body 區段中,
而 clearInterval() 也一定得硬寫在 body 標籤中。
如此得以避免畫蛇添足。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-17, 18:27 
訪客(amauds) 寫:
Anonymous 寫:
setInerval() 正是使用「建立 event listener」的方法,再加個 listerner 不免有畫蛇添足之疑。
而clearInterval() 則意在釋放 listener,更無須再為 clearInterval() 建立一個 listener。

喔!突然想到了,這是否意謂著,
要使用 setInterval() 時一定得像前述 code 一般,
硬寫在 body 區段中,
而 clearInterval() 也一定得硬寫在 body 標籤中。
如此得以避免畫蛇添足。


那也不盡然,amauds 的寫法是多點「彈性」,有高手風格。


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
  
引用回覆  
 文章主題 :
文章發表於 : 2007-04-17, 21:03 
離線
頭像

註冊時間: 2005-02-24, 19:15
文章: 1037
來自: Taiwan
Anonymous 寫:
那也不盡然,amauds 的寫法是多點「彈性」,有高手風格。

有沒有彈性我是不曉得,
只是有時多組計數器同時運作時,
我都是集中在同一處來控管。
其實 setTimeout 也是可以一直呼叫而不會造成 memory leak,
只要設計函數時將釋放功能寫入就好了。

代碼:
var myTimeout = null;
function a() {
  if(myTimeout != null) { clearTimeout(myTimeout); myTimeout = null; }
  .....
  .....
  myTimeout = setTimeout("a()",1000);
}

不過得小心如果間隔時間太短所可能引發的例外。

_________________
Amauds's Firefox
曾經妳以為最可靠的依賴;其實從未曾真實的存在過。
圖檔圖檔


回頂端
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
 個人資料  
引用回覆  
顯示文章 :  排序  
發表新文章 回覆主題  [ 22 篇文章 ]  前往頁數 12  下一頁

所有顯示的時間為 UTC + 8 小時


誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 3 位訪客


不能 在這個版面發表主題
不能 在這個版面回覆主題
不能 在這個版面編輯您的文章
不能 在這個版面刪除您的文章
不能 在這個版面上傳附加檔案

搜尋:
前往 :  
Powered by phpBB® Forum Software © phpBB Group
正體中文語系由 竹貓星球 維護製作
© moztw.org, Mozilla Foundation
MozTW,Mozilla 台灣社群