【问题标题】:How to write and keep clean, easily understood Javascript & jQuery如何编写和保持干净、易于理解的 Javascript 和 jQuery
【发布时间】:2012-01-04 17:41:32
【问题描述】:

有没有人有关于整理以下代码的建议:

/* Example code only to demonstrate the type of code my app contains and 
will contain more of */

$("#filter").click(function()
{
    if($(this).attr("value") != "" && $(this).attr("value").length > charLimit)
        filterable($(this).attr("value"))
});

$("#filter").keyup(function()
{
    if($(this).attr("value") == "" || $(this).attr("value").length <= charLimit)
    {
        $('.alphablock').show(300);
        $('.filterable a').removeClass("selected");
    }
});

$('.slidingForm fieldset').hide();

$('.slidingForm fieldset:first').find(':input:first').focus();

/* Snip More Code */

基本上,我的每个元素都有很多代码,这只是一堆东西,这可行,但它只会变得更大,更难维护和开发。

我很了解 PHP,我通常会求助于类来将代码保存在可维护的块中。但我不确定 jQuery 和一般 javascript 功能的最佳方法,它们的使用方式完全不同,因为它的程序性较低,并且可以根据用户交互随时调用函数。

谢谢 杰克

【问题讨论】:

  • 整理是什么意思?对我来说它看起来很整洁。
  • 我的意思是,将项目按更合乎逻辑的顺序排列,以供其他人遵循,并让我自己在未来发展。目前它只是许多选择器及其操作的列表,但没有关于在哪里找到什么的结构。评论会有所帮助,但到目前为止的答案都很棒。

标签: javascript jquery coding-style


【解决方案1】:

一切都很干净,但是我最近一直在做一些我推荐的事情:

(function($)
{    
    "use strict";

    // Variables declared here are scoped to this function, won't polute 
    // the globals.

    $(function()
    {
        // Do your work here.
    });

})(jQuery);

将脚本包含在函数本身中,允许您声明不会在全局范围内创建的变量。如果您需要全局化,请将其分配给 window 对象:

window.something = {};

我还会考虑将您的 jquery 对象分配给一个变量,重复选择相同的对象是没有意义的,例如$("#filter")$(this)

如果您使用类选择器,最后一件事是更喜欢在标签名称前加上前缀,例如$("div.slidingForm") 而不是 $(".slidingForm")。尽管您可能不会注意到简单页面上的任何差异,但在您进行大量选择的更复杂页面上,最好允许浏览器使用本机 getElementsByTagName 方法提取元素子集以匹配类选择器开启,而不必遍历整个 DOM。

【讨论】:

    【解决方案2】:

    我不知道你所说的整洁是什么意思。但是,我认为将 FunctionDeclaration 作为参数传递总是一个好主意。这样做有两个好处:

    1. 由于 JavaScript 声明被提升,FunctionDeclaration 可以放在脚本的末尾,并且可以作为参数引用。
    2. 命名为 Functions 总是更容易调试,因为堆栈跟踪将显示引发错误的确切函数。

    它会更多地按照以下方式编写您的代码:

    (function () {
        /* Example code only to demonstrate the type of code my app contains and 
        will contain more of */
    
        var filter = $("#filter");
        filter.click(filterClick);
        filter.keyup(filterKeyup);
        $('.slidingForm fieldset').hide();
        $('.slidingForm fieldset:first').find(':input:first').focus();
    
        /* Snip More Code */
    
        function filterClick() {
            if ($(this).attr("value") !== "" && $(this).attr("value").length > charLimit) {
                filterable($(this).attr("value"));
            }
        }
    
        function filterKeyup() {
            if ($(this).attr("value") === "" || $(this).attr("value").length <= charLimit) {
                $('.alphablock').show(300);
                $('.filterable a').removeClass("selected");
            }
        }
    })();
    

    【讨论】:

      【解决方案3】:

      尝试使用其中一种 Javascript 框架,如 Backbone.js、AngularJS 以模型-视图-控制器的方式组织代码。

      【讨论】:

      • 你真的需要为这个程序使用 MVC 架构吗?在上述情况下,不需要模型或控制器。 JQuery 仅用于视图。
      • 这里有另一个答案引用了 KnockOut Js,这也非常好。那个答案已经消失了,这是下一个最好的。谢谢卡兹
      • KnockoutJS 类似于 Angular,但 Angular 看起来很棒。我用了一段时间,效果很好。
      【解决方案4】:

      旁注:使用http://documentcloud.github.com/backbone/

      我的看法:

      $filter = $("#filter")
      $filter.click(function(){
        var value = $(this).attr("value");
        if(value != "" && value.length > charLimit){
          filterable(value)
        }
      });
      
      $filter.keyup(function(){
        var value = $(this).attr("value");
        if(value == "" || value.length <= charLimit){
            $('.alphablock').show(300);
            $('.filterable a').removeClass("selected");
        }
      });
      
      $('.slidingForm fieldset').hide();
      $('.slidingForm fieldset:first').find(':input:first').focus();
      

      【讨论】:

        【解决方案5】:

        我一般会做两件事:

        • 寻找可以重构为基于约定的插件的通用功能,并尝试重用它们。
        • 给每个主要视图它自己的 js 文件,并在视图加载时加载它以保持干净

        【讨论】:

          【解决方案6】:

          我倾向于避免绑定,而是直接将onClick 放入元素中,除非有动态绑定需要。我的 HTML 文件通常只是空结构,例如

          <div id="content">
            <div id="sidebar" />
          

          那种东西。我使用 jQuery 动态填充它们。我的js文件被组织成功能区域,例如页面或对象类,它们都有对应的css文件。我最终得到如下文件结构:

          js/basicstuff.js
          js/someclass/class1.js
          css/basicstuff.css
          css/someclass/class1.css
          

          原型js 文件及其覆盖也共享一个命名空间。我已经用这种方式编写了一些相当大的应用程序,但是单独的 jscss 文件很容易找到和更新,因为它们被应用程序的功能区域(例如 intro、setup、stage1、main、ending、设置 - 用于游戏)。

          在有意义的情况下,我还会使用动态函数组数组 - 例如,我使用全局 $(window).resize() 函数,它遍历数组,调用可能需要的页面定义的调整大小函数。当页面转换到下一个页面时,我只是删除了数组中的那个元素(尽管将它留在里面不会有任何伤害,只是需要一些额外的计算周期才能忽略)。

          【讨论】:

          • 在 jQuery 中绑定事件处理程序被认为是最佳实践。将功能代码与 HTML 混合会违反关注点分离。编辑-我只是重新阅读了您的答案,并认为我同意您的观点:P
          • 我可以看到@jbabey。我倾向于以可视化编辑器(如 Visual Studio 或 XCode)将事件绑定到对象的相同方式来考虑 UI 创建过程。尽管绑定是在代码中解决的,但定义往往出现在属性类型对话框中,将它(在我看来)与可视元素相关联。我认为这在网页中对我来说很重要。
          【解决方案7】:

          您可以将所有内容放入“命名空间”对象,然后调用方法(作为函数的属性)来初始化您的事件处理程序。这样可以使事情井井有条。

          $(document).ready(function () {
             filter.initialize('filter');
          });
          
          var filter = (function () {
              var initialize = function (filterID) {
                  var that = $('#' + filterID);
          
                  that.click(function() {
                      var value = that.val();
          
                      if (value != '' && value.length > charLimit) {
                          filterable(value);
                      }
                  });
          
                  that.keyup(function() {
                      var value = that.val();
          
                      if (value == '' || value.length <= charLimit) {
                          $('.alphablock').show(300);
                          $('.filterable a').removeClass("selected");
                      }
                  });
          
                  $('.slidingForm fieldset').hide();
                  $('.slidingForm fieldset:first').find(':input:first').focus();
              };
          
              return {
                  initialize: initialize
              };
          });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-04-02
            • 1970-01-01
            • 2011-02-15
            • 2010-09-16
            • 2018-06-10
            • 2012-12-24
            • 2020-06-04
            相关资源
            最近更新 更多