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

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

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

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

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


EDIT

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

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

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


当前回答

我用这个小东西。它为JS和HTML模板提供了“include”指令。它完全消除了混乱。

https://github.com/gaperton/include.js/

$.include({
    html: "my_template.html" // include template from file...
})
.define( function( _ ){ // define module...
    _.exports = function widget( $this, a_data, a_events ){ // exporting function...
        _.html.renderTo( $this, a_data ); // which expands template inside of $this.

        $this.find( "#ok").click( a_events.on_click ); // throw event up to the caller...
        $this.find( "#refresh").click( function(){
            widget( $this, a_data, a_events ); // ...and update ourself. Yep, in that easy way.
        });
    }
});

其他回答

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

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

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

我为所有我真的不需要在屏幕上实例化几次的东西创建单例,为其他所有东西创建一个类。所有这些都放在同一个文件的同一个名称空间中。所有的东西都是用UML、状态图进行注释和设计的。javascript代码是清楚的html,所以没有内联javascript,我倾向于使用jquery来最小化跨浏览器的问题。

遵循良好的OO设计原则和设计模式有助于使代码易于维护和理解。 但我最近发现的最好的东西之一是信号和槽,也就是发布/订阅。 看看http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html 简单的jQuery实现。

这个想法在其他语言的GUI开发中也得到了很好的应用。当代码中某个重要的事件发生时,你会发布一个全局合成事件,其他对象中的其他方法可能会订阅该事件。 这提供了很好的对象分离。

我认为Dojo(和Prototype?)有这种技术的内置版本。

参见什么是信号和槽?

你可以使用jquery mx(在javascriptMVC中使用),这是一组允许你使用模型、视图和控制器的脚本。我曾在一个项目中使用它,并帮助我创建结构化javascript,由于压缩,脚本大小最小。以控制器为例:

$.Controller.extend('Todos',{
  ".todo mouseover" : function( el, ev ) {
   el.css("backgroundColor","red")
  },
  ".todo mouseout" : function( el, ev ) {
   el.css("backgroundColor","")
  },
  ".create click" : function() {
   this.find("ol").append("<li class='todo'>New Todo</li>"); 
  }
})

new Todos($('#todos'));

如果对视图和模型部分不感兴趣,也可以只使用querymx的控制器端。

我使用一个受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。