Adds a JavaScript file, setting, or inline code to the page.
The behavior of this function depends on the parameters it is called with. Generally, it handles the addition of JavaScript to the page, either as reference to an existing file or as inline code. The following actions can be performed using this function:
(function ($) {... })(jQuery);
or use jQuery() instead of $().
Examples:
drupal_add_js('misc/collapse.js');
drupal_add_js('misc/collapse.js', 'file');
drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline');
drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => 5,
));
drupal_add_js('http://example.com/example.js', 'external');
drupal_add_js(array(
'myModule' => array(
'key' => 'value',
),
), 'setting');
Calling drupal_static_reset('drupal_add_js') will clear all JavaScript added so far.
If JavaScript aggregation is enabled, all JavaScript files added with $options['preprocess'] set to TRUE will be merged into one aggregate file. Preprocessed inline JavaScript will not be aggregated into this single file. Externally hosted JavaScripts are never aggregated.
The reason for aggregating the files is outlined quite thoroughly here: http://www.die.net/musings/page_load_time/ "Load fewer external objects. Due to request overhead, one bigger file just loads faster than two smaller ones half its size."
$options['preprocess'] should be only set to TRUE when a file is required for all typical visitors and most pages of a site. It is critical that all preprocessed files are added unconditionally on every page, even if the files are not needed on a page. This is normally done by calling drupal_add_js() in a hook_init() implementation.
Non-preprocessed files should only be added to the page when they are actually needed.
$data: (optional) If given, the value depends on the $options parameter, or $options['type'] if $options is passed as an associative array:
$options: (optional) A string defining the type of JavaScript that is being added in the $data parameter ('file'/'setting'/'inline'/'external'), or an associative array. JavaScript settings should always pass the string 'setting' only. Other types can have the following elements in the array:
The group number serves as a weight: JavaScript within a lower weight group is presented on the page before JavaScript within a higher weight group.
The current array of JavaScript files, settings, and in-line code, including Drupal defaults, anything previously added with calls to drupal_add_js(), and this function call's additions.
function drupal_add_js($data = NULL, $options = NULL) {
$javascript =& drupal_static(__FUNCTION__, array());
$jquery_added =& drupal_static(__FUNCTION__ . ':jquery_added', FALSE);
// If the $javascript variable has been reset with drupal_static_reset(),
// jQuery and related files will have been removed from the list, so set the
// variable back to FALSE to indicate they have not yet been added.
if (empty($javascript)) {
$jquery_added = FALSE;
}
// Construct the options, taking the defaults into consideration.
if (isset($options)) {
if (!is_array($options)) {
$options = array(
'type' => $options,
);
}
}
else {
$options = array();
}
if (isset($options['type']) && $options['type'] == 'setting') {
$options += array(
'requires_jquery' => FALSE,
);
}
$options += drupal_js_defaults($data);
// Preprocess can only be set if caching is enabled.
$options['preprocess'] = $options['cache'] ? $options['preprocess'] : FALSE;
// Tweak the weight so that files of the same weight are included in the
// order of the calls to drupal_add_js().
$options['weight'] += count($javascript) / 1000;
if (isset($data)) {
// Add jquery.js, drupal.js, and related files and settings if they have
// not been added yet. However, if the 'javascript_always_use_jquery'
// variable is set to FALSE (indicating that the site does not want jQuery
// automatically added on all pages) then only add it if a file or setting
// that requires jQuery is being added also.
if (!$jquery_added && (variable_get('javascript_always_use_jquery', TRUE) || $options['requires_jquery'])) {
$jquery_added = TRUE;
// url() generates the prefix using hook_url_outbound_alter(). Instead of
// running the hook_url_outbound_alter() again here, extract the prefix
// from url().
url('', array(
'prefix' => &$prefix,
));
$default_javascript = array(
'settings' => array(
'data' => array(
array(
'basePath' => base_path(),
),
array(
'pathPrefix' => empty($prefix) ? '' : $prefix,
),
),
'type' => 'setting',
'scope' => 'header',
'group' => JS_LIBRARY,
'every_page' => TRUE,
'weight' => 0,
),
'misc/drupal.js' => array(
'data' => 'misc/drupal.js',
'type' => 'file',
'scope' => 'header',
'group' => JS_LIBRARY,
'every_page' => TRUE,
'weight' => -1,
'requires_jquery' => TRUE,
'preprocess' => TRUE,
'cache' => TRUE,
'defer' => FALSE,
),
);
$javascript = drupal_array_merge_deep($javascript, $default_javascript);
// Register all required libraries.
drupal_add_library('system', 'jquery', TRUE);
drupal_add_library('system', 'jquery.once', TRUE);
}
switch ($options['type']) {
case 'setting':
// All JavaScript settings are placed in the header of the page with
// the library weight so that inline scripts appear afterwards.
$javascript['settings']['data'][] = $data;
break;
case 'inline':
$javascript[] = $options;
break;
default:
// 'file' and 'external'
// Local and external files must keep their name as the associative key
// so the same JavaScript file is not added twice.
$javascript[$options['data']] = $options;
}
}
return $javascript;
}