jQuery and “Organized Code”
我最近一直在努力理解组织jquery代码的最佳方法。我之前问了另一个问题,我觉得我不够具体(在这里的这个问题中找到)。
我的问题是,应用程序越丰富,客户端越快失控。考虑这种情况…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | //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命令中有几个级别,并开始怀疑在屏幕开始融化之前,还能添加多少逻辑。
我的问题是,人们如何管理或组织以限制其代码的复杂性?
我在另一篇文章中列出了我是如何做到这一点的…
只是想补充一下前面提到的内容:
1 2 3 | $.each(container.children(), function(j,w) { $(w).unbind().change(function() { ... }); }); |
可优化为:
1 | container.children().unbind().change(function() { ... }); |
这都是关于链接的,一种简化代码的好方法。
到目前为止,我是这样做的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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中,函数是第一类对象,因此可以用作变量。
好吧,首先,拥有一个理解JavaScript的好的IDE可以非常有帮助,即使只是识别匹配的分界(大括号、parens等)。
如果你的代码真的开始变得如此复杂,考虑制作你自己的静态对象来组织混乱——你不必那么努力工作来保持所有的匿名性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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(); |
有人写了一篇关于类似主题的文章。
jquery代码不必是丑陋的
例如,作者SteveWellens建议不要使用匿名函数,因为这会使代码更难阅读。相反,将函数引用推送到jquery方法中,如下所示:
1 2 3 4 5 6 7 | $(document).ready(DocReady); function DocReady() { AssignClickToToggleButtons(); ColorCodeTextBoxes(); } |
本文的另一个要点是将jquery对象分配给一个具体的变量,这使得代码看起来更干净,对实际的jquery对象的依赖性更低,并且更容易分辨某一行代码在做什么:
1 2 3 4 5 6 7 8 9 10 11 12 | function ColorCodeTextBoxes() { var TextBoxes = $(":text.DataEntry"); TextBoxes.each(function() { if (this.value =="") this.style.backgroundColor ="yellow"; else this.style.backgroundColor ="White"; }); } |
在我看来,Baileyp所描述的方法是我开始使用的方法,然后我通常将所有内容抽象成更多的可重用块,特别是当某些功能扩展到更容易将其抽象为插件的程度,然后将其特定于一个站点时。
只要将大块代码保存在单独的文件中并进行良好的编码,就可以得到一些真正干净的语法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // 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() {}); }); } |
使用http://coffeescript.com/;)
1 2 3 4 5 6 7 8 | $ -> container = $ '#inputContainer' for i in [0...5] $('<input/>').change -> $.ajax success: (data) -> for w in container.children() $(w).unbind().change -> alert 'duh' |
我在你的另一篇文章中描述了我的方法。简短形式:
- 不要混合使用JavaScript和HTML
- 使用类(基本上开始将应用程序视为小部件的集合)
- 只有一个$(document).ready(…)块
- 将jquery实例发送到类中(而不是使用插件)
将一些anon函数粘贴到全局范围函数(或您自己的"namespace"对象)中,尤其是重用的函数中,它开始不像您发布的那样。有点像你所联系的。