随着像jQuery这样的JavaScript框架使客户端web应用程序更丰富,功能更强大,我开始注意到一个问题…

你到底是怎么组织起来的?

把所有的处理程序放在一个地方,并为所有事件编写函数? 创建函数/类来包装您的所有功能? 疯狂地写作,只希望结果是最好的? 放弃,找一份新工作?

我提到了jQuery,但它实际上是一般的JavaScript代码。我发现,当一行一行开始堆积时,管理脚本文件或找到您要找的内容变得越来越困难。我发现的最大问题可能是,做同一件事有太多的方法,很难知道哪一种是目前普遍接受的最佳实践。

有什么通用的建议可以让你的.js文件像你的应用程序的其他部分一样漂亮整洁吗?或者这只是IDE的问题?还有更好的选择吗?


EDIT

这个问题主要是关于代码组织,而不是文件组织。有一些合并文件或拆分内容的好例子。

我的问题是:目前普遍接受的组织实际代码的最佳实践方式是什么?您的方法是什么,甚至推荐的方法是什么,以与页面元素交互并创建互不冲突的可重用代码?

有些人列出了名称空间,这是个好主意。还有什么其他方法,更具体地说,处理页面上的元素并保持代码的组织和整洁?


当前回答

我的老板仍然在谈论他们编写模块化代码(C语言)的时代,并抱怨现在的代码是多么糟糕!据说程序员可以在任何框架中编写程序集。总有一种策略可以克服代码组织。最基本的问题是那些把java脚本当作玩具的人,从来没有尝试去学习它。

在我的例子中,我在UI主题或应用程序屏幕的基础上编写js文件,使用适当的init_screen()。使用适当的id命名约定,我确保在根元素级别上没有名称空间冲突。在不引人注目的window.load()中,我根据顶级id将内容绑定起来。

我严格使用java脚本闭包和模式来隐藏所有私有方法。这样做之后,再也没有遇到属性/函数定义/变量定义冲突的问题。然而,当与团队一起工作时,通常很难执行同样的严格性。

其他回答

对于JavaScript组织一直使用以下

Folder for all your javascript Page level javascript gets its' own file with the same name of the page. ProductDetail.aspx would be ProductDetail.js Inside the javascript folder for library files I have a lib folder Put related library functions in a lib folder that you want to use throughout your application. Ajax is the only javascript that I move outside of the javascript folder and gets it's own folder. Then I add two sub folders client and server Client folder gets all the .js files while server folder gets all the server side files.

您没有提到服务器端语言是什么。或者,更确切地说,您在服务器端使用什么框架(如果有的话)。

IME,我在服务器端组织东西,让它全部震动到网页上。该框架的任务不仅是组织每个页面必须加载的JS,还包括与生成的标记一起工作的JS片段。这样的片段通常不希望发出超过一次——这就是为什么它们被抽象到框架中,以便代码处理该问题。: -)

对于必须发出自己的JS的最终页面,我通常发现生成的标记中有一个逻辑结构。这种本地化的JS通常可以在这种结构的开始和/或结束处组装。

请注意,这些都不能免除您编写高效JavaScript的责任!: -)

我使用一个受Ben Nolan的行为启发的自定义脚本(很遗憾,我再也找不到这个脚本的当前链接了)来存储我的大多数事件处理程序。例如,这些事件处理程序由元素className或Id触发。 例子:

Behaviour.register({ 
    'a.delete-post': function(element) {
        element.observe('click', function(event) { ... });
    },

    'a.anotherlink': function(element) {
        element.observe('click', function(event) { ... });
    }

});

我喜欢动态地包含大多数Javascript库,除了那些包含全局行为的库。为此,我使用Zend Framework的headScript()占位符帮助器,但您也可以使用javascript加载其他脚本,例如Ajile。

Dojo从一开始就使用模块系统。事实上,它被认为是Dojo的基石,是将所有Dojo结合在一起的粘合剂:

dojo。要求——官方文件。 理解dojo.declare, dojo。Require和dojo. provider。 引入Dojo。

使用模块Dojo可以实现以下目标:

Namespaces for Dojo code and custom code (dojo.declare()) — do not pollute the global space, coexist with other libraries, and user's non-Dojo-aware code. Loading modules synchronously or asynchronously by name (dojo.require()). Custom builds by analyzing module dependencies to create a single file or a group of interdependent files (so-called layers) to include only what your web application needs. Custom builds can include Dojo modules and customer-supplied modules as well. Transparent CDN-based access to Dojo and user's code. Both AOL and Google carry Dojo in this fashion, but some customers do that for their custom web applications as well.

我尽量避免在HTML中包含任何javascript。所有代码都封装在类中,每个类都在自己的文件中。对于开发,我有单独的<script>标记来包含每个js文件,但是它们被合并到一个更大的包中用于生产,以减少HTTP请求的开销。

通常,我会为每个应用程序创建一个“main”js文件。所以,如果我正在编写一个“调查”应用程序,我将有一个名为“survey.js”的js文件。这将包含进入jQuery代码的入口点。我在实例化期间创建jQuery引用,然后将它们作为参数传递到我的对象中。这意味着javascript类是“纯粹的”,不包含任何对CSS id或类名的引用。

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

我还发现命名约定对于可读性很重要。例如:我在所有jQuery实例前加'j'。

在上面的例子中,有一个类叫做DimScreen。(假设这会使屏幕变暗并弹出一个警告框。)它需要一个div元素,它可以放大以覆盖屏幕,然后添加一个警告框,因此我传入一个jQuery对象。jQuery有一个插件概念,但它似乎有局限性(例如,实例不是持久的,不能访问),没有真正的好处。因此,DimScreen类将是一个标准的javascript类,只是恰好使用jQuery。

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

我已经使用这种方法构建了一些相当复杂的应用程序。