【问题标题】:managing common jquery script files in asp.net project管理 asp.net 项目中的常用 jquery 脚本文件
【发布时间】:2013-09-18 11:09:38
【问题描述】:

我正在寻找在 asp.net 项目中使用 javascript/jQuery sn-ps 的最佳实践。我知道最好将所有脚本放在一个单独的文件中,而不是内联。那挺好的。将这些脚本函数移动到一个公共文件很容易(可能是几个不同的,以平衡为小函数加载单个大文件的性能)。

但是有一些jQuery 需要在每个页面上的document.Ready 上发生。我将如何将此移动到一个常见的.js 文件中?我想避免每页一个脚本,因为它太多了。

例如,假设 Page1 需要在加载时操作几个单选按钮,并且内联了以下脚本。 (仅作说明)

<script>
$(document).ready(function() {
 //check checkboxes
  if(true)
   call function1();
});
</script>

与 Page2 相同,但对于某些其他条件,调用不同的函数 function2

我可以将函数 1 和函数 2 移动到一个通用的 .js 文件中,但是 document ready 部分呢?那应该保持内联吗?我假设是这样,否则我不确定common.js 将如何区分不同页面的document.ready

那么它是否违背了没有内联javascript 的目的?如果有人能对此有所了解,不胜感激。

我做了一些研究,但可能是由于关键字不正确,到目前为止我还没有找到任何符合相同思路的好的信息。不显眼的 JavaScript 在下面的 cmets 中似乎很有希望。

【问题讨论】:

  • 你应该阅读不显眼的 Javascript,它可以让你完全摆脱那些。 Bootstrap 就是这样工作的。
  • 感谢您的评论。我很可能无法使用任何新框架,因为它是一个现有项目。我将研究不显眼的 js,但如果您知道任何好的入门链接可以让我朝着正确的方向前进,那就太好了。谢谢。
  • 基本上就是在页面内data-*属性中指定行为,然后使用单个全局JS脚本来读取它们。
  • 我不太了解'data-*'属性,但无论如何,这不是也需要每页一个脚本文件吗?如果每个页面只有几个脚本功能,更不用说用户控件,那就太多了!
  • data-* 属性适用于所有浏览器。摆脱现成的脚本,并在页面末尾包含一个脚本,用于查找装饰元素并激活/编写脚本。

标签: javascript jquery asp.net webforms


【解决方案1】:

您应该使用 data-* 属性指定 HTML 中应该存在的行为。
然后,您可以使用单个通用 Javascript 代码来读取这些属性并应用行为。

例如:

<div data-fancy-trick="trick-3">...</div>

在JS文件中,可以这样写

$('[data-fancy-trick]'.each(function() { 
    var trickName = $(this).data('fancy-trick');
    switch (trickName) {
        ...
    }
});

有关此技术的真实示例,请查看Bootstrap's Javascript components

【讨论】:

    【解决方案2】:

    您可以简单地为每个页面创建单独的 js 文件并将它们包含在相关页面中。对于共享脚本代码,有一个通用的 js 文件。按照你的例子:

    common.js

    var myCommonVar = {};
    function myCommonFunction(...){
       ...
    }    
    

    page1.js

    $(document).ready(function() {
     ...
     function1();
     ...
    });
    

    page2.js

    $(document).ready(function() {
     ...
     function2();
     ...
    });
    

    page1.html

    ...
    <script src='/js/common/js'></script>
    <script src='/js/page1.js'></script>
    ...
    

    page2.html

    ...
    <script src='/js/common/js'></script>
    <script src='/js/page2.js'></script>
    ...
    

    【讨论】:

    • 每页只有一个脚本是不是太过分了?
    • @alex,这取决于。与内联相比,将其保存在文件中的一个好处是浏览器缓存。
    • 我同意。但仍然每页一个脚本是一个太多了。我们有 100 多页左右。
    • @alex,然后请将该约束添加到您的问题中,以便我们知道我们在处理什么。
    • 我在问题中提到过它(一个或两个文件),但明确添加了该信息。
    【解决方案3】:

    考虑使用 AMD(异步模块定义)设计模式。将您的 JavaScript 代码放入模块中,并在每个页面上只使用您真正需要的那些。例如requirejs 做得很好,我一直在成功使用它。如果您有更大的项目,您可以将模块拆分为命名空间。这种方法将保持出色的代码可维护性并且是可靠的。您只需将“starter”javascript 文件放在每个页面上,然后只加载每个页面需要使用的那些必需模块。

    【讨论】:

      【解决方案4】:

      有很多方法可以解决这个问题,或者使用旨在将您的网站视为“Webapp”的 JavaScript 框架(AngularEmber 在流行中),或者使用您自己的自定义脚本将做到这一点 - 为每个加载的页面调用适当的 JavaScript。

      基本上,能够处理它的自定义脚本必须使用(伪)“命名空间”来分隔模块/页面代码部分。

      假设您有 2 个假设页面,HomeBrowse,简化的代码示例可能如下所示:

      HTML:

      <body data-page="Home">
      

      Global.js:

      var MyApp = {}; // global namespace
      
      $(document).ready(function()
           {
           var pageName = $('body').data('page');
      
           if (pageName && MyApp[pageName] && MyApp[pageName].Ready)
                MyApp[pageName].Ready();
           });
      

      Home.js:

      MyApp.Home = MyApp.Home || {}; // 'Home' namespace
      
      MyApp.Home.Ready = function()
           {
           // here comes your 'Home' document.ready()
           };
      

      Browse.js:

      MyApp.Browse = MyApp.Browse || {}; // 'Browse' namespace
      
      MyApp.Browse.Ready = function()
           {
           // here comes your 'Browse' document.ready()
           };
      
      MyApp.Browse.AnotherUtilFunc = function()
           {
           // you could have the rest of your page-specific functions as well
           }
      

      另外,由于您使用的是 ASP.NET MVC,有时您的 Controller 名称可能适合作为限定页面名称,您可以在您的 Layout.cshtml 中自动设置它(如果有的话):

      <html>
            <head>
            </head>
      
            <body data-page="@ViewContext.RouteData.Values["Controller"].ToString()">
                 @RenderBody()
            </body>
      </html>
      

      【讨论】:

      • 我删除了 asp.net mvc 标签,只使用网络表单。
      • 您仍然可以从Routing 值中提取和使用一些数据,甚至可以使用 ASPX 文件名。
      【解决方案5】:

      我认为将所有内容都塞进一个文件并用条件语句分隔它们是不值得的,只是为了避免在相应文件上添加引用。

      如果您有可以在 2,3 或更多页面上调用的代码,那么我们可以选择将它们放在一个公共文件中。但是如果要在单个页面上调用它,那么我们必须只在相应的页面上编写代码。这也会增加声明不会在当前页面调用的函数的开销

      而当你使用普通的js文件时,则不用担心$(document).ready();事件,你可以在普通文件中使用单个ready事件,并使用条件语句分隔代码。

      【讨论】:

        【解决方案6】:

        新版本的脚本管理器会将所有内容合并到一个脚本中。从理论上讲,它可以减少往返次数,并且运行速度更快。实际上,您最终可能会得到几个几乎相同的大型脚本,并且每个页面都需要自己的脚本块。如果您制作其中之一从不更改 url 网站页面,那么这就是要走的路。

        我在 ASP.Net 上使用 jquery 时提出了这些最佳实践

        1. 在第一个脚本管理器上方的母版页中加载 Jquery。 Jquery 现在在每个页面上都可用。浏览器只会获取一次并缓存它。
        2. 如果带宽有问题,请使用 googleload 或 MS content delivery network 等 jquery 加载程序
        3. Document.load 始终位于页面底部,以确保所需的所有内容都已加载。

        From my blog that I haven't updated in years...Google Load with ASP.Net

        【讨论】:

          【解决方案7】:

          解决此问题的一种常见方法是让您的通用脚本包含后跟每页脚本元素:

          <!-- In 'shoppingcart.html' -->
          <script src="main.js"></script>
          <script>
              // Let there be a onDomReady JS object inside main.js
              // that defines the document.ready logic on a per-page basis
              $(document).ready(onDomReady.shoppingCart);
          </script>
          

          【讨论】:

            【解决方案8】:

            很好的问题,我一直在处理同样的事情。 这是我一直在做的事情:

            让您的 $(document).ready() 调用不同的 init 函数(如果它们存在),其中每个 .js 文件都有自己的 init,它添加事件侦听器和加载函数、与 css 混淆等。每个 .js文件被分成不同的功能。

            这样您就可以准备好一个调用所有初始化程序的文档。所以每个页面都会包含它需要的 .js 功能。这样您就可以区分出不同之处。

            例如:

            ready.js:

            $(document).ready(function(){
            if (typeof menuNavInit == 'function'){
                 menuNavInit();
            }
            if (typeof menuNavDifferentInit == 'function'){
                 menuNavDifferentInit();
            }
            //other .js functionality
            });
            

            menuNav.js

            function menuNavInit(){
                 $("#menu").on('click', menuNavClick)
            }
            
            function menuNavClick(){
            //do something
            }
            

            menuNavDifferent.js

            function menuNavDifferentInit(){
                 $("#menu").on('click', menuNavDifferentClick)
            }
            
            function menuNavDifferentClick(){
            //do something else
            }
            

            page1.html

            ...
            <script src='scripts/ready.js'></script>
            <script src='scripts/menuNav.js'></script>
            ...
            

            page2.html

            ...
            <script src='scripts/ready.js'></script>
            <script src='scripts/menuNavDifferent.js'></script>
            ...
            

            【讨论】:

              猜你喜欢
              • 2019-06-14
              • 2017-05-23
              • 1970-01-01
              • 2013-04-09
              • 2010-09-24
              • 1970-01-01
              • 1970-01-01
              • 2012-12-24
              • 2011-03-12
              相关资源
              最近更新 更多