JavaScript中代码组织的常见最佳实践

时间:2008-10-29 15:19:32

标签: javascript jquery design-patterns architecture formatting

随着像jQuery这样的JavaScript框架使客户端Web应用程序更丰富,更实用,我开始注意到一个问题......

你是如何保持这种组织的?

  • 将所有处理程序放在一个位置并为所有事件编写函数?
  • 创建函数/类来包装所有功能吗?
  • 写得像疯了似的,只希望它能够做到最好?
  • 放弃并开始新的职业生涯?

我提到了jQuery,但它实际上是任何JavaScript代码。我发现随着线条开始堆积起来,管理脚本文件或找到你要找的东西变得更加困难。很可能我发现的最大的问题是有很多方法可以做同样的事情,很难知道哪一个是目前普遍接受的最佳实践。

是否有关于保持 .js 文件与应用程序其他部分一样漂亮和整洁的最佳方法的一般性建议?或者这仅仅是IDE的问题?那里有更好的选择吗?


修改

这个问题旨在更多地关注代码组织而不是文件组织。有一些非常好的合并文件或分割内容的例子。

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

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

28 个答案:

答案 0 :(得分:177)

如果javascript内置了命名空间,那将会更好,但我发现像Dustin Diaz这样的组织描述here对我有很大的帮助。

var DED = (function() {

    var private_var;

    function private_method()
    {
        // do stuff here
    }

    return {
        method_1 : function()
            {
                // do stuff here
            },
        method_2 : function()
            {
                // do stuff here
            }
    };
})();

我将不同的“名称空间”和有时单独的类放在不同的文件中。通常我从一个文件开始,并且作为一个类或命名空间变得足够大以保证它,我将它分成它自己的文件。使用工具将所有文件组合起来进行制作也是一个很好的主意。

答案 1 :(得分:87)

我尽量避免在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();
});

我还发现命名约定对可读性很重要。例如:我将'j'添加到所有jQuery实例中。

在上面的示例中,有一个名为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>');
  //...
};

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

答案 2 :(得分:39)

您可以将脚本拆分为单独的文件进行开发,然后创建一个“发布”版本,将所有文件一起填入并运行YUI Compressor或其类似的东西。

答案 3 :(得分:27)

受早期帖子的启发,我制作了一份分发了WysiHat Rakefile 和供应商目录的副本,并对其进行了一些修改包括JSLint的代码检查和YUI Compressor的缩小。

我们的想法是使用Sprockets(来自WysiHat)将多个JavaScripts合并到一个文件中,使用JSLint检查合并文件的语法,并在分发之前使用YUI Compressor缩小它。

<强>先决条件

  • Java Runtime
  • 红宝石和耙子宝石
  • 您应该知道如何将JAR放入Classpath

现在执行

  1. 下载Rhino并将JAR(“js.jar”)放入您的类路径
  2. 下载YUI Compressor并将JAR(build / yuicompressor-xyz.jar)放入类路径
  3. 下载WysiHat并将“vendor”目录复制到JavaScript项目的根目录
  4. 下载JSLint for Rhino并将其放入“供应商”目录
  5. 现在在JavaScript项目的根目录中创建一个名为“Rakefile”的文件,并将以下内容添加到其中:

    require 'rake'
    
    ROOT            = File.expand_path(File.dirname(__FILE__))
    OUTPUT_MERGED   = "final.js"
    OUTPUT_MINIFIED = "final.min.js"
    
    task :default => :check
    
    desc "Merges the JavaScript sources."
    task :merge do
      require File.join(ROOT, "vendor", "sprockets")
    
      environment  = Sprockets::Environment.new(".")
      preprocessor = Sprockets::Preprocessor.new(environment)
    
      %w(main.js).each do |filename|
        pathname = environment.find(filename)
        preprocessor.require(pathname.source_file)
      end
    
      output = preprocessor.output_file
      File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) }
    end
    
    desc "Check the JavaScript source with JSLint."
    task :check => [:merge] do
      jslint_path = File.join(ROOT, "vendor", "jslint.js")
    
      sh 'java', 'org.mozilla.javascript.tools.shell.Main',
        jslint_path, OUTPUT_MERGED
    end
    
    desc "Minifies the JavaScript source."
    task :minify => [:merge] do
      sh 'java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v',
        OUTPUT_MERGED, '-o', OUTPUT_MINIFIED
    end
    

    如果您已正确完成所有操作,则应该可以在控制台中使用以下命令:

    • rake merge - 将不同的JavaScript文件合并为一个
    • rake check - 检查代码的语法(这是默认任务,因此您只需键入rake
    • rake minify - 准备JS代码的缩小版本

    关于源合并

    使用Sprockets,JavaScript预处理器可以包含(或require)其他JavaScript文件。使用以下语法来包含初始文件中的其他脚本(名为“main.js”,但您可以在Rakefile中更改它):

    (function() {
    //= require "subdir/jsfile.js"
    //= require "anotherfile.js"
    
        // some code that depends on included files
        // note that all included files can be in the same private scope
    })();
    

    然后......

    查看WysiHat提供的Rakefile来设置自动单元测试。好东西:)

    现在回答

    这不能很好地回答原始问题。我知道,我很抱歉,但我已经在这里发布了,因为我希望其他人可以组织他们的混乱。

    我解决这个问题的方法是尽可能多地进行面向对象的建模,并将实现分成不同的文件。然后处理程序应尽可能短。 List单例的示例也很好。

    名称空间......他们可以通过更深层次的对象结构来模仿。

    if (typeof org === 'undefined') {
        var org = {};
    }
    
    if (!org.hasOwnProperty('example')) {
        org.example = {};
    }
    
    org.example.AnotherObject = function () {
        // constructor body
    };
    

    我不是模仿的忠实粉丝,但是如果你有许多想要移出全球范围的物品,这可能会有所帮助。

答案 4 :(得分:18)

代码组织要求采用惯例和文档标准:
1.物理文件的命名空间代码;

Exc = {};


2。这些命名空间中的组类javascript;
3.设置用于表示现实世界对象的原型或相关函数或类;

Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};
Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    ...
};


4.设置约定以改进代码。例如,将其所有内部函数或方法分组到对象类型的类属性中。

Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    this.internal = {
        widthEstimates: function (tips) {
            ...
        }
        formatTips: function () {
            ...
        }
    };
    ...
};


5。制作名称空间,类,方法和变量的文档。必要时还讨论一些代码(一些FI和Fors,它们通常实现代码的重要逻辑)。

/**
  * Namespace <i> Example </i> created to group other namespaces of the "Example".  
  */
Exc = {};
/**
  * Namespace <i> ui </i> created with the aim of grouping namespaces user interface.
  */
Exc.ui = {};

/**
  * Class <i> maskdInput </i> used to add an input HTML formatting capabilities and validation of data and information.
  * @ Param {String} mask - mask validation of input data.
  */
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};

/**
  * Class <i> domTips </i> used to add an HTML element the ability to present tips and information about its function or rule input etc..
  * @ Param {String} id - id of the HTML element.
  * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id <i> </i>.
  */
  Exc.ui.domTips = function (id, tips) {
    this.domID = id;
    this.tips = tips;
    ...
};


这些只是一些提示,但这对组织代码有很大帮助。记住你必须有纪律才能成功!

答案 5 :(得分:13)

遵循良好的OO设计原则和设计模式对于使代码易于维护和理解有很长的路要走。 但我最近发现的最好的事情之一是信号和插槽,即发布/订阅。 看看http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html 对于简单的jQuery实现。

这个想法很好地用于其他语言的GUI开发。当代码中某处发生重要事件时,您会发布一个全局合成事件,其他对象中的其他方法可能会订阅该事件。 这样可以很好地分离物体。

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

另见What are signals and slots?

答案 6 :(得分:12)

我能够在之前的工作中成功将Javascript Module Pattern应用于Ext JS应用程序。它提供了一种创建封装好的代码的简单方法。

答案 7 :(得分:11)

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

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

  • Dojo代码和自定义代码(dojo.declare())的命名空间 - 不会污染全局空间,与其他库共存,以及用户的非Dojo感知代码。
  • 按名称(dojo.require())同步或异步加载模块。
  • 通过分析模块依赖关系来自定义构建,以创建单个文件或一组相互依赖的文件(所谓的图层),以仅包含Web应用程序所需的内容。自定义构建还可以包括Dojo模块和客户提供的模块。
  • 透明的基于CDN的Dojo访问和用户代码。 AOL和谷歌都以这种方式运载Dojo,但有些客户也会为他们的自定义Web应用程序执行此操作。

答案 8 :(得分:9)

我很惊讶没人提到MVC框架。我一直在使用Backbone.js模块化和解耦我的代码,这是非常宝贵的。

这里有很多这样的框架,其中大部分都非常小。我个人的观点是,如果你要编写的不仅仅是几行jQuery for flashy UI,或者想要一个丰富的Ajax应用程序,MVC框架将使你的生活更轻松。

答案 9 :(得分:9)

我的老板仍然谈到他们编写模块化代码(C语言)的时代,并抱怨现在的代码有多糟糕!据说程序员可以在任何框架中编写程序集。始终存在一种克服代码组织的策略。基本问题在于将java脚本视为玩具并且从不尝试学习它的人。

在我的情况下,我使用适当的init_screen()在UI主题或应用程序屏幕上编写js文件。使用正确的id命名约定,我确保根元素级别没有名称空间冲突。在不引人注目的window.load()中,我根据顶级id绑定了一些东西。

我严格使用java脚本闭包和模式来隐藏所有私有方法。执行此操作后,从未遇到过冲突的属性/函数定义/变量定义的问题。但是,与团队合作时,通常很难强制执行相同的严格要求。

答案 10 :(得分:9)

查看JavasciptMVC

你可以:

  • 将您的代码拆分为模型,视图和控制器层。

  • 将所有代码压缩到单个生产文件中

  • 自动生成代码

  • 创建并运行单元测试

  • 以及更多......

最重要的是,它使用jQuery,因此您也可以利用其他jQuery插件。

答案 11 :(得分:8)

“写得像疯了一样,只希望它能够做到最好吗?”,我看到这样一个项目由2位开发人员开发和维护,这是一个包含大量JavaScript代码的庞大应用程序。最重要的是,您可以想到的每个可能的jquery函数都有不同的快捷方式。我建议他们将代码组织为插件,因为它是类,模块,命名空间和整个Universe的jquery等价物。但事情变得更糟,现在他们开始编写插件来替换项目中使用的3行代码的每个组合。 Personaly我认为jQuery是魔鬼,它不应该用于有大量JavaScript的项目,因为它鼓励你懒惰而不考虑以任何方式组织代码。我宁愿阅读100行javascript而不是一行40个链式jQuery函数(我不是在开玩笑)。 与流行的看法相反,将javascript代码组织成名称空间和类的等价物非常容易。这就是YUI和Dojo所做的。如果你愿意,你可以轻松自己动手。我觉得YUI的方法更好,更有效率。但是,如果你想编写任何有用的东西,你通常需要一个支持片段的好编辑器来补偿YUI命名约定。

答案 12 :(得分:7)

我为每件事创建单身,我真的不需要在屏幕上多次实例化,其他一切都是类。并且所有这些都放在同一文件中的相同名称空间中。所有内容都经过评论,并使用UML状态图进行设计。 javascript代码没有html,所以没有内联javascript,我倾向于使用jquery来最小化跨浏览器问题。

答案 13 :(得分:6)

在我的上一个项目-Viajeros.com-我使用了几种技术的组合。我不知道如何组织一个网络应用程序 - Viajeros是一个社交网站,适合那些定义明确的部分的旅行者,所以很容易将每个区域的代码分开。

我根据站点部分使用命名空间模拟和延迟加载模块。在每个页面加载时,我声明一个“vjr”对象,并始终为它加载一组公共函数(vjr.base.js)。然后每个HTML页面通过简单的方式决定需要哪些模块:

vjr.Required = ["vjr.gallery", "vjr.comments", "vjr.favorites"];

Vjr.base.js从服务器中解压缩每一个并执行它们。

vjr.include(vjr.Required);
vjr.include = function(moduleList) {
  if (!moduleList) return false;
  for (var i = 0; i < moduleList.length; i++) {
    if (moduleList[i]) {
      $.ajax({
        type: "GET", url: vjr.module2fileName(moduleList[i]), dataType: "script"
      });
    }
  }
};

每个“模块”都有这种结构:

vjr.comments = {}

vjr.comments.submitComment = function() { // do stuff }
vjr.comments.validateComment = function() { // do stuff }

// Handlers
vjr.comments.setUpUI = function() {
    // Assign handlers to screen elements
}

vjr.comments.init = function () {
  // initialize stuff
    vjr.comments.setUpUI();
}

$(document).ready(vjr.comments.init);

鉴于我有限的Javascript知识,我知道必须有更好的方法来管理它,但直到现在它对我们来说都很有用。

答案 14 :(得分:6)

以Jquery为中心的NameSpace方式组织代码可能如下所示......并且不会与Prototype,Ext等其他Javascript API冲突。

<script src="jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">

var AcmeJQ = jQuery.noConflict(true);
var Acme = {fn: function(){}};

(function($){

    Acme.sayHi = function()
    {
        console.log('Hello');
    };

    Acme.sayBye = function()
    {
        console.log('Good Bye');
    };
})(AcmeJQ);

// Usage
//          Acme.sayHi();
// or
// <a href="#" onclick="Acme.sayHi();">Say Hello</a>


</script>

希望这有帮助。

答案 15 :(得分:6)

OO + MVC的优秀校长肯定会在管理复杂的JavaScript应用程序方面走得很远。

基本上我正在将我的应用程序和javascript组织到以下熟悉的设计中(从我的桌面编程时代到Web 2.0一直存在)

JS OO and MVC

图像上数值的说明:

  1. 表示我的应用程序视图的小部件。这应该是可扩展的,并且整齐地分离出来,导致MVC试图实现的良好分离,而不是将我的小部件变成意大利面条代码(相当于将大块Javascript直接放在HTML中的Web应用程序)。每个小部件通过监听其他小部件生成的事件来通过其他小部件进行通信,从而减少小部件之间的强大耦合,这可能导致无法管理的代码(请记住添加onclick的那一天到处都指向脚本标记中的全局函数?Urgh ...)
  2. 对象模型,表示我想在窗口小部件中填充并来回传递到服务器的数据。通过将数据封装到其模型中,应用程序变为数据格式不可知。例如:虽然自然在Javascript中这些对象模型大多是序列化和反序列化为JSON,如果服务器以某种方式使用XML进行通信,我需要更改的是更改序列化/反序列化层,而不一定需要更改所有窗口小部件类
  3. 管理业务逻辑和与服务器通信的控制器类+偶尔缓存层。该层控制与服务器的通信协议,并将必要的数据放入对象模型
  4. 将类整齐地包装在相应的名称空间中。我相信大家都知道Javascript中的全局命名空间是多么令人讨厌。
  5. 过去,我会将文件分成自己的js,并使用通常的做法在Javascript中创建OO原则。我很快发现有很多方法可以编写JS OO并且并不一定所有团队成员都采用相同的方法。随着团队变得更大(在我的情况下超过15人),这变得复杂,因为没有标准的面向对象的Javascript方法。与此同时,我不想写自己的框架,重复一些我确信比我解决的人更聪明的工作。

    jQuery作为Javascript Framework非常好,我喜欢它,但随着项目变得越来越大,我显然需要为我的Web应用程序提供额外的结构,特别是为了便于标准化OO实践。对于我自己,经过几次实验,我发现YUI3 Base和Widget(http://yuilibrary.com/yui/docs/widget/http://yuilibrary.com/yui/docs/base/index.html)基础设施正是我所需要的。我使用它们的原因很少。

    1. 它提供了命名空间支持。真正需要OO和整洁的代码组织
    2. 它支持类和对象的概念
    3. 它提供了一种标准化方法,可以将实例变量添加到您的类
    4. 它整齐地支持课程扩展
    5. 它提供构造函数和析构函数
    6. 它提供渲染和事件绑定
    7. 它有基本小部件框架
    8. 每个小部件现在都可以使用基于标准事件的模型
    9. 相互通信
    10. 最重要的是,它为所有工程师提供了JO开发的OO标准
    11. 与许多观点相反,我不一定要在jQuery和YUI3之间做出选择。这两者可以和平共处。虽然YUI3为我的复杂Web应用程序提供了必要的OO模板,但jQuery仍然为我的团队提供了易于使用的JS抽象,我们都喜欢和熟悉它。

      使用YUI3,我已经设法创建MVC模式,通过分离扩展Base作为模型的类,将Widget扩展为View的类,当然你有Controller类进行必要的逻辑和服务器端调用。

      Widget可以使用基于事件的模型相互通信,并根据预定义的界面监听事件并执行必要的任务。简单地说,将OO + MVC结构放到JS中对我来说是一种快乐。

      只是免责声明,我不为雅虎工作!而且只是一个试图解决原始问题所提出的同一问题的建筑师。我想如果有人发现等效的OO框架,这也可以。原则上,这个问题也适用于其他技术。感谢所有提出OO Principles + MVC的人,让我们的编程日更易于管理。

答案 16 :(得分:5)

我使用 Dojo的包管理dojo.requiredojo.provide)和类系统(dojo.declare,这也允许简单的多重继承)来模块化我的所有将类/小部件分成不同的文件。这不仅可以保持代码的有序性,而且还可以让你懒惰/及时加载类/小部件。

答案 17 :(得分:3)

创建假类,并确保任何可以被抛入一个有意义的单独函数的东西都是这样做的。还要确保评论很多,而不是编写spagghetti代码,而是将其全部保留在各个部分。例如,一些描述我理想的无意义代码。显然,在现实生活中,我还会编写许多基本上包含其功能的库。

$(function(){
    //Preload header images
    $('a.rollover').preload();

    //Create new datagrid
    var dGrid = datagrid.init({width: 5, url: 'datalist.txt', style: 'aero'});
});

var datagrid = {
    init: function(w, url, style){
        //Rendering code goes here for style / width
        //code etc

        //Fetch data in
        $.get(url, {}, function(data){
            data = data.split('\n');
            for(var i=0; i < data.length; i++){
                //fetching data
            }
        })
    },
    refresh: function(deep){
        //more functions etc.
    }
};

答案 18 :(得分:3)

答案 19 :(得分:3)

几天前,37Signals released a RTE control的那些人有点扭曲。他们建立了一个使用一种预处理器命令捆绑javascript文件的库。

我一直在使用它,因为我将JS文件分开,最后将它们合并为一个。这样我可以分开关注点,最后只有一个文件通过管道(gzip,不能​​少)。

在模板中,检查您是否处于开发模式,并包含单独的文件,如果在生产中,则包括最后一个(您必须自己“构建”)。

答案 20 :(得分:2)

我认为这可能与DDD(域驱动设计)有关。我正在处理的应用程序虽然缺少正式的API,但它通过服务器端代码(类/文件名等)提供了这样的提示。有了这个,我创建了一个顶级对象作为整个问题域的容器;然后,我在需要的地方添加了名称空间:

var App;
(function()
{
    App = new Domain( 'test' );

    function Domain( id )
    {
        this.id = id;
        this.echo = function echo( s )
        {
            alert( s );
        }
        return this;
    }
})();

// separate file
(function(Domain)
{
    Domain.Console = new Console();

    function Console()
    {
        this.Log = function Log( s )
        {
            console.log( s );
        }
        return this;
    }
})(App);

// implementation
App.Console.Log('foo');

答案 21 :(得分:2)

对于JavaScript组织一直使用以下

  1. 所有javascript文件夹
  2. 页面级别javascript获取其自己的文件,其页面名称相同。 ProductDetail.aspx将是ProductDetail.js
  3. 在库文件的javascript文件夹中,我有一个lib文件夹
  4. 将相关库函数放在要在整个应用程序中使用的lib文件夹中。
  5. Ajax是我在javascript文件夹之外移动的唯一一个javascript,并获取它自己的文件夹。然后我添加两个子文件夹客户端和服务器
  6. 客户端文件夹获取所有.js文件,而服务器文件夹获取所有服务器端文件。

答案 22 :(得分:2)

我正在使用这个小东西。它为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.
        });
    }
});

答案 23 :(得分:2)

您可以使用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'));

如果您对视图和模型部分不感兴趣,也可以使用jquerymx的only the controller面。

答案 24 :(得分:1)

你的问题是去年年底困扰我的问题。差异 - 将代码交给从未听说过私有和公共方法的新开发人员。我必须建立一些简单的东西。

最终结果是一个小的(大约1KB)框架,它将对象文字转换为jQuery。语法在视觉上更容易扫描,如果你的js变得非常大,你可以编写可重用的查询来查找使用的选择器,加载的文件,相关函数等等。

在这里发布一个小框架是不切实际的,所以我写了blog post with examples(我的第一个。这是一次冒险!)。欢迎你来看看。

对于其他任何有几分钟检查的人,我非常感谢您的反馈!

建议使用FireFox,因为它支持对象查询示例的toSource()。

干杯!

亚当

答案 25 :(得分:0)

Lazy按需加载您需要的代码。 Google使用google.loader

执行此类操作

答案 26 :(得分:0)

您没有提到您的服务器端语言。或者,更有针对性的是,您正在使用的框架 - 如果有的话 - 在服务器端。

IME,我在服务器端组织一些事情,让它们全部转移到网页上。该框架的任务不仅是组织每个页面必须加载的JS,还要组织使用生成的标记的JS片段。您通常不希望这样的片段不止一次发出 - 这就是为什么它们被抽象到该代码的框架中以照顾该问题。 : - )

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

请注意,这些都不会让您无法编写高效的JavaScript! : - )

答案 27 :(得分:0)

我使用了一个自定义脚本,灵感来自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's headScript() placeholder helper,但您也可以使用use javascript to load other scripts on the fly Ajile