错误信息

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls 在 menu_set_active_trail() (行 2405/data/itxueku/includes/menu.inc).

Drupal中JavaScript该怎么写?

浏览:249

drupal项目开发中,不可避免遇到JavaScript的开发,尤其是如客户端的开发,JavaScript几乎承担了大多数业务逻辑,跟Java、PHP等后端语言一样,也需要合理的规划和封装。


本文标题有些标题党的成分,出于简洁原因。本来应该是:《drupal开发中,如何保障大量JavaScript的可维护性》。(注:本文是参加Drupal深圳聚会的演讲题目,因此这里只是做一个简单的摘要)。
drupal-js


目前,JavaScript在Drupal开发中的困境:


1. 必须是jQuery,最好搭配jQueryUI。
2. 各个模块的js大多以闭包开始。
3. 闭包里面添加事件绑定以及业务逻辑函数。
4. Drupal.behaviors的缺点。


第1点导致不便引入其他框架。
2-3导致维护性差,因为很多都是bind事件函数。
此外闭包的IDE支持也比较差(详情见ppt)。
第4点Drupal的behavior有一些缺点,比如效率低,触发所有的behavior,由于很多时候,开发人员并不会考虑重复执行和重复绑定的问题,因此会引起bug等等。



Web项目的重点在于可维护性!!


做网站的人都明白,网站可以一遍一遍的推倒重做,但是真正的商业网站(商业网站不包括企业站),都是有很好的扩展性和维护性,即使重新开发,都是有迹可循的,不是盲目的推倒重来。
不可维护性的网站上线注定就是悲剧!


因此Drupal中的JavaScript一定要有可维护性!!


在本次演讲中,我们以Drupal大学为例,Drupal大学(http://drupal001.net)是一个Drupal开发的Drupal知识问答网站,本身参考知乎的开发,运用了大量的ajax和javascript,所以从一开始就考虑了JavaScript的维护性。


主要有以下几点:


1. 面向对象,命名空间
2. 按照命名空间分包(类)
3. behavior的代替
4. 事件处理
5. 隔离一些html元素(避免由于html id等修改带来的维护性困难)
6. IDE支持以及压缩JS等


面向对象和分包


面向对象就是简单的用JavaScript的静态类封装即可,然后写对应的类的方法。并且每个模块的功能写到对应的模块,按照类分文件。


比如a.question.js, a.flag.js, a.message.js等等,这样一目了然。
具体的写法比较简单:





 a.Question = {
   post: funtion() {
   },
   remove: function() {
   }
 }

上面的写法就是比较容易维护、IDE支持友好(Netbean、Eclipse、PHPStorm都能完整的显示Outline)。


Drupal.behaviors


我们在触发和重新绑定的时候,一般调用Drupal.attachBehaviors,但是我们自己写模块的js时,一般很少考虑多次执行的问题,所有会产生一些意想不到的bug,并且会触发所有的behavior,因此效率也比较低。


如果我们分包了,可以如下写法:





a.Question = {
  Events: {load: {},submit: {}
  }} 
#attach事件
a.Question.Events.load.aaEvt = function() {}a.Question.Events.load.bbEvt = function() {} 
#新的attchBehavior函数 用于触发事件
a.attachBehaviors = function(object, context, op) {
  jQuery.each(object, function() {this(context || document, op);
  });}; 
#调用(触发事件)
a.attchBehaviors(a.Question.Events.load, context);#上面就调用了所有的load事件

这种写法就是有点长,但是IDE一般有提示,也容易记忆,并且有什么事件,Events对象一目了然,不需要再看文档或者找trigger之类的函数。


此外,页面初始化,也重新处理了,比之前单纯的behavior更优雅一些。
详情参考:http://drupal001.net/question/205 (Drupal大学几近完美的UI是如何做出来的?)


JS压缩以及依赖


如果JavaScript不是太大,一般不需要requireJS,因为额外的http请求也是有开销的。加上压缩和打包基本没有太大问题(注意,有些js不要打包)。


Advanced CSS/JS Aggregation:
https://drupal.org/project/advagg


压缩,直接使用apache的压缩即可(效率高),不要用Drupal模块或者PHP压缩,影响服务器性能。


群里之前也有朋友问如何用apache实现压缩,我们这里也贴出来一个解决方案
新建一个 deflate.conf在/etc/http/conf.d下面,贴入以下代码:





   <Location  />AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript
 #NOT Allowed here#DeflateCompressionLevel 9 
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
 
        SetOutputFilter DEFLATE
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
        Header append Vary User-Agent env=!dont-vary</Location>

深圳聚会的PPT下载地址(或者点击上面大图下载):
http://www.drupal001.com/wp-content/plugins/download-monitor/download.ph...




top