51

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

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

//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 命令的几个级别并开始想知道在屏幕开始融化之前还可以添加多少逻辑的情况并不少见。

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

我在另一篇文章中列出了我是如何做到的...

4

8 回答 8

49

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

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

可以优化为:

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

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

于 2008-10-31T23:08:22.577 回答
18

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

// 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 中,函数是一等对象,因此可以用作变量。

于 2008-10-30T21:37:48.533 回答
8

好吧,一方面,拥有一个理解 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();
于 2008-10-30T21:32:10.043 回答
4

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

jQuery 代码不一定是丑陋的

例如,作者 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";
    });
}
于 2010-02-02T15:14:18.520 回答
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() {});
    });
}
于 2008-10-30T22:59:24.780 回答
2

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

$->
  容器 = $ '#inputContainer'
  对于我在 [0...5]
    $('<input/>').change ->
      $.ajax 成功:(数据)->
        在 container.children() 中为 w
          $(w).unbind().change ->
            警报“呃”
于 2010-10-28T02:58:55.353 回答
2

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

于 2008-10-30T21:30:05.507 回答
2

在你的另一篇文章中描述了我的方法。简写:

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