問題描述

有沒有辦法使用 wp_enqueue_script() 進行內聯指令碼?

我這樣做是因為我的內聯指令碼取決於另一個指令碼,我想要在載入後插入它的靈活性。

此外,它是一個內聯指令碼,因為我將 PHP 變數傳入 javascript(像主題路徑等)

提前致謝。

最佳解決方案

那麼你有 wp_localize_script(),但這只是傳遞資料。

否則你可以這樣做:

function print_my_inline_script() {
  if ( wp_script_is( 'some-script-handle', 'done' ) ) {
?>
<script type="text/javascript">
// js code goes here
</script>
<?php
  }
}
add_action( 'wp_footer', 'print_my_inline_script' );

這個想法是,您不應該依賴於依賴於指令碼的內聯指令碼,而是後來。

次佳解決方案

只是不要使它成為一個內聯指令碼,然後將動態引數傳遞給它作為變數。奧託有 written a great guide 如何有效地做到這一點。

WordPress 3.3 也將使這個更強大:https://core.trac.wordpress.org/ticket/11520

第三種解決方案

該解決方案類似於 @ scribu 的 answer,但是它遵循 wp_enquque_script()的形式,並且如果指令碼中的依賴關係包含在標題中,則會將指令碼放置在標題中。

/**
 * Enqueue inline Javascript. @see wp_enqueue_script().
 *
 * KNOWN BUG: Inline scripts cannot be enqueued before
 *  any inline scripts it depends on, (unless they are
 *  placed in header, and the dependant in footer).
 *
 * @param string      $handle    Identifying name for script
 * @param string      $src       The JavaScript code
 * @param array       $deps      (optional) Array of script names on which this script depends
 * @param bool        $in_footer (optional) Whether to enqueue the script before </head> or before </body>
 *
 * @return null
 */
function enqueue_inline_script( $handle, $js, $deps = array(), $in_footer = false ){
    // Callback for printing inline script.
    $cb = function()use( $handle, $js ){
        // Ensure script is only included once.
        if( wp_script_is( $handle, 'done' ) )
            return;
        // Print script & mark it as included.
        echo "<script type="text/javascript" id="js-$handle">n$jsn</script>n";
        global $wp_scripts;
        $wp_scripts->done[] = $handle;
    };
    // (`wp_print_scripts` is called in header and footer, but $cb has re-inclusion protection.)
    $hook = $in_footer ? 'wp_print_footer_scripts' : 'wp_print_scripts';

    // If no dependencies, simply hook into header or footer.
    if( empty($deps)){
        add_action( $hook, $cb );
        return;
    }

    // Delay printing script until all dependencies have been included.
    $cb_maybe = function()use( $deps, $in_footer, $cb, &$cb_maybe ){
        foreach( $deps as &$dep ){
            if( !wp_script_is( $dep, 'done' ) ){
                // Dependencies not included in head, try again in footer.
                if( ! $in_footer ){
                    add_action( 'wp_print_footer_scripts', $cb_maybe, 11 );
                }
                else{
                    // Dependencies were not included in `wp_head` or `wp_footer`.
                }
                return;
            }
        }
        call_user_func( $cb );
    };
    add_action( $hook, $cb_maybe, 0 );
}

// Usage
enqueue_inline_script('test','alert('enqueue inline script test');',array( 'jquery'));

注意:這使用匿名函式,但是對於 5.3 之前的 PHP 版本,這可以很容易地轉換為類。

第四種方案

我發現更好的方法是使用 wp_localize_script(),如 @scribu 所建議的。

通常,我決定使用 in-line Javascript,因為我需要為我的指令碼提供一些 PHP 變數。這可以用 wp_localize_script()來解決。我將舉一個例子:

您有一個陣列 $aFoo 與一些選項,並需要傳遞給一個指令碼。

$aFoo = array( 'option1' => $option1Value, 'option2' => $option2Value );

使用 in-line 指令碼:

<script>
    var oFoo = {};
    oFoo.option1 = <?php echo $aFoo['option1'] ?>;
    oFoo.option2 = <?php echo $aFoo['option2'] ?>;
    //do some stuff with oFoo
</script>

使用 wp_localize_script()

wp_register_script( 'script_name', 'pathToScript/script.js', array( 'jquery' )); //if jQuery is not needed just remove the last argument.
wp_localize_script( 'script_name', 'object_name', $aFoo ); //pass 'object_name' to script.js
wp_enqueue_script( 'script_name' );

然後,pathToScript/script.js 將是:

var oFoo = {};
oFoo.option1 = object_name.option1;
oFoo.option2 = object_name.option2;
//do some stuff with oFoo (no PHP needed)

這樣你就不需要 in-line 指令碼了。

第五種方案

scribu 是完全正確的。無論如何,我想新增一些資訊:

我希望我的函式輸出一個指令碼一次,無論它多久被呼叫。它是一個 content-related 功能,所以我不能等待任何鉤子。我使用 scribus 資訊和一些閱讀 WP 核心來提出這一點:

function print_script_once() {
    if(!wp_script_is('my-handle', 'done')) {
        echo "<script>alert('once!');</script>";
        global $wp_scripts;
        $wp_scripts->done[] = 'my-handle';
    }
}
add_action('get_footer', print_script_once);

使用這種方法我可以列印一個內聯的指令碼一次。在我的情況下,我有一個功能建立一個 share-button,需要一個指令碼來執行所有的按鈕。但只有一次。

第六種方案

由於 WordPress 4.5 可以使用 wp_add_inline_script()

add_action( 'wp_enqueue_scripts', 'cyb_enqueue_scripts' );
function cyb_enqueue_scripts() {
   wp_enqueue_script( 'myscript', 'url/to/myscript.js', array(), '1.0' );
   wp_add_inline_script( 'myscript', 'Your inline javascript code gos here' );
}

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。