2012-06-26 36 views
1

我遵循h5bp建議的模式,將所有腳本文件都拍在頁面底部,保存爲Modernizr使用HTML 5 Boilerplate簡化jQuery代碼

現在,這裏是我在ASP.NET MVC 3中的一些工作。我正在創建對HtmlHelper的擴展來劃分窗體上某些可重用元素/控件的標記。類似於@Html.GiveMeATableDammit()會爲表格生成標記。

我的困境來到這裏。如果生成的標記需要運行一些jQuery來對付它呢?爲了說明這一點,讓我們說,一個jQuery插件功能需要被稱爲對這個表:

@Html.GiveMeATableDammit("a-very-dirty-mouthed-table") 

// 
// will generate customized HTML 
<table id="a-very-dirty-mouthed-table"> 
    <!-- some more stuff --> 
</table> 
<script> 
    // along with customized javascript to match 
    jQuery(function ($) { 
     $('#a-very-dirty-mouthed-table').giveMeSuperPowers(); 
    }); 
</script> 

的問題是,在生成標記點,jQuery的還不存在,因爲jQuery是在底部這一頁。

現在,禁止移動jQuery來<head>的想法,我怎麼能抵擋一個功能,直到頁,jQuery的已經存在的最末端執行?

+0

你不能把JavaScript保存在JavaScript文件中嗎? – powerbuoy

+0

@powerbuoy〜完全不是重點。如果我用''來代替問題中的內聯腳本塊,我仍然會遇到同樣的問題。 –

+0

是的,但是如何在關閉body標籤前添加一個腳本元素(根據html5boilerplate最佳實踐(以及常規最佳實踐(緩存,性能,代碼分離))),並且一個JS文件是所有爲每個模塊/頁面的一部分提供單獨的JS文件。我從來沒有使用ASP.NET MVC,但沒有看到爲什麼這會是一個問題? – powerbuoy

回答

1

除非有一些ASP魔術要做到這一點,一個方法,我所看到的是聲明在你的頁面的<head>數組,push()ready處理程序給他們,然後,在底部(的jQuery)加載,運行它們:

<head>

var handlers = []; 

只要:

handlers.push(function ($) { 
    $('#a-very-dirty-mouthed-table').giveMeSuperPowers(); 
}); 

</body>

<script src="http://code.jquery.com/jquery-1.7.2.js"></script> 
<script> 
    handlers.forEach(function (val) { 
     jQuery(document).ready(val); 
    }); 
</script> 
+0

我確實記得閱讀某些地方的某些東西(最可能是SO),甚至將別名'$(document).ready()'指向'[] .push()'調用。儘管如此,一個好主意。謝謝:) –

+0

找到它了:http://blog.colin-gourlay.com/blog/2012/02/safely-using-ready-before-including-jquery/ –

+0

@RichardNeilIlagan,請參閱我對該帖的歷史回答。 –

1

From my blog關於這個問題:

<head> 
    <script> 
     (function(a){ 
      _q=function(){return a;}; 
      $=function(f){ 
       typeof f==="function" && a.push(arguments); 
       return $; 
      }; 
      jQuery=$.ready=$; 
     }([])); 
    </script> 
</head> 
<body> 
    <div id="main"> 
     <script> 
      $(function() { 
       $("#main").prepend("<p>Heyo!</p>"); 
      }); 
     </script> 
     <div>...more HTML...</div> 
    </div> 
    <script src="/js/jquery.js"></script> 
    <script> 
     (function(i, s, q, l) { 
      for(q = window._q(), l = q.length; i < l;) { 
       $.apply(this, s.call(q[ i++ ])); 
      } 
      window._q = undefined; 
     }(0, Array.prototype.slice)); 
    </script> 
    <script src="/js/scripts.js"></script> 
</body> 

什麼第一<script>確實是通過存儲任何呼叫的參數$.ready其中第一個參數是一個模仿jQuery的ready功能函數轉換爲數組。這個數組對於我們全局作用域的_q方法是私有的,在調用時該方法返回數組。

最後一個內聯<script>通過調用_q()循環訪問數組,然後將最初傳遞給我們的冒名頂替者$.ready的參數應用於實際的$.ready

Sam Saffron大約一年後獨立想出similar method來解決Stack Overflow的相同問題。

迴應Sam的帖子,Colin Gourlay想出了一個甚至more robust method(這可能是矯枉過正)。

+0

很酷,謝謝分享。這絕對是我之前閱讀的文章。 :)是的,我認爲對'.bind('ready',fn)'的支持也有點矯枉過正。 +1 –