2012-01-09 69 views
12

我知道這可能聽起來很奇怪,但我需要知道頁面中是否有任何活動/正在運行的JavaScript。檢測是否有任何JavaScript函數正在運行

我處於這種情況,在頁面上的所有內容都被渲染並且所有其他腳本完成後,我必須運行我的javascript/jquery代碼。

是否有可能檢測到這一點?

編輯:

謝謝大家的答案。不幸的是,我無法找到解決方案,因爲我無法完全控制頁面上發生的事情。

甚至,我能夠把我的JavaScript放在頁面的末尾,我認爲它不會再解決。原因是當頁面呈現一個函數被觸發時,它會調用其他函數並且他們調用其他函數等等。因此,一些數據不正確,這就是爲什麼我需要運行我的代碼來糾正它。

我使用的setTimeout 2秒,以確保我的代碼將被最後執行,但是這是醜陋的...

所以,謝謝大家,但是這是更問題的系統,而不是JS。

+0

什麼瀏覽器運行? – Boomer 2012-01-09 14:43:07

+0

@Boomer我需要做這個跨瀏覽器。 – gotqn 2012-01-09 14:44:38

+0

這可能有所幫助:http://stackoverflow.com/questions/3283576/how-to-trace-javascript-events-stack-trace – 2012-01-09 14:45:46

回答

12

上的Web瀏覽器的JavaScript是單線程(禁止使用的web workers),所以如果你的JavaScript代碼運行,根據定義沒有其他的JavaScript代碼運行。*

爲了儘量保證你的腳本發生之後頁面上的所有其他JavaScript已經被下載和評估,已發生的所有渲染之後,提出了一些建議:

  • 將腳本標記爲您的代碼在文件的最後。
  • 在標籤上使用defer and async屬性(它們會被不支持它們的瀏覽器忽略,但目標是儘可能地使您的最後)。
  • 通過DOM2風格的連接鉤住windowload事件(例如,在具有標準支持的瀏覽器上爲addEventListener,在較舊的IE版本上爲attachEvent)。
  • load事件中,安排您的代碼在setTimeout延遲0ms後運行(它不會真的爲零,它會稍微長一些)。

所以,script標籤:

<script async defer src="yourfile.js"></script> 

...和yourfile.js

(function() { 
    if (window.addEventListener) { 
     window.addEventListener("load", loadHandler, false); 
    } 
    else if (window.attachEvent) { 
     window.attachEvent("onload", loadHandler); 
    } 
    else { 
     window.onload = loadHandler; // Or you may want to leave this off and just not support REALLY old browsers 
    } 

    function loadHandler() { 
     setTimeout(doMyStuff, 0); 
    } 

    function doMyStuff() { 
     // Your stuff here. All images in the original markup are guaranteed 
     // to have been loaded (or failed) by the `load` event, and you know 
     // that other handlers for the `load` event have now been fired since 
     // we yielded back from our `load` handler 
    } 
})(); 

這並不意味着其他代碼不會已經安排自己以後運行(通過setTimeout,例如,就像我們上面做的,但有一個更長的超時),但。

所以你可以做一些事情來做最後的嘗試,但我不相信有任何方法可以在沒有完全控制頁面和腳本運行的情況下實際保證它(我從問題是你沒有)。


(*有一些邊緣的情況下螺紋可以懸浮在一個地方,然後允許其他代碼到在另一個地方運行[例如,當一個AJAX調用完成而被示出的alert消息有些瀏覽器會觸發ajax處理程序,即使0123'上的另一個函數正在等待解除],但它們是邊緣情況,並且仍然只有一件事情正在一次完成。)

2

沒有確切的方法這樣做是因爲您無法真正瞭解其他腳本已計劃自己運行的最新版本。你將不得不決定你想要的目標。

  1. 您可以嘗試在加載DOM時可能正在運行的任何其他操作之後運行腳本。
  2. 您可以嘗試在頁面完全加載(包括圖像)時可能正在運行的任何其他內容之後運行腳本。

沒有可靠的,跨瀏覽器的方式來知道這些事件,頁面中的腳本正在使用。

無論是哪種情況,您都會勾選相應的事件,然後使用setTimeout()嘗試在觀察這些事件的任何其他事件之後運行腳本。例如,如果您決定等到整個頁面(包括圖像)被加載,並且想要讓您的腳本在等待相同事件的其他任何事情之後運行,那麼您應該這樣做:

window.addEventListener("load", function() { 
    setTimeout(function() { 
     // put your code here 
    }, 1); 
}, false); 

對於早期版本的IE,您將不得不使用attachEvent()

使用此方法時,您不必擔心腳本在頁面中相對於頁面中的其他腳本加載的位置,因爲這會安排腳本在特定事件發生後的特定時間運行。

1

對於遲到的回覆感到抱歉。

我已經找到了解決辦法:

var loading_var = 0; 

    function f1() { 
     loading_var++; 
     /*code to be executed*/ 
     onready(); 
    } 

    function f2() { 
     loading_var++; 
     /*The same for each function in your code*/ 
     onready(); 
    } 

    function onready() { 
     loading_var--; 
     if(loading_var == 0) { 
     /*Means all functions have finished executing !*/ 
     } 
    } 

我用這個在JavaScript遊戲,以防止用戶因爲功能仍在執行與遊戲互動。

相關問題