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 。