2010-11-29 112 views
5

我想統計訪問者在某個頁面上花費多少時間並將其存儲在我的MySQL數據庫中。JS onunload事件不會總是有效

我認爲剛開始的計時器上的window.onload是這樣的:

window.onload= startCount; 
window.onunload= sendCount; 

var b=0; 
var y; 
function startCount() { 
    document.getElementById('livecount').innerHTML=b; 
    b=b+1; 
    y=setTimeout("startCount()",1000); 
} 

和遊客離開後的頁面(window.onunload),我要送的時候通過一個XMLHttpRequest到PHP文件,它會將其存儲在我的數據庫中:

function sendCount() { 
    clearTimeout(y);  
if (window.XMLHttpRequest) 
    {// code for IE7+, Firefox, Chrome, Opera, Safari 
    xmlhttp=new XMLHttpRequest(); 
    } 
else 
    {// code for IE6, IE5 
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
xmlhttp.open("GET","count.php?q="+b,true); 
xmlhttp.send(); 
} 

問題是它並不總是有效。我會說它的工作原理就像我嘗試過10次中的3次。 難道是沒有足夠的時間讓PHP和SQL完全執行?

回答

0

onunload不是一種可靠的方式來跟蹤...好吧,幾乎任何東西。例如 請參閱http://www.google.com/support/forum/p/Google+Analytics/thread?tid=6496cd5d4b627c0e&hl=en

至於解決問題,最好的方法是跟蹤上次用戶在頁面上。例如,每隔一分鐘從客戶端調用跟蹤器。像谷歌分析這樣的分析系統實際上只是假設用戶在最後一頁服務之後離開了。即如果我閱讀頁面然後點擊某個內容,它會刷新計數器。但是如果沒有後續的命中發生,那就意味着我離開了。

+0

OK,我明白了,它甚至不,當你在不同的URL輸入離開頁面的工作:(嘛,怎麼我還能解決我的問題(計數並存儲在時間花費某些頁面)? – LightDark 2010-11-29 19:51:30

4

由於onunload是不可靠的,我會考慮一個AJAX解決方案。我根本就不是這方面的專家,但想到的想法就是每隔一段時間就會對你的櫃檯進行一次平衡。我不會每秒都打你的櫃檯,因爲這似乎過分。

我會多次打破你關心的持續時間,如< 5秒,< 30秒< 1分鐘,< 5分鐘,5+分鐘。

然後我會寫一段JavaScript像這樣:

window.onload = soCounter; 

var iter=0; 
var times=[0,5,30,60,300]; // Your duration choices 

function doCounter() { 

    sendCountPing(times(iter)); 

    iter++; 

    if(iter < times.length) { 
     setTimeout(doCounter, times[iter]*1000); 
    } 
} 

function sendCountPing(dur) { 
    if (window.XMLHttpRequest) 
    { // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp=new XMLHttpRequest(); 
    } 
    else 
    { // code for IE6, IE5 
     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

    xmlhttp.open("GET","count.php?q="+b,true); 
    xmlhttp.send(); 

} 

的訣竅是,每count.php?q=30是被髮送,你需要減去一個從count.php?q=5計數。這不一定是程序化的,它很容易進行後期處理。

爲了澄清,如果你有3人次,一個花3秒,一個花費20秒,一個花費30分鐘後,你會看到下面的罪狀:

0: 3 // 3 people spent at least 0 seconds 
    5: 2 // 2 people spent at least 5 seconds 
30: 1 
60: 1 
300: 1 // 1 person spent at least 5 minutes 

有意義嗎?

+0

非常感謝您的廣泛回答。是的,這是理所當然的,但這不是我想做的事情。我的目標是將所有用戶花費在頁面上的時間所以沒有統計數據是必須的),我想每5秒左右發送一次帶有AJAX的數據庫,但這不是對服務器計算能力的巨大浪費嗎? – LightDark 2010-11-29 22:44:08

+2

正如別處所說,如果這是目標,最好的做法是對輕量級服務器腳本進行30秒鐘的ping處理,ping的頻率取決於你所在站點的類型,但在普通站點上,超過30秒。也許你可以做一個5秒鐘的ping,然後將它減慢到30秒。無論哪種方式,你永遠不會得到一個確切的數字。 – 2010-11-30 19:39:59

1

當onload處理程序運行時,頁面處於被取下的過程中。我不確定你對DOM或其​​他服務的狀態有什麼保證,但是你絕對不能指望異步事件或超時。雖然不是標準的一部分,但大多數(所有?)瀏覽器都提供了一個onbeforeunload鉤子,其工作方式與其他事件處理程序的工作方式大致相同,除了如果您選擇,還可以返回false以取消卸載。

+0

感謝您的回答,我試過oneforeunload,它根本無法使用Chrome:/ – LightDark 2010-11-30 11:07:46

1

您可以按照建議設置一個計時器,它可以隨時運行(幾秒鐘左右),並將信息存儲在cookie(或cookie)中。如果需要執行某些操作而不是將值顯示給用戶,則可以將此信息發送到服務器。因此,不要在每個週期內將其發送到服務器,只要將該信息發送到服務器(例如向用戶顯示他在網站上的各個頁面上花費的所有時間)即可。

0

另一種方法是將數據保存在localStorage/cookie中,並在用戶下次訪問該網站時發送;假設用戶停留或曾經返回到您的網站。

最好用Date() calc而不是setInterval/setTimeout來計算時間。
最好使用addEventListener而不是onload = func

sendPreviousStats(); 
window.addEventListener('load',loadFunc); 
window.addEventListener('unload',leaveFunc); 

function loadFunc() { 
    window.startTime = new Date(); 
} 

function leaveFunc() { 
    var msec = new Date().getTime()-window.startTime.getTime(); 
    var seconds = Math.round(msec/1000); 
    localStorage.setItem('leaveSeconds',seconds); 
} 

function sendPreviousStats() { 
    var duration = localStorage.getItem('leaveSeconds'); 
    if (duration !== null && duration !== undefined) { 
     localStorage.removeItem('leaveSeconds'); 
     sendCountPing(duration); 
    } 
}