由于依赖关系,WP将内联脚本入队

时间:2011-08-03 作者:chrisjlee

是否有方法将wp\\u enqueue\\u script()用于内联脚本?

我这样做是因为我的内联脚本依赖于另一个脚本,我希望在加载后能够灵活地插入它。

此外,它是一个内联脚本,因为我将php变量传递到javascript中(如主题路径等)

提前谢谢。

6 个回复
最合适的回答,由SO网友:scribu 整理而成

当然,您有wp\\u localize\\u 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\' );
这个想法是,您不应该依赖于内联脚本在它所依赖的脚本之后打印,而应该稍后打印。

SO网友:Viper007Bond

只是不要让它成为内联脚本,然后将动态参数作为变量传递给它。奥托有written a great guide 如何有效地做到这一点。

WordPress 3.3还将使此功能更加强大:https://core.trac.wordpress.org/ticket/11520

SO网友:Stephen M. Harris

此解决方案类似于@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$js\\n</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版本,可以轻松地将其转换为类

SO网友:cybmeta

由于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\' );
}

SO网友:Manolo

我找到的更好的方法是wp_localize_script(), 正如@scribu建议的那样。

通常,我决定使用内嵌Javascript,因为我需要为脚本提供一些PHP变量。这可以通过以下方法解决wp_localize_script(). 我将提供一个示例:

你有一个数组$aFoo 并需要将其传递给脚本。

$aFoo = array( \'option1\' => $option1Value, \'option2\' => $option2Value ); 
使用内嵌脚本:

<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)
这样,您就不再需要内嵌脚本了。

SO网友:Julian F. Weinert

scribu绝对正确。无论如何,我想添加一些信息:

我希望我的函数只输出一次脚本,不管它被调用的频率有多高。这是一个与内容相关的函数,所以我不能等待任何挂钩。我使用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);
使用此方法,我可以打印一次内联脚本。在我的例子中,我有一个创建共享按钮的函数,需要为所有按钮执行一个脚本。但只有一次。

结束

相关推荐