Come aggiungere il tag defer="defer" negli script javascript dei plugin?

9 gen 2012, 09:59:34
Visualizzazioni: 40.9K
Voti: 31

Non riesco ad aggiungere il tag defer negli script javascript dei plugin. Il test di Google PageSpeed mi suggerisce di aggiungere il tag defer negli script di Contact Form 7.

Ecco come Contact Form 7 include javascript nell'header.

add_action( 'wp_enqueue_scripts', 'wpcf7_enqueue_scripts' );

function wpcf7_enqueue_scripts() {
    // jquery.form.js originariamente incluso in WordPress è obsoleto e deprecato
    // quindi dobbiamo deregistrarlo e registrare nuovamente l'ultima versione
    wp_deregister_script( 'jquery-form' );
    wp_register_script( 'jquery-form', wpcf7_plugin_url( 'jquery.form.js' ),
        array( 'jquery' ), '2.52', true );

    $in_footer = true;
    if ( 'header' === WPCF7_LOAD_JS )
        $in_footer = false;

    wp_enqueue_script( 'contact-form-7', wpcf7_plugin_url( 'scripts.js' ),
        array( 'jquery', 'jquery-form' ), WPCF7_VERSION, $in_footer );

    do_action( 'wpcf7_enqueue_scripts' );
}

Come posso aggiungere il tag defer="defer" nel codice sopra riportato?

2
Commenti

Ticket rilevante: http://core.trac.wordpress.org/ticket/12009

scribu scribu
9 gen 2012 19:15:15

Ottima domanda @Viruthagiri.

Ramkumar M Ramkumar M
2 feb 2012 15:30:47
Tutte le risposte alla domanda 2
6
63

A partire da WordPress 4.1 c'è un filtro: script_loader_tag. Puoi usarlo per trovare lo script corretto:

add_filter( 'script_loader_tag', function ( $tag, $handle ) {

    if ( 'contact-form-7' !== $handle )
        return $tag;

    return str_replace( ' src', ' defer="defer" src', $tag );
}, 10, 2 );

Risposta precedente

Non esiste un filtro dedicato disponibile... almeno non riesco a vederne uno. Ma...

  • wp_print_scripts() chiama WP_Scripts->do_items()
  • che chiama WP_Scripts->do_item()
  • che utilizza esc_url()
  • che offre un filtro: 'clean_url'.

Ed eccoci qui:

function add_defer_to_cf7( $url )
{
    if ( FALSE === strpos( $url, 'contact-form-7' )
      or FALSE === strpos( $url, '.js' )
    )
    { // non è il nostro file
        return $url;
    }
    // Deve essere un ', non "!
    return "$url' defer='defer";
}
add_filter( 'clean_url', 'add_defer_to_cf7', 11, 1 );

Avvertenza: non testato, solo un'idea. :)

Aggiornamento

Ho scritto e testato un plugin con questo codice.

9 gen 2012 13:56:46
Commenti

È perfetto anche da usare con data-main in requirejs

Nicola Peluchetti Nicola Peluchetti
6 giu 2012 18:07:47

È un bel trucco, e così semplice. Penso che sarebbe utile anche per aggiungere charset='utf-8' quando necessario!

webaware webaware
16 gen 2013 10:16:09

Ottimo, ma perché: Deve essere un ', non "! ?

henrywright henrywright
1 feb 2014 04:09:52

@henrywright WordPress aggiunge ' su entrambi i lati della stringa restituita, un " risulterebbe in HTML non valido.

fuxia fuxia
1 feb 2014 12:54:48

Probabilmente è una buona idea, nel caso qualcuno volesse adattare questo codice per funzionare con altri script, assicurarsi di validare l'uso solo sul front-end magari usando if( ! is_admin() ){}. Plugin popolari come ACF potrebbero causare problemi.

crissoca crissoca
28 apr 2015 05:09:37

@crissoca, grazie amico. Me n'ero dimenticato finché TinyMCE non ha fatto quello che avrebbe dovuto (mancavano i qtags e così via :-D). Quindi sì, usa questo SOLO sul front-end!

Charles Charles
12 giu 2015 15:46:31
Mostra i restanti 1 commenti
0

La risposta accettata è corretta, ma volevo apportare alcuni miglioramenti/aggiornamenti per un caso più generale, utile a chiunque, incluso il mio futuro io, che dovesse imbattersi in questa soluzione durante una ricerca. Per casi generali che non riguardano il plugin contact-form-7, dove si vuole aggiungere l'attributo defer a tutti gli script, è probabile che si voglia escluderlo dalle pagine di amministrazione, poiché queste si basano sull'esecuzione degli script in un ordine specifico. Inoltre, per le pagine non di amministrazione, è bene escludere jQuery, poiché jQuery dovrebbe probabilmente essere caricato nell'head prima di qualsiasi altro script. Inoltre, invece di manipolare la stringa del tag, un approccio migliore sarebbe caricarla in un oggetto DOMDocument, manipolarlo e poi riconvertirlo in stringa. Inoltre, le versioni più recenti di PHP supportano il type checking, quindi è consigliabile aggiungere i tipi dei parametri e del valore di ritorno nella chiamata della funzione.

<?php

    add_filter('script_loader_tag', function (string $tag, string $handle, string $src):string {
        if (is_admin()) {
            return $tag;
        }
        if (in_array($handle, array('jquery-core', 'jquery-migrate'))) {
            return $tag;
        }
        $dom = new \DomDocument();
        $dom->loadHTML($tag, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        $dom->getElementsByTagName('script')[0]->setAttribute("defer", "defer");
        $tag = $dom->saveHTML();
        return $tag;
    }, 10, 3);

?>
6 giu 2023 01:05:52