【问题标题】:jQuery and "Organized Code"jQuery 和“有组织的代码”
【发布时间】:2010-09-20 02:10:59
【问题描述】:

我最近一直在努力理解组织 jQuery 代码的最佳方式。我之前问了另一个问题,我认为我不够具体 (found in this question here)。

我的问题是,您制作的应用程序越丰富,您的客户端就会越快失控。考虑一下这种情况...

//Let's start some jQuery
$(function() {        
    var container = $("#inputContainer");

    //Okay let's list text fields that can be updated
    for(var i=0; i < 5; i++) {

        //okay let's add an event for when a field changes
        $("<input/>").change(function() {

            //okay something changed, let's update the server
            $.ajax({
                success:function(data) {

                    //Okay - no problem from the server... let's update
                    //the bindings on our input fields
                    $.each(container.children(), function(j,w) {

                        //YIKES!! We're deep in here now!!
                        $(w).unbind().change(function() {

                            //Then insanity starts...

                        }); // end some function

                    }); //end some loop

                } // what was this again?

            }); //ending something... not sure anymore

        }).appendTo(container); //input added to the page... logic WAY split apart

    }; //the first loop - whew! almost out!

});  //The start of the code!!

现在这种情况并非不可能。我并不是说这是正确的做法,但是发现自己进入 jQuery 命令的几个级别并开始想知道在屏幕开始融化之前还能添加多少逻辑。

我的问题是人们如何管理或组织以限制其代码的复杂性?

I listed how I'm doing it in my other post...

【问题讨论】:

  • .changed(... 应该是 .change(...
  • 你说得对——我是凭记忆做的……这对我来说不是最好的……
  • 您能编辑帖子并更正它吗?在我阅读其中一个答案时让我感到困惑。
  • @Hugoware 我认为你应该接受这个答案:)

标签: javascript jquery code-organization


【解决方案1】:

只是想补充一下前面提到的内容:

$.each(container.children(), function(j,w) {
    $(w).unbind().change(function() { ... });
});

可以优化为:

container.children().unbind().change(function() { ... });

这一切都与链接有关,这是一种简化代码的好方法。

【讨论】:

  • 而且阅读你的代码更有趣 - 我没有意识到你不需要遍历每个项目......非常酷
  • 噗,你会知道什么,约翰。
  • 这里的“优化”是什么意思?代码运行得更快还是可以缩短一段长代码?我认为是后者,但我想我要求确定。
  • @Khnle:我认为它是:更简单、更短的代码、更易于阅读。不太可能对执行时间产生太大影响。
【解决方案2】:

到目前为止,我是这样做的:

// initial description of this code block
$(function() {        
    var container = $("#inputContainer");

    for(var i=0; i < 5; i++) {
        $("<input/>").changed(inputChanged).appendTo(container);
    }; 

    function inputChanged() {
        $.ajax({
            success: inputChanged_onSuccess
        });
     } 

     function inputChanged_onSuccess(data) {
        $.each(container.children(), function(j,w) {
          $(w).unbind().changed(function() {
             //replace the insanity with another refactored function
          });
        });
      }
});

在 JavaScript 中,函数是一等对象,因此可以用作变量。

【讨论】:

  • 我也喜欢这种方法 - 将所有内容保密。除非您希望某些方法是公开的;)
  • 同意;这种方法不会在全局命名空间中留下任何杂物,因为它将所有内容封装在匿名闭包中。 jQuery 的函数式风格倾向于这种模式。 BaileyP 的答案中的 Crockford 的 OOP 模式在您稍后需要引用您的代码块时很有用。
【解决方案3】:

嗯,首先,拥有一个理解 javascript 的优秀 IDE 会大有帮助,即使只是为了识别匹配的分界线(大括号、括号等)。

如果您的代码开始变得如此复杂,请考虑创建自己的静态对象来组织混乱 - 您不必费力地保持所有内容匿名。

var aCustomObject = {
    container: $("#inputContainer"),
    initialize: function()
    {
        for(var i=0; i < 5; i++)
        {
            $("<input/>").changed( aCustomObject.changeHandler );
        }
    },
    changeHandler: function( event )
    {
        $.ajax( {success: aCustomObject.ajaxSuccessHandler} );
    },
    ajaxSuccessHandler: function( data )
    {
        $.each( aCustomObject.container.children(), aCustomObject.updateBindings )
    },
    updateBindings: function( j, w )
    {
        $(w).unbind().changed( function(){} );
    }
}
aCustomObject.initialize();

【讨论】:

  • 我想投票赞成你提到一个好的 IDE 的好处 - 但我想投票反对你建议使用对象来组织代码而不是它们的预期功能。
  • 另一方面,也许您的意思不是将对象用作组织元素而排除其他考虑因素,所以我将怀疑的好处告诉您。
  • 对象的目的不一定是为了组织,虽然这是一个很好的辅助好处,但是为了保持全局命名空间消耗尽可能小。我认为这根本不违背他们的“预期目的”。这种思维方式非常有限。
【解决方案4】:

在我看来,BaileyP 描述的方法是我开始使用的方法,然后我通常将所有内容抽象为更可重用的块,特别是当某些功能扩展到更容易将其抽象为插件的程度时它特定于一个站点。

只要您将大块代码保存在一个单独的文件中并且编码良好,您就可以得到一些非常干净的语法。

// Page specific code
jQuery(function() {
    for(var i = 0; i < 5; i++) {
         $("<input/>").bindWithServer("#inputContainer");
    }
});

// Nicely abstracted code
jQuery.fn.bindWithServer = function(container) {
     this.change(function() {
             jQuery.ajax({
                 url: 'http://example.com/',
                 success: function() { jQuery(container).unbindChildren(); }
             });
     });
}
jQuery.fn.unbindChildren = function() {
    this.children().each(function() {
        jQuery(this).unbind().change(function() {});
    });
}

【讨论】:

    【解决方案5】:

    有人写了一篇关于类似主题的帖子。

    jQuery Code Does not have to be Ugly

    例如,作者 Steve Wellens 建议不要使用匿名函数,因为这会使代码更难阅读。相反,将函数引用推送到 jQuery 方法中,如下所示:

    $(document).ready(DocReady);
    
    function DocReady()
    {       
        AssignClickToToggleButtons();
        ColorCodeTextBoxes();
    }
    

    这篇文章的另一个要点是将一个 jQuery 对象分配给一个具体的变量,这使得代码看起来更干净,更少依赖于实际的 jQuery 对象,并且更容易分辨出某行代码在做什么:

    function ColorCodeTextBoxes()
    {
        var TextBoxes = $(":text.DataEntry");
    
        TextBoxes.each(function()
        {
            if (this.value == "")
                this.style.backgroundColor = "yellow";
            else
                this.style.backgroundColor = "White";
        });
    }
    

    【讨论】:

    • 我最初将此标记为不是答案,但后来意识到这是我有足够的经验来修复自己,所以我编辑了这个以从链接中引入一些内容,这样如果它是休息一下,这篇文章对未来的访问者仍然有用。希望这会有所帮助!
    【解决方案6】:

    将一些匿名函数粘贴到全局范围函数(或您自己的“命名空间”对象)中,尤其是重复使用的函数,它开始看起来不像您发布的那样。有点像您链接的内容。

    【讨论】:

      【解决方案7】:

      我描述了我的方法in your other post。简写形式:

      • 不要混合使用 javascript 和 HTML
      • 使用类(基本上开始将您的应用程序视为小部件的集合)
      • 只有一个 $(document).ready(...) 块
      • 将 jQuery 实例发送到您的类中(而不是使用插件)

      【讨论】:

        【解决方案8】:

        使用http://coffeescript.com/ ;)

        $-> 容器 = $ '#inputContainer' 对于我在 [0...5] $('').change -> $.ajax 成功:(数据)-> 在 container.children() 中为 w $(w).unbind().change -> 警报“呃”

        【讨论】:

        • 不太明白这将如何帮助 OP。但无论如何,+1 向我展示了一些新的和有趣的东西。
        • 我在 3 年多前回答了这个问题,这算作负面声誉吗?这些天所有酷孩子都在使用 Coffeescript。
        • 我猜人们看不到使用 CoffeeScript 如何回答原始问题。尽管可能很有帮助,但使用 CoffeeScript 并不要求以某种方式组织您的代码。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        • 2018-10-12
        • 1970-01-01
        相关资源
        最近更新 更多