4

I'm looking for best practices for using javascript/jQuery snippets in an asp.net project. I know that it is best to put all the scripts in a separate file rather than inline. That's good. It is easy to move these script functions to a common file (may be a couple of different ones to even out the performance of loading a single large file for small functions).

But there is some jQuery stuff that needs to happen on document.Ready on each page. How will I move this to a common .js file? I would like to avoid one script per page as it would be just too many.

For example, say Page1 has a need to manipulate a few radio buttons on load and has the following script inline. (just for illustration)

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

Same with Page2 but for some other condition, calling different function function2.

I can move the function1 and function2 to a common .js file but how about the document ready sections. Should that stay inline? I assume so because otherwise I'm not sure how the common.js will differentiate between document.ready for different pages.

Then does it defeat the purpose of not having inline javascript? If anyone can throw some light into this, it is much appreciated.

I did some research, but probably due to incorrect keywords, so far I haven't been able to find any good information along the same lines. Unobtrusive JavaScript seems promising in the comments below.

4

8 回答 8

3

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 的 Javascript 组件

于 2013-09-17T15:11:09.090 回答
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>
...
于 2013-09-17T01:03:31.753 回答
1

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

于 2013-09-19T07:23:28.747 回答
0

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

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

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

前任:

准备好了.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>
...
于 2013-09-23T21:37:10.710 回答
0

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

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

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

于 2013-09-17T12:51:59.640 回答
0

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

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

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

从我多年未更新的博客中... Google Load with ASP.Net

于 2013-09-21T13:18:52.890 回答
0

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

<!-- 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>
于 2013-09-23T05:20:03.560 回答
0

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

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

假设您有 2 个假设页面,Home并且Browse,简化代码示例可能如下所示:

HTML:

<body data-page="Home">

全球.js:

var MyApp = {}; // global namespace

$(document).ready(function()
     {
     var pageName = $('body').data('page');

     if (pageName && MyApp[pageName] && MyApp[pageName].Ready)
          MyApp[pageName].Ready();
     });

主页.js:

MyApp.Home = MyApp.Home || {}; // 'Home' namespace

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

浏览.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>
于 2013-09-17T00:37:54.327 回答