wp stellt Inline-Skripte aufgrund von Abhängigkeiten in die Warteschlange

35

Gibt es eine Möglichkeit, wp_enqueue_script () für Inline-Skripte zu verwenden?

Ich mache das, weil mein Inline-Skript von einem anderen Skript abhängt und ich die Flexibilität haben möchte, es einzufügen, nachdem es geladen wurde.

Es ist auch ein Inline-Skript, weil ich PHP-Variablen in das Javascript übergebe (wie Theme-Pfad, etc.)

Danke im Voraus.

chrisjlee
quelle

Antworten:

33

Nun, Sie haben wp_localize_script (), aber das ist nur für die Übergabe von Daten.

Andernfalls können Sie dies tun:

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' );

Die Idee ist, dass Sie sich nicht darauf verlassen sollten, dass Ihr Inline-Skript genau nach dem Skript gedruckt wird , von dem es abhängt, sondern später.

scribu
quelle
4
Sicher funktioniert das nur, wenn das Skript, von dem Sie abhängig sind, bereits ausgegeben wurde? Wenn das Skript, von dem Sie abhängig sind, auch in wp_footer registriert ist und nach dem Inline-Skriptcode ausgeführt wird, wird das Inline-Skript einfach nicht in den Client geschrieben und daher ausgeführt.
Sam Peacey
6
Ab WordPress 4.5 können Sie wp_add_inline_script() wp_add_inline_script mit WordPress JQuery verwenden
Dhinju Divakaran
7

Diese Lösung ähnelt der Antwort von @ scribu , folgt jedoch der Form von wp_enquque_script()und platziert das Skript in der Kopfzeile, wenn die Abhängigkeiten in der Kopfzeile enthalten sind.

/**
 * 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'));

Hinweis: Hierbei werden anonyme Funktionen verwendet. In PHP-Versionen vor 5.3 kann dies jedoch problemlos in eine Klasse konvertiert werden.

Stephen M. Harris
quelle
5

Seit WordPress 4.5 können Sie wp_add_inline_script () verwenden :

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' );
}
Cybmeta
quelle
4

Der bessere Weg, den ich gefunden habe, ist die Verwendung von wp_localize_script(), wie @scribu vorgeschlagen hat.

Normalerweise habe ich mich für die Verwendung von Inline-Javascript entschieden, weil ich meinem Skript einige PHP-Variablen hinzufügen musste. Dies kann mit gelöst werden wp_localize_script(). Ich werde ein Beispiel geben:

Sie haben ein Array $aFoomit einigen Optionen und müssen es an ein Skript übergeben.

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

Inline-Skript verwenden:

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

Verwenden von 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' );    

Dann pathToScript/script.jswäre:

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

Auf diese Weise benötigen Sie nie mehr Inline-Skripte.

Manolo
quelle
3

Scribu ist absolut richtig. Wie auch immer, ich möchte ein paar Infos hinzufügen:

Ich möchte, dass meine Funktion ein Skript einmal ausgibt, egal wie oft es aufgerufen wird. Da es sich um eine inhaltsbezogene Funktion handelt, kann ich nicht auf Hooks warten. Ich habe Scribus-Infos und einige Lektüren des WP-Kerns verwendet, um dies zu erreichen:

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);

Mit dieser Methode kann ich ein Inline-Skript einmal drucken. In meinem Fall habe ich eine Funktion, die einen Share-Button erzeugt und ein Skript für alle Buttons benötigt. Aber nur einmal.

Julian F. Weinert
quelle
Der echoInline-Skript-Ansatz ist, wie das Twenty Seventeen-Thema zumindest an einer Stelle konstruiert wurde. Und ich benutze diese Technik auch. Funktioniert hervorragend und ermöglicht es Ihnen, sich an verschiedenen Orten einzuklinken.
Josh Habdas