WordPress 引入 css/js 方法很多,条件很多。如何全局加载,或仅在某些页面精准加载,什么时候需要先注册脚本再加载,本文希望找到最简单的方式,并给出探索更多方法的途径。

在前台加载 css/js
用 wp_enqueue_script() 函数加载 js,用 wp_enqueue_style() 加载 css,加载资源的位置 (action) 只有一个——wp_enqueue_scripts 。

用 wp_enqueue_系列函数可以更好的处理脚本样式表的依赖关系,防止重复加载,以 twentyfifteen 主题为例。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

functiontwentyfifteen_scripts(){

    //全局加载一般的样式表

    wp_enqueue_style('genericons',get_template_directory_uri().'/genericons/genericons.css',array(),'3.2');

    //全局加载主样式表

    wp_enqueue_style('twentyfifteen-style',get_stylesheet_uri());

    //全局加载仅用于 IE 的样式表

    wp_enqueue_style('twentyfifteen-ie',get_template_directory_uri().'/css/ie.css',array('twentyfifteen-style'),'20141010');

    wp_style_add_data('twentyfifteen-ie','conditional','lt IE 9');

    //全局加载 js 脚本

    wp_enqueue_script('twentyfifteen-script',get_template_directory_uri().'/js/functions.js',array('jquery'),'20141212',true);

    //给 js 脚本传递变量,解决脚本中不能调用 php 的问题

    wp_localize_script('twentyfifteen-script','screenReaderText',array(

        'expand'   =>'<span >'.__('expand child menu','twentyfifteen').'</span>',

        'collapse'=>'<span >'.__('collapse child menu','twentyfifteen').'</span>',

    ));

}

add_action('wp_enqueue_scripts','twentyfifteen_scripts');

若仅在某些页面加载,利用 WordPress 的 Conditional Tags 即可。

什么时需要先注册 css/js
即何时需要使用 wp_register_script() 和 wp_register_style() 函数。

当 css/js 很多,并且要分情况加载时,使用 wp_register_script() 可以更好的管理资源,避免重复劳动。下面的示例代码中,先在 init action 上把所有需要用到样式表都注册一遍,之后不管想在哪里引入,都可以简单的用 wp_enqueue_style( $handle ) 来加载。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

// 在 init action 处注册脚本,可以与其它逻辑代码放在一起

functionmy_init(){

    $url=get_template_directory_uri();

    // 注册样式表

    $styles=array(

        'style1'=>$url.'/css/style1.css',

        'style2'=>$url.'/css/style2.css',

        'style3'=>$url.'/css/style3.css'

    );

    foreach($styles as$k=>$v){

        wp_register_style($k,$v,false);

    }

    // 注册脚本

    // 其它需要在 init action 处运行的脚本

}

add_action('init','my_init');

注册脚本时需要运行 $wp_scripts->add( $handle, $src, $deps, $ver );,若脚本没有注册直接使用 wp_enqueue_script,需要先调用 add 方法,也就是说重复 enqueue 一个脚本就会运行多次 add 方法,降低了程序的效率。

在 WordPress 登录页面加载
将 action 替换为 login_enqueue_scripts 即可,例如

functionenqueue_for_login(){

    wp_enqueue_style('core','style.css',false);

    wp_enqueue_script('my-js','filename.js',false);

}

add_action('login_enqueue_scripts','enqueue_for_login');

如果想了解其它方式,可以仔细阅读 wp-login.php 。

在后台全局加载
同理,将 action 改为 admin_enqueue_scripts

functionmy_enqueue(){

    wp_enqueue_script('my_custom_script',plugin_dir_url(__FILE__).'myscript.js');

}

add_action('admin_enqueue_scripts','my_enqueue');

想了解更多方法,请阅读 wp-admin/admin-header.php 。

在后台按需加载
仅用于后台某些页面的资源只在这些页面加载就好,不要到处使用,可以减少不必要的冲突。

1. $hook_suffix

首先我们可以根据 admin_enqueue_scripts 这个 action 传递的 $hook_suffix 参数来判断所处的页面,例如仅在 edit.php 加载,代码如下

functionmy_enqueue($hook_suffix){

    if('edit.php'==$hook_suffix){

       wp_enqueue_script('my_custom_script',plugin_dir_url(__FILE__).'myscript.js');

    }  

}

add_action('admin_enqueue_scripts','my_enqueue');

edit.php 就是 post 、 page 或者 custom post type 的列表页面,编辑页面是 post.php,新建页面是 post-new.php,可以在不同页面打印 $hook_suffix 来了解它的使用方法。但由此也可看出它不能区分现在是在哪种 post 页面,需要借助更多的全局变量来判断。

2. $typenow

全局变量 $typenow 可以告诉我们当前的 post type,例如仅在 post 的列表页面加载可以这样来判断

functionmy_enqueue($hook_suffix){

    global$typenow;

    if('edit.php'==$hook_suffix&&$typenow=='post'){

       wp_enqueue_script('my_custom_script',plugin_dir_url(__FILE__).'myscript.js');

    }  

}

add_action('admin_enqueue_scripts','my_enqueue');

3. get_current_screen()

上述两个全局变量可以区分大多数情况,若区分不了,可以试试使用 get_current_screen() 函数,该函数返回当前页面的 post type 、 ID 、 base 等信息,只能在 admin_init 之后使用,具体可以参考官方文档。

4. $pagenow

全局变量 $pagenow 的返回值与 $hook_suffix 类似,只是它在前台后台都可以访问,定义的更早,例如前三者在 admin_init 处没有值,但 $pagenow 却有。

它定义在 wp-includes/vars.php 中,该文件还定义了浏览器、服务器全局变量,例如 $is_winIE 、 $is_apache,wp_is_mobile() 函数也在这里出现。

上述全局变量和函数能区分大多数情况,但依然有无力的时候,这时可以借助 $_REQUEST 来判断。上述变量的值也是从 $_REQUEST 获取,但多一层值是否存在的检查,所以能用它们解决的就不要用 $_REQUEST 或者 $_GET 。