正确的引入脚本是提升WordPress性能的一个手段,今天碰巧读了一篇文章《How to load JavaScript like a WordPress Master》继而意识到对wp_enqueue_script这个函数还是一知半解,不得不好好学习一下。

功能说明

安全地将 javascript 代码加入到 WordPress 创建的页面中。一般来说,将没有被内置的代码进行添加,并在 WordPress 运行时进行加载。

使用方法

<?php wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); ?>

需要调用wp_enqueue_script函数时,应该将它分配给一个钩子,只在前台调用,使用钩子wp_enqueue_script(action),只在后台调用,使用admin_enqueue_scripts

参数

$handle – 脚本名称,自定义脚本自己命名,不要和其他脚本名字冲突就好

$src – 脚本的路径,绝对不能硬编码,从WordPress 2.6开始,用户可以将wp-content文件夹改名,想象一下硬编码的插件或者主题将会在这之后完全崩溃。获得插件的路径使用plugin_url,获取主题路径可以用get_template_directory_uri,注意这个函数返回的是parent theme的路径,如果你使用child theme,应该调用get_stylesheet_directory_uri。WP模板路径相关的函数中,通常带有template的是指parent theme,带有stylesheet的指向child theme。

$deps – 依赖关系,需要在本代码之前加载的代码的名称。假设你的js脚本一来jquery库,那么这里要用数组的形式写上jquery。

$ver – 版本号。表示代码版本号的字串,将会作为查询字串附加在路径的末尾。默认为 false 。如果没有设置,或者设置为 false ,wordpress 将会自动将 wordpress 的版本号附加在路径的末尾。这个参数用来确保正确的版本信息传递给了客户端,以免受到缓存的影响当你的js脚本或样式表发生变化时,通过更改版本号可以强制客户浏览器下载最新版本),因此如果可以获得合适的版本号就应该使用。如果你不愿意 附加任何版本号信息在路径的末尾,你就必须将本参数设置为 NULL 。将 NULL 进行传递是不被推荐的,所以使用 NULL 之前请确保 NULL 是可行的。

$in_footer – (可选项) 一般代码放置于 <head> 部分。如果将这个参数设置为 ture,代码将被放置在 <body> 部分的末尾。这就需要模板要正确的放置wp_footer()。注意你需要将本功能放置在wp_head之前,相应的代码才能被加载,即使设置了将代码放置在页脚处。

返回值

无返回值

举例

1. 用wp_enqueue_scripts action调用wp_enqueue_scripts函数

用wp_enqueue_scripts引入scriptaculous脚本,可以避免scriptaculous在后台被渲染,当你发现后台的功能出现问题时,很可能是主题或者插件没有正确界定脚本范围引起的,把只在前台使用的脚本引入到后台是导致后台功能出错的常见原因。使用下面的代码,可以避免混乱

<?php
function my_scripts_method() {
    wp_enqueue_script('scriptaculous');            
}    
 
add_action('wp_enqueue_scripts', 'my_scripts_method'); // For use on the Front end (ie. Theme)
?>

只在后台引入,将

add_action('wp_enqueue_scripts', 'my_scripts_method');

换成

add_action('admin_enqueue_scripts', 'my_scripts_method');

2. 从插件中引入依赖于scriptaculous的新脚本newscript

<?php
function my_scripts_method() {
   wp_enqueue_script('newscript',
     /* WP_PLUGIN_URL . '/someplugin/js/newscript.js', // 过时的方法,不兼容SSL*/
     plugins_url('/js/newscript.js', __FILE__), // where the this file is in /someplugin/
     array('scriptaculous'),
     '1.0' );
}    
 
add_action('wp_enqueue_scripts', 'my_scripts_method');
?>

3. 从主题中引入依赖于WordPress已有js脚本的js文件

<?php
function my_scripts_method() {
   // register your script location, dependencies and version
   wp_register_script('custom_script',
       get_template_directory_uri() . '/js/custom_script.js',
       array('jquery'),
       '1.0' );
   // enqueue the script
   wp_enqueue_script('custom_script');
}
add_action('wp_enqueue_scripts', 'my_scripts_method');
?>

4. 只在后台插件页面引入脚本

<?php
    add_action( 'admin_init', 'my_plugin_admin_init' );
    add_action( 'admin_menu', 'my_plugin_admin_menu' );

    function my_plugin_admin_init() {
        /* Register our script. */
        wp_register_script( 'my_plugin_script', plugins_url('/script.js', __FILE__) );
    }

    function my_plugin_admin_menu() {
        /* Register our plugin page */
        $page = add_submenu_page( 'edit.php', // The parent page of this menu
                                  __( 'My Plugin', 'myPlugin' ), // The Menu Title
                                  __( 'My Plugin', 'myPlugin' ), // The Page title
				  'manage_options', // The capability required for access to this item
				  'my_plugin-options', // the slug to use for the page in the URL
                                  'my_plugin_manage_menu' // The function to call to render the page
                               );

        /* Using registered $page handle to hook script load */
        add_action('admin_print_styles-' . $page, 'my_plugin_admin_styles');
    }

    function my_plugin_admin_styles() {
        /*
         * It will be called only on your plugin admin page, enqueue our script here
         */
        wp_enqueue_script( 'my_plugin_script' );
    }

    function my_plugin_manage_menu() {
        /* Output our admin page */
    }
?>

5. jQuery noConflict模式

注意:jQuery在WordPress中默认工作在"no conflict"模式,该模式下jQuery不再使用$符号,避免和其它脚本冲突,在WordPress中要使用$符号时,应该用jQuery代替,也就是说下面的脚本

$(document).ready(function(){
     $(#somefunction) ...
});

应该写成

jQuery(document).ready(function(){
    jQuery(#somefunction) ...
});

如果无论如何都要使用$符号,也不是没办法,可以这样做

jQuery(document).ready(function($) {
    // $() will work as an alias for jQuery() inside of this function
});

jQuery(document).ready保证脚本在页面DOM元素全部加载后才会执行(还可以用load事件,load会等待图片载入),如果你想让脚本立刻执行,不用等待DOM元素加载,可以用下面的方法

(function($) {
    // $() will work as an alias for jQuery() inside of this function
})(jQuery);

6. wp_enqueue_script可以用那些钩子渲染

wp_enqueue_script函数位于wp-includes/functions.wp-scripts.php/中。

可以执行它的钩子有wp_enqueue_scripts、admin_enqueue_scripts和init

5条留言

  1. Hi Sola,
    又来请教了,呵呵
    我想 只在首页 调用wordpress默认jQuery库,其它页面调用自定义的JS,这个再function.php里面怎么写?
    我尝试下面2种方法,都不行,
    第一种:

    //if (is_home() || is_front_page()) {
    //wp_head();
    //} else {
    //wp_deregister_script('jquery');wp_head();
    //}

    第二种


    //function wpbootstrap_scripts_with_jquery()
    //{
    // wp_register_script( 'custom-script', get_template_directory_uri() . '/bootstrap/js/bootstrap.min.js' );
    // wp_register_script('jquery-new', ("http://code.jquery.com/jquery-1.11.0.min.js") );
    // if ( !is_admin() || is_home() || is_front_page()) {
    // wp_deregister_script( 'custom-script' );
    // wp_deregister_script( 'jquery-new' );

    // }
    // else {
    // wp_enqueue_script( 'custom-script' );
    // wp_enqueue_script( 'jquery-new' );
    // }

    //}
    //add_action( 'wp_enqueue_scripts', 'wpbootstrap_scripts_with_jquery' );

    1. jquery不会自动加载,所以这样应该可以

      function wpbootstrap_scripts_with_jquery(){
      	if( is_home() || is_front_page() ){
      		wp_enqueue_script(&#039;jquery&#039;);
      	} else {
      		wp_enqueue_script(&#039;custom-script&#039;, &#039;script source&#039;);
      	}
      }
      add_action( &#039;wp_enqueue_scripts&#039;, &#039;wpbootstrap_scripts_with_jquery&#039; );
      

      前提是header.php里要写上wp_head(),否则无效。
      还有一点,如果别的插件已经调用了jquery,就要用wp_dequeue_script()解除加载,但你调用wp_dequeue_script必须是在它调用wp_enqueue_script之后,如果它用了init action,就要泪奔了。

      1. 谢谢谢谢,搞定了,看来顺序不能错,
        顺便问下,你上面说的“如果它用了init action,就要泪奔了”,这是啥概念,不是很明白

        1. 标准用法是通过wp_enqueue_scripts action加载脚本,用init的要不就是文档读的不够,要么就是随心所欲的高手,对初学者来说这两者都不是最佳选择。

评论功能已关闭