Gestione delle collisioni dei componenti jQuery

14 apr 2012, 16:45:30
Visualizzazioni: 849
Voti: 4

Nello sviluppo di plugin, qual è la migliore pratica per prevenire le collisioni dei componenti jQuery sul frontend?

Ad esempio, supponiamo che includa il dialogo jQuery Apprise in un plugin che lo carica sul frontend per una determinata funzionalità, mentre un altro plugin potrebbe fare lo stesso. Poiché questo viene caricato e dichiarato due volte, o forse una versione è modificata e personalizzata mentre la mia no, potremmo ottenere errori JavaScript sul frontend (presumo).

(Nota che sto seguendo la best practice di utilizzare la strategia wp_register_script() e wp_enqueue_script() tramite un'azione wp_head() per caricare un componente jQuery sul frontend.)

1
Tutte le risposte alla domanda 3
2

La mia suggerimento sarebbe di utilizzare un mix di isolamento del codice in una funzione anonima e verificare se jQuery è già presente.

Ecco un esempio:

(function() {

var jQuery;  // la tua variabile jQuery

// verifica se jQuery è presente e se ha la versione che desideri
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.8.3') {

    // carica la libreria jQuery dalle librerie ospitate da Google
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");

    // attendi il caricamento della libreria jQuery
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // vecchie versioni di IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              jqueryLoadHandler();
          }
      };
    } else { // per altri browser
      script_tag.onload = jqueryLoadHandler;
    }

    // Prova a trovare l'head, altrimenti usa documentElement come fallback
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);

} else {

    // Il sito sta già utilizzando la versione di jQuery che desideri, quindi punta semplicemente la tua variabile a quel jQuery
    jQuery = window.jQuery;
    main();
}

// non appena jQuery è caricato
function jqueryLoadHandler() {
    // Ripristina $ e window.jQuery ai loro valori precedenti e memorizza il
    // nuovo jQuery nella nostra variabile jQuery locale
    jQuery = window.jQuery.noConflict(true);

    // Chiama la funzione principale del plugin
    main(); 
}

// funzione principale del plugin
function main() { 
    jQuery(document).ready(function($) { 
        // Qui puoi usare $ senza problemi
    });
}

})(); // Chiamiamo immediatamente la nostra funzione anonima

In questo modo puoi utilizzare jQuery senza problemi nel tuo plugin, anche se altri plugin hanno usato jQuery senza wp_enqueue_script. Tutte le variabili e le funzioni che utilizzi all'interno di questa funzione anonima non interferiranno con il resto della pagina.

Forse potrebbe funzionare ancora meglio se integrato con wp_enqueue_script.

Puoi leggere di più su questo approccio di caricamento di jQuery all'interno di una funzione anonima su http://alexmarandon.com/articles/web_widget_jquery/

14 dic 2012 13:02:34
Commenti

Nota che questa domanda riguarda librerie di terze parti (plugin, ecc.).

fuxia fuxia
14 dic 2012 13:04:52

sì, ho capito. è solo un suggerimento. Ad esempio, in questa situazione se jquery apprise fosse caricato in questo modo, non interferirebbe con altri apprise caricati da altri plugin.

dbeja dbeja
14 dic 2012 13:14:06
0

Il problema con jQuery core è molto comune e molti plugin hanno diversi modi per prevenirlo.

Quando parliamo di plugin per jQuery c'è un altro problema, ma puoi rimuoverlo in modo simile.

Nella tua situazione preferisco la soluzione comune di aggiungere un interruttore di inclusione nella pagina delle impostazioni del tuo plugin - penso che sia molto popolare per i plugin con jQuery core, ma puoi usarlo anche per i plugin jQuery.

Un'altra soluzione è scrivere uno script in js per verificare se il metodo extra di jQuery (dal plugin) è definito, quando non lo è puoi includere il plugin nel tuo script. Questa soluzione funzionerà solo se aggiungi un hook per gli script con una priorità molto bassa. Verrà eseguito dopo altri plugin e questa condizione funzionerà.

16 dic 2012 15:35:09
0

La migliore pratica per accodare o registrare script è utilizzare wp_register_script e wp_enqueue_script. Plugin e temi che non utilizzano queste funzioni per aggiungere i loro script, non dovrebbero essere utilizzati.

La ragione è semplice: con wp_register_script() siamo in grado di recuperare molte informazioni sugli script registrati. Specialmente se una determinata risorsa è già registrata o meno.

Ho scritto una classe semplice per verificare se una risorsa è già registrata. La classe può deregistrare lo script e registrare il nuovo script o saltare il nuovo script. Questa classe dovrebbe essere un punto di partenza per il tuo sviluppo. Non è per ambienti di produzione!

Come funziona la classe?

La classe recupera un array con gli script che dovrebbero essere registrati. Poi confronta i nomi dei file (e solo i nomi dei file) di ogni script registrato con i nomi dei file degli script che dovrebbero essere registrati. Se lo script/nome del file non è già registrato, il suo handle verrà aggiunto a un array e verrà registrato in un secondo momento.

La classe può essere estesa per confrontare il percorso completo dello script o la versione o qualsiasi altra cosa sia necessaria per decidere se lo script dovrebbe essere registrato o meno.

Un semplice esempio

    $my_scripts = array(

            'foo' => array(
                    'src' => 'external/ressource/foo.js',
                    'deps' => array( 'jquery' ),
                    'version' => false,
                    'in_footer' => true
                    ),

            'bar' => array(
                    'src' => home_url( '/wp-admin/js/common.min.js' ),
                    'deps' => false,
                    'version' => false,
                    'in_footer' => true
                    ),

            'jquery' => array(
                    'src' => '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js',
                    'deps' => false,
                    'version' => '1.8.3',
                    'in_footer' => true
                    ),

    );

    $safe_register = new Safe_Registering_Scripts( $my_scripts, true );

    global $wp_scripts;

    var_dump( $wp_scripts->registered['jquery'] );

Innanzitutto definiamo un array con tutti i nostri script da registrare. La classe esaminerà i nostri script e confronterà se la risorsa è già registrata.

  • lo script foo verrà sempre registrato perché la risorsa non è registrata.
  • lo script bar non verrà mai registrato perché la sua risorsa è già registrata.
  • lo script jquery è un caso speciale. C'è già un handle chiamato jquery ma il secondo parametro nella chiamata della classe dice che questa risorsa dello script deve essere sostituita con la nuova risorsa.

Come puoi vedere nel var_dump(), la risorsa dello script jquery è stata sostituita dalla classe. Quindi se estendi la classe e aggiusti il test (risorsa, nome del file js, versione, script accodati, ecc.), potrebbe aiutare a minimizzare le collisioni js.

16 dic 2012 22:38:01