上海戴文 - Drupal开发专家

你在这里

Drupal中的JavaScript和jQuery

主标签

使用JavaScript会给网站的主题增添很多动态的演出效果。为了添加自定义的JavaScript文件,Drupal的开发者们觉得jQuery是非常方便的。

jQuery是一个轻量级的JavaScript库,并且Drupal默认已经整合该库文件。jQuery中已经遍布了所有共通的DOM,事件,特效以及Ajax功能。

Drupal7中已经绑定了jQuery 1.4.4和jQuery UI 1.8.7。Drupal6.0到6.2中绑定了jQuery 1.2.3,Drupal6.3中绑定了jQuery 1.2.6 的升级版。

模块开发过程中如果需要最新版的jQuery,可以使用jQuery update 模块。当通过Drupal在页面中添加JavaScript时,jQuery也会自动的被添加到该页面。

关于jQuery的详细信息可参考 jQuery APIDocumentation

 

添加JavaScript

主题中添加JavaScript有两种方法。

.info File内添加描述

可以在主题的info文件中以script标签的方式添加JavaScript。例如在Drupal的所有页面中需要添加foo.js时,可以在info文件中如下描述。

scripts[] = foo.js

 

主题的info文件中描述的JavaScript会在页面生成的过程阶段(core/library以及各个模块的js脚本被加载之后)被添加。理解这个加载顺序是非常重要的。

也就是说当模块中的js脚本提供了页面中的相当功能之后,主题中的js脚本才有运行的机会。

Drupal6中只要在主题中创建名称为script.js的脚本,可以不通过在info文件中进行指定,该脚本会成为默认的脚本运行在所有的页面内。而Drupal7中取消了此机制,所有的默认js脚本都必须在info中进行指定。

 

template.php内描述

也可以在templete.php文件中使用drupal_add_js()函数添加js脚本(或者在drupal7中也可以使用drupal_add_library() )。例如想要在主题的根目录下添加foo.js脚本。

 

drupal6下

<?php

function example_preprocess_page(&$variables) {

  drupal_add_js(drupal_get_path('theme', 'example'). '/foo.js', 'theme');

  //在此处添加时需要对scripts变量进行重构。

  $variables['scripts'] = drupal_get_js();

}

?>

 

drupal7下

<?php

function example_preprocess_html(&$variables) {

  $options = array(

    'group' => JS_THEME,

  );

  drupal_add_js(drupal_get_path('theme', 'example'). '/foo.js', $options);

}

?>

 

drupal7中无需对变量scripts进行重构。$scripts会在template_preprocess_html阶段中被生成并加载。

Drupal7中增加了libraay管理的机制。所谓library为JavaScript,CSS以及依赖库的合集。例如Drupal7中导入jQuery UI。

jQuery UI是一个内部存在很多相互依赖关系的库合集。当加载ui.autocomplete 的同时,其依赖的ui.core 和ui.position 也需要被加载。

Drupal的library会承担这些依赖关系的管理。加载ui.autocomplete所需要的CSS,JS以及依赖库时,需要进行一下描述。

<?php

drupal_add_library('system', 'ui.autocomplete');

?>

 

仅仅上述一个函数就可以实现加载jquery.ui.autocomplete.js 和jquery.ui.autocomplete.css,以及其所依赖的jquery.ui.position.js,jquery.ui.widget.js,

jquery.ui.core.js,jquery.ui.core.css、jquery.ui.theme.css。详细可参考drupal_add_library see the API documentation

JavaScript的闭包

js代码中加入闭包是非常实用的体验。闭包可以起到限制变量的作用域以防止错误的覆盖全局变量。

 

// 定义新函数

(function () {

  // 此处定义的变量不会影响到全局。

  var window = "Whoops, at least I only broke my code.";

  console.log(window);

  // 通过下边的括号可以在此处执行定义的函数。

}());

// 闭包中的代码不会对其他地方产生影响。

console.log(window);

 

使用闭包还有一个好处。jQuery可以作为此函数的参数进行传递。当使用【$ 】时,可以不用在意是否调用jQuery.noConflict(),使用$()作为快捷键进行编码。

 

 // 定义参数为「 $ 」

(function ($) {

  // jQuery可以通过快捷键「 $ 」表述。

  console.log($.browser);

 // 此处的参数可以传递jQuery。

}(jQuery));

 

drupal7中为了能够使用其他的JS库采用了调用jQuery.noConflict()的方法。因此你可以使用类似jQuery() 或使用闭包的机制进行编码。

 

JavaScript的behavior

Drupal针对页面上的元素为了能够提供一元化的JavaScript功能机制,采用了一种称为【behavior】的机制。采用behavior把功能集中到一起,其优势在于当最初页面被加载,其后即使通过AHAH/AJAX页面内容产生变化,也能保持一贯性。Drupal7中的behavior规定了2个函数。一个为把要素加载到页面时,另一个为当要素在页面中被删除时会分别被调用到。behavior作为Drupal.behaviors的属性被定义并进行注册。当Drupal调用每个behavior时,第一个参数为DOM元素(Drupal7中第二个参数为设置对象)。为了能够效率化使用它们,使用behavior的函数时最好以下两个要点要牢记。

  • jQuery中传递context 参数,作用域要限定在context元素及其子孙范围内。
  • 要避免对相同元素的重复处理。drupal6中为了限制选择器其标记使用了class。: jQuery('.foo:not(.foo-processed)', context).addClass('foo-processed').css('color', 'red'); drupal7中使用了内核嵌入的Once插件。: jQuery('.foo', context).once('foo').css('color', 'red');

我们看一个简单的示例。例如我们想把<a href="https://example.com">Example</a>改成 <a href="https://example.com">Example (Secure!)</a>,也就是页面中所有https

协议的链接需要显示其为安全字样的文本。此情况下如果执行两次处理会变成「 Example (Secure!) (Secure!) 」,避免重复处理是非常重要的。

drupal6中会这样写:

// 使用闭包把jQuery 映射为$

(function ($) {

  // 注册函数并使其为Drupal.behaviors的属性。

  Drupal.behaviors.myModuleSecureLink = function (context) {

    // 寻找还没有处理完的安全链接(已处理的会标记相关的class)

    $('a[href^="https://"]:not(.secureLink-processed)', context)

      // 找到后添加作为已处理的class。

      .addClass('secureLink-processed')

      // 插入文本表明此为安全链接。

      .append(' (Secure!)');

  };

 

  // behavior中还需添加函数时可以在此处继续定义。

  Drupal.behaviors.myModuleMagic = function(context) {};

}(jQuery));

 

drupal7中为了实现当页面中添加新元素并被生效以及当元素消失时的相关运行,其描述方法与drupal6有略少差异。

// 使用闭包把jQuery 映射为$

(function ($) {

  //  注册函数并使其为Drupal.behaviors的属性。

  Drupal.behaviors.myModuleSecureLink = {

    attach: function (context, settings) {

      // 寻找还没有处理完的安全链接(已处理的会标记相关的class)

      $('a[href^="https://"]', context)

        // 避免重复处理。

        .once('secureLink')

        // 插入文本表明此为安全链接。

        .append(' (Secure!)');

    }

  }

 

  //behavior中还需添加函数时可以在此处继续定义。

  Drupal.behaviors.myModuleMagic = {

    attach: function (context, settings) { },

    detach: function (context, settings) { }

  };

}(jQuery));

 

JavaScript主题

Drupal与通常的主题同样针对JavaScript也提供了主题机制。因此JavaScript所生成的markup可以通过主题进行自定义。

模块可以提供生成markup的主题函数。例如以下代码表示生成"powered by Drupal"图标的名为powered主题函数。

Drupal.theme.prototype.powered = function(color, height, width) {

  return '<img src="/misc/powered-'+ color +'-'+ height +'x'+ width +'.png" />';

}

可以再模块中使用以下代码插入生成的markup。

$('.footer').append(Drupal.theme('powered', 'black', 135, 42));

 

由此页面中class为footer的元素内可以插入如下的markup。

<img src="http://drupal.org/misc/powered-black-135x42.png" />

 

使用主题更改markup输出时,可以通过替换主题函数时来实现。以下代码是主题中使用的主题函数示例。

Drupal.theme.powered = function(color, height, width) {

  return '<div class="powered-'+ color +'-'+ height +'x'+ width '"></div>';

}

 

模块中的主题函数为Drupal.theme.prototype.powered 时,主题中可以通过「 Drupal.theme.powered 」来覆盖。

主题中通过js读取此主题函数时之前的代码

$('.footer').append(Drupal.theme('powered', 'black', 135, 42));

其结果会变为<div class="powered-black-135x42"></div>。

JavaScript 的主题函数其返回值完全是自由的。不仅仅是字符串,数组和对象以及jQuery的元素等复杂的数据结构都可以作为返回值。

drupal中关于JavaScript以及jQuery的详细信息可以参考开发者指南中的 JavaScript section 章节。

另外JavaScript以及jQuery的相关讨论及建议可以通过参加社区http://groups.drupal.org/javascript

 

原文地址:JavaScript と jQuery

 

Drupal 版本: 

猜你喜欢