jQuery和“有组织的代码”
我一直在努力理解组织jQuery代码的最佳方法。 我之前又问了另外一个问题,我觉得我没有足够的具体( 在这里可以find这个问题 )。
我的问题是,你申请得越丰富,你的客户端越快失控。 考虑这种情况…
//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命令并开始想知道在屏幕开始熔化之前可以添加多less逻辑的情况并不less见。
我的问题是,人们如何pipe理或组织来限制代码的复杂性?
我列出了我在另一篇文章中的做法
只是想补充一下之前提到的那个:
$.each(container.children(), function(j,w) { $(w).unbind().change(function() { ... }); });
可以优化为:
container.children().unbind().change(function() { ... });
这一切都是关于链接的,这是简化代码的好方法。
到目前为止,我这样做:
// 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中,函数是一stream的对象,因此可以用作variables。
那么,有一个理解JavaScript的好的IDE可以帮助很大,即使只是为了确定匹配的分界(大括号,parens等)。
如果你的代码开始真的变得复杂了,那就考虑制作你自己的静态对象来组织这个烂摊子 – 你不必为了保持所有的匿名而努力工作。
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();
在我看来,BaileyP描述的方法是我用来开始的,然后我通常把所有的东西都抽象成更多可重用的块,特别是当一些function扩展到更容易把它抽象成插件的时候,一个网站。
只要你把大块代码保存在一个单独的文件中,并且编码得很好,你就可以得到一些非常干净的语法。
// 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() {}); }); }
有人在类似的话题上写了一篇文章。
jQuery代码不一定是丑陋的
例如,作者Steve Wellensbuild议不要使用匿名函数,因为它使代码难以阅读。 相反,将函数引用推入jQuery方法,如下所示:
$(document).ready(DocReady); function DocReady() { AssignClickToToggleButtons(); ColorCodeTextBoxes(); }
本文的另一个要点是将一个jQuery对象分配给一个具体的variables,这使得代码看起来更干净,更less依赖于实际的jQuery对象,并且更容易地告诉某一行代码在做什么:
function ColorCodeTextBoxes() { var TextBoxes = $(":text.DataEntry"); TextBoxes.each(function() { if (this.value == "") this.style.backgroundColor = "yellow"; else this.style.backgroundColor = "White"; }); }
将一些匿名函数粘贴到全局范围函数(或您自己的“名称空间”对象)中,尤其是重用函数中,并且开始看起来不像您发布的内容。 有点像你链接到的东西。
我在你的另一篇文章中描述了我的方法。 简写:
- 不要混合JavaScript和HTML
- 使用类(基本上开始看你的应用程序作为一个小部件的集合)
- 只有一个$(document).ready(…)块
- 发送jQuery实例到您的类(而不是使用插件)
$ - > container = $'#inputContainer' 因为我在[0 ... 5] $('<input />')。change - > $ .ajax成功:(data) - > 对于container.children()中的w $(w).unbind()。change - > 警惕'呃'