2010-09-02 100 views
28

我的頁面有一些JavaScript需要在頁面加載時運行。所述JavaScript需要找到ServerControl的客戶端組件,它使用$ find()。

當然,如果我將代碼直接發送到頁面上,它將在頁面正在讀取時執行,並且失敗,因爲它依賴的任何內容都尚未初始化。

如果我把我的代碼放到pageLoad()函數中,它運行得很好,因爲asp.net自動爲任何名爲pageLoad()的函數連接一個onload處理函數。問題是我真的不喜歡pageLoad()解決方案 - 主要是因爲它是一個單一的全球名稱。如果我使用pageLoad()提交了一些代碼,我只知道其他一些程序員將複製該方法,某處不恰當,我們將最終創建一個包含兩個或更多不同pageLoad()函數的頁面,並且結果將會是一連串的神祕錯誤,這些錯誤將會永遠追蹤。

所以,我把我的代碼裏面的一個匿名函數傳遞給jquery的$(document).ready()。這會失敗,因爲它在ServerControl的客戶端組件存在之前運行。

因此,我把我的代碼放在一個匿名函數中,由Sys.Application.add_load()傳遞給它。這也失敗了,因爲Sys是未定義的。所以我最終決定把我的代碼放入Sys.Application.add_load()中,然後把它放在$(document).ready()調用的函數中。這種方法很有效,但它的效果與pageLoad()幾乎一樣。

<script type="text/javascript"> 
    $(document).ready(function(){ 
     Sys.Application.add_load(function(){ 
      var component = $find(<clientid>); 
      if (component) { <do something> } 
     }); 
    }); 
</script> 

必須有更好的方式來處理這個問題。

任何想法?

回答

20

如果你有在控制代碼隱藏,你可以註冊JavaScript來通過像在啓動時運行:您作爲組件已通過Sys.Application.add_init加載

this.Page.ClientScript.RegisterStartupScript(
    this.GetType(), 
    "StartupScript", 
    "Sys.Application.add_load(function() { functioncall(); });", 
    true); 

只要()你應該沒問題...

+0

這似乎爲我們工作。 – 2010-09-17 20:49:34

3

我相信,如果您在腳本塊上添加(或移動)ScriptManager控件,則無需將其包裝在jQuery的$(document).ready()函數中。通過這樣做顯然Sys將作爲使用ScriptManager:

注入大量的JavaScript的 的 ScriptManager控件在頁面位於 的確切位置。 [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]

然而,這種解決方案可能還是給你燒心,因爲它肯定不會是顯而易見的任何不知情的開發商什麼的ScriptManager實際上是提供在這裏。

在ScriptManager中添加腳本引用的另一種方法(請參閱上文鏈接文章中討論的「更好的方法」)並不適合我,因爲我不是整個ScriptManager方法的忠實粉絲。

5

我想爲那些試圖構建外部庫並試圖在.NET中儘可能遵循不顯眼的javascript思維模式的人提供一種替代方案。

pageLoad是一種很好的方法,可以自動連接AJAX事件,這些事件應該在每個頁面加載時觸發(無論該加載來自後退按鈕導航到此頁面,向前導航到頁面,AJAX回調,標準頁面加載等),並且由於您不必擔心等待ScriptManager存在於DOM中,並且它的命名方式非常有意義,因此絕大多數情況下(pageLoad vs. body.onload是輕微的對於非.NET編碼人員來說很混亂,但對於一個.NET人來說,pageLoad會觸發每一頁加載,包括回調之後,因爲服務器端Page_Load的行爲是相同的)。話雖如此,你的擔心是好的 - 你不想在給定的頁面上有兩個pageLoad實例,因爲它會中斷。這裏有一個直接的javascript解決方案,它對開發人員來說都是安全的,它允許使用pageLoad,不擔心DOM存在,確保沒有代碼衝突,並且對我們來說奇妙的作品。

在你的主JavaScript庫,定義頁面加載,以及一個輔助功能:

if (!pageLoad) { var pageLoad = function (sender, args) {}; }; 
if (!mylibrarynamespace) {var mylibrarynamespace = {};}; 
if (!mylibrarynamespace.registerStartupScript) mylibrarynamespace.registerStartupScript = function (fn) { 
    /* create local pointer for added function */ 
    var f = fn; 

    /* create pointer to existing pageLoad function */ 
    var pLoad = pageLoad; 

    /* add new function pointer to pageLoad by creating new anonymous function (search Google for "javascript enclosures" for why pl and f will persist with this newly defined anonymous function) */ 
    pageLoad = function (sender, args) { 
    pLoad(sender,args); 
    f(sender, args); 
    } 
} 

然後,在你的客戶端代碼的任何地方使用它,只要做到以下幾點:

mylibrarynamespace.registerStartupScript(
    function (sender, args){ 
     /* do my AJAX always enabled startup code logic here*/ 
    } 
); 

爲了使功能變得更加簡單,我建議傳入的匿名函數在該頁或控件的庫子集中調用一個函數,以便只需將庫的函數聲明(在文件中或動態運行時)更改爲改變pag的方式eLoad適用於您網站的特定部分。

+0

在javascript中編寫你的頭幾行是這樣的:var pageload = pageload ||函數(sender,args){}; – Goyuix 2012-10-12 20:10:49

0

嘗試使用ScriptManager註冊客戶端腳本塊,但給每個附加函數調用一個唯一的標題,尤其是如果它具有唯一參數(如果使用的是相同的函數但具有不同的參數值)。如果您使用add_load技術,則只能在頁面加載不是回發時才使用,即只在頁面刷新或頁面加載後沒有回發後調用一次。這個GetType(),「唯一標題」,「alert('quick test');」,true);

相關問題