|
|
51CTO旗下网站
|
|
移动端

MooTools团队成员:我们为何强于jQuery

文章的作者是MooTools Team的成员之一,本文他主要讲解了jQuery和MooTools的区别,同时也分享了他写JavaScript代码的方式和思维。

作者:Fdream 译来源:fdream's博客|2010-09-30 09:04

jQuery非常容易学习,有很杰出的特性,但是当你从插件库里去找更多的功能时,发现官方的库里面根本就没有。插件特性非常好,但是也有很不好的地方……很快你就会被无数个可用的插件弄得晕头转向,你需要花很多时间去确定哪些插件才和核心库的质量相匹配。

因此,我必须首先很轻而易举地证明:jQuery是最受欢迎以及有更好表现的框架。他们是最好的。John Resig(jQuery的作者)在三天里曾七次说:“Microsoft演示了怎样把jQuery包含进了它的SDK,出席会议的人也非常肯定地谈论了这个框架。这些都清楚地让我看到:jQuery正在做一些正确的事情。”

我去参加这个会议的一部分任务就是尽可能多地参与jQuery的交流和学习(我曾经也很深入地学习过,但是我希望从开发团队和John那里学习到更多东西),同时也可以看一下我是否能够找到这个框架受欢迎的原因。

jQuery  MooTools

这里需要一些解释。MooTools团队从来没有真正关注过这个框架有多受欢迎。我们只是对写这个框架感兴趣,为我们自己使用和它本身目的去写,但是我们真的没有花很多精力去让其他人去使用这个框架。我们从不认为其它框架是我们的竞争对手——因为我曾经在很多场合都听说过这样的话,我们在和浏览器进行斗争,而不是相互斗争。在我的这篇文章中,我给你们的建议是:多尝试一些选 择,然后选择适合你的需求和你的风格的框架。你真的不能做一个坏的选择(因此,请停止争吵!)。jQuery、Prototype、YUI、Dojo、 MooTools——我们都只是用不同的方法在做同样的事。关于这一点写得有点多,因为我最近一直在思考这个。

Bill Scott在继续教我一些事情

当这个事情还在Boston的时候,我偶然遇见了Bill Scott。Bill是Yahoo的YUI团队的领导者,是一个很好的演讲者(尽管他在Boston的时候只做了一个关于他当前工作的五分钟的“闪电演 讲”)。一段时间以前,他帮助开始了Rico框架的开发,随后转到了YUI。接着在一年前,他离开了Yahoo,去了Netflix,带领团队做了许多工 作——不只是JavaScript(更多地关注了他们的新API和用户体验)。Netflix也在使用jQuery,因此我有机会和他坐下来谈论这些事 情。

在这里我要小心一些,并提醒正在阅读这篇文章的各位读者,我没有任何关于 jQuery的坏话要说,我也不想在这篇文章或者其他文章中挑起一场无谓的争论。jQuery和MooTools(以及Prototype、Dojo、 YUI等等等等)都是不同的而且没有相互竞争。它们用不同的方式解决问题,而我,就个人而言,碰巧喜欢Moot解决问题的方式以及它尝试解决问题的方式。 由于我还在学习jQuery,因此很容易我可能就会写一些不正确的jQuery语句,如果我有什么说得不正确的地方,还请大家谅解。

编程模式

在和Bill的谈话中,我说了我的一些关于“编程模式”的思考。我所谓的“编程模式”是这样的:当我写我的代码的时候,我可以选择做一个架构师,或者一个代码编写者。我可以设计,我也可以实施。事实上,我必须都做,但是我必须选择我更想做的一个,而且,在许 多情况下,不论是我还是其他人,都可能一个人去完成几乎所有的工作——尽管不是100%。

我究竟在说些什么?让我这样跟你讲:如果你写了20行代码,来描述一个页面上的用户交互,以便使页面看起来很 漂亮或者很易用,那么它是不是值得再多写5行或者10行代码来使其可以被重复使用?如果你只是依据经验直接编程,那么你需要写一遍又一遍。但是如果你按照 模式来写,你要写的代码会越来越少。

假设有这样一个用户体 验:当哟哦难怪乎点击“log in”按钮的时候,显示一个登陆框。当用户点击“log in”的时候,这个登陆框就出现。用户提交登陆表单,登陆框发出一个ajax请求并显示一个提示信息。当请求完成时,这个登陆框告诉用户已经登陆了并在过 一会儿后消失。

我可以用JavaScript来表现这些,就写在当前这个页面上或 者在我的全站代码里面(可能这个登陆框在每个页面上都有,是吧?)。它可能是这样一段代码(我会在某种程度上省略一些代码)——注意:我这里使用的是MooTools的语法,不过它看起来和现在的大多数框架都差不多,因为我们都相互借鉴好的点子:

  1. window.addEvent('domready', function(){  
  2.      $('loginLink').addEvent('click', function(e){  
  3.          e.stop(); //don't follow the link  
  4.          $('loginPopup').show();  
  5.      });  
  6.      //loginPopup contains loginForm  
  7.      $('loginForm').addEvent('submit', function(e){  
  8.          e.stop(); //don't submit the form  
  9.          $('loginForm').send({  
  10.              onComplete: function(result) {  
  11.                  $('loginPopup').set('html', result); //show the result  
  12.                  (function(){  
  13.                      $('loginPopup').hide();  
  14.                  }.delay(1000)); //wait a sec, then hide the popup  
  15.              }  
  16.          })  
  17.      });  
  18. }); 

美丽的直接了当,是吧?但是我们退后一步,然后问我们自己:这是什么模式呢?我们能再看到它的一部分吗?当然,一个弹出层包含一个form,然后提交、更新自己,然后做一些其它事情,而且可以再次出现。是吧?

这就是我所说的“编程模式”。在我以前的代码中,我 可能像上面的那样写代码。如果它是我的网站的一部分,我可能有一个名字空间(namespace)并且给它们一个叫做“showLogin”的方法,然后 在on domready事件中调用mySite.showLogin。或者,更可能是这样子的,我的网站需要很多这样的方法。showLogin、 logOut、makeToolTips、autoScroll、setupDraggers等等。然后我会写一个叫做mySite.init的方法来调 用所有的这些方法。

但是在回头看看我的老代码,我可能有一个巨大的domready方法,里面包括了所有的这些布局和交互的指令,一个很大的启动方法。

如果你从来没有写过这样的代码,你永远也不会知道维护这个代码的乐 趣。它会花费大量的精力去理解在第一件事情之后该是什么事情。再回头看看上面的示例代码,想像一下,如果我们遇到了类似的事情,但是有这个的3倍、5倍或 者10倍长,然后再想像一下一年以后我们再次碰到类似的事情。仅仅只是拆分这些行为就已经非常令人可怕了。

现在,让我们按照模式编程。一个弹出层,有一个form,并且自动更新。这就是我们要重复出现的模式。下面是一个MooTools类,实现了同样的东西:

  1.  var PopupForm = new Class({  
  2.      Implements: [Events, Options],  
  3.      options: {  
  4.          requestOptions: {/*the user can fill in additional ajax options*/},  
  5.          onComplete: $empty //do nothing on complete by default  
  6.      },  
  7.      initialize: function(link, form, popup, options) {  
  8.          this.form = $(form);  
  9.          this.link = $(link);  
  10.          this.popup = $(popup);  
  11.          this.setOptions(options);  
  12.          this.makeRequest();  
  13.          this.attach();  
  14.      },  
  15.      makeRequest: function(){  
  16.          thisthis.request = this.form.retrieve('send', this.options.requestOptions);  
  17.          this.request.addEvent('complete', function(response){  
  18.              popup.set('html', response);  
  19.              this.fireEvent('complete');  
  20.          }.bind(this));  
  21.      },  
  22.      attach: function(){  
  23.          this.link.addEvent('click', this.show.bind(this));  
  24.          this.form.addEvent('submit', function(e){  
  25.              e.stop();  
  26.              this.request.send();  
  27.          }.bind(this));  
  28.      },  
  29.      show: function(){  
  30.          this.popup.show();  
  31.      },  
  32.      hide: function() {  
  33.          this.popup.hide();  
  34.      }  
  35. }); 

现在,不可否认的是我的类已经有两倍长了,但是它还仍然没有与我的登陆链接关联起来。要使其生效,我还需要对它进行初始化:

  1. window.addEvent('domready', function(){  
  2.     new PopupForm($('loginLink'), $('loginForm'), $('loginPopup'), {  
  3.         onComplete: function(){  
  4.             (function(){  
  5.                 this.hide();  
  6.             }.delay(1000, this)); //wait a sec, then hide the popup  
  7.         }  
  8.     })  
  9. }); 

有所取舍,但追求最大利益

除了代码变成了以前的两倍长以外,我还需要其他的9行代码去完成这个事情。15行代码和42行代码,看起来并不是个好的交易,但是我最近在我的所有代码里面都是这样写的。通过变换到这种思考方式,我从写很多很多代码段中解放出来,也节约了很多我以前根本没有考虑到的时间。

◆代码现在更加清晰易读了。我有一些很小的方法,它们只做一件事情,但是我知道它们在做什么以及为什么做。我的类的名字描述了它们要做的事情,而且它们也很小,也只做一件事情。如果我需要一个做两件事情的类,我会写两个类和一个小的控制类来调用它们。

◆代码可以重复使用——如果这个模式再度出现,我不需要再重复写这些代码。我曾经被它们出现的频率吓倒。我从来没有想过要重用一周以内的代码,但是我现在又开始重新使用他们了。

◆应用程序在哪——我现在正在做的web页面上,我的代码一般都很少。我不给页面单独写多少代码——我所做的只是针对每个给定的页面元素实例化一些类。这些小的“脚印”(页面执行时间?)意味这越少的代码对页面越好。

◆什么时候需要重构——可能我现在使用的框架已经有新的版本了,或者发现了一个新的浏览器bug,或者一个先的浏览器冲击了市场(例如Chrome),或者 我在自己的代码里面发现了一个bug(这是这几个原因里面最常见的),我需要立即修正它们。如果我为每个页面都写了有代码,那么我将需要一一修正。从另外 一个方面来说,如果我的页面只是实例化了我的几个