Aggiungere onload al body in WordPress

25 ago 2010, 09:24:15
Visualizzazioni: 14.7K
Voti: 5

Sto attualmente sviluppando un plugin che incorporerà un Tour di Google Earth in un post/pagina WP tramite shortcode.

Il problema che sto riscontrando è che per far caricare il tour, devo aggiungere un onload="init()" nel tag <body>.

Posso modificare un file template specifico, ma trattandosi di una release, devo aggiungerlo dinamicamente tramite un hook. Qualche idea?

1
Commenti

Non è possibile utilizzare JavaScript non intrusivo tramite jQuery?

MikeSchinkel MikeSchinkel
25 ago 2010 10:20:39
Tutte le risposte alla domanda 5
6

Ed ecco una soluzione jQuery (come suggerito da Mike nel suo primo commento).

function add_my_scripts() {
    wp_enqueue_script( 'jquery' );
    wp_enqueue_script( 'my_init_script', SCRIPTSRC, 'jquery', '1.0' );
}
add_action( 'init', 'add_my_scripts' );

Quindi aggiungi uno script al tuo plugin che faccia questo:

jQuery.noConflict();

jQuery(document).ready(function($) {
    init();
});

Questo avvierà jQuery in modalità no conflict (se non lo è già) e aggiungerà una chiamata al metodo init() quando il documento è pronto. È un metodo più sicuro da usare rispetto a body onready() perché la funzione onready() può chiamare solo una cosa... quindi nessun altro può agganciarvi qualcosa o aggiungere script personalizzati. È meglio rendere il tuo plugin il meno intrusivo possibile, così altri plugin non interferiranno o viceversa.

25 ago 2010 17:18:20
Commenti

Penso che il tuo sia uno dei metodi preferiti. Credo che il codice jQuery possa essere addirittura ridotto, perché jQuery offre una scorciatoia alla funzione ready.

hakre hakre
25 ago 2010 19:02:52

@EAMann - Puoi spiegare meglio jQuery.noConflict()? Non l'ho mai usato e la documentazione non mi è stata chiara.

MikeSchinkel MikeSchinkel
25 ago 2010 21:17:40

Di default, jQuery imposta il simbolo $ come sinonimo di jQuery... questo può rompere altre librerie (Prototype, Scriptaculous, ecc.) e può anche compromettere funzioni $ definite dall'utente. Usando jQuery.noConflict() si disabilita questa impostazione predefinita, ma puoi ancora usare la funzione $ nel tuo codice se la passi come parametro... quindi la funzione che ho definito sopra potrebbe usare $.ajax e altre chiamate native all'interno della funzione definita.

EAMann EAMann
25 ago 2010 21:35:42

@EAMann - Grazie. Sapevo dell'uso all'interno della funzione ready() ma non avevo realizzato che ci sarebbe stato un conflitto se non avessi mai usato il $ al di fuori di una chiusura. Ancora non capisco cosa faccia. Forse dovrei semplicemente fare qualche ricerca in più...

MikeSchinkel MikeSchinkel
28 ago 2010 02:49:58

@MikeSchinkel - Di default, jQuery imposta il simbolo globale $ come alias per l'oggetto jQuery. Invocare jQuery in modalità noConflict() sovrascrive questa impostazione predefinita.

EAMann EAMann
14 dic 2010 16:56:33
Mostra i restanti 1 commenti
2

Ecco un approccio. Dovresti aggiungere la chiamata add_action() all'interno del tuo hook, credo. Il JavaScript che includo presume che la funzione init sia già stata definita. Se non lo è, allora questo fallirà, ma includere lo script sembra un problema che hai già risolto, se ho capito bene. Nota che non è necessariamente necessario aggiungerlo a wp_foot, potresti altrettanto facilmente aggiungerlo a wp_head:

<?php

function mypluginprefix_onload_init() { ?>
<script language="text/javascript">
// controlla il modo standard per aggiungere eventi onload
if ( typeof(window.addEventListener) !== 'undefined' )
    window.addEventListener( "load", init, false );
// o il vecchio modo non standard di msie
else if ( typeof(window.attachEvent) !== 'undefined' ) {
    window.attachEvent( "onload", init );
}
</script>
<?php }

// questo va nel tuo hook
add_action('wp_foot', 'mypluginprefix_onload_event');
?>
25 ago 2010 17:09:08
Commenti

Perché JavaScript diretto e non jQuery? jQuery gestisce tutti i casi limite in cui il codice potrebbe essere eseguito prima che la pagina sia completamente caricata.

MikeSchinkel MikeSchinkel
25 ago 2010 21:16:10

Per un semplice onload, penso che jQuery sia eccessivo. Basta allegare il gestore e il gioco è fatto. jQuery comporta un costo in termini di overhead per il download. Amo jQuery, ma non è la soluzione a tutto. Ora, se jQuery fosse già in coda, allora direi di usarlo, ma la mia risposta fa a meno di esso.

artlung artlung
25 ago 2010 22:00:24
0

Ignorando la possibilità di farlo con jQuery, una cosa che potresti fare è agganciare il filtro template_include e usare ob_start() con una callback. La tua callback può poi cercare la stringa '<body' e sostituirla con '<body onload="init()"' come fa il seguente codice. Dovresti essere in grado di inserirlo direttamente nel tuo plugin, assicurati solo di cambiare i nomi per seguire la convenzione di denominazione del tuo plugin:

<?php
add_filter('template_include','start_buffer_capture',1);
function start_buffer_capture($template) {
  ob_start('end_buffer_capture');  // Avvia il buffer della pagina
  return $template;
}
function end_buffer_capture($buffer) {
  return str_replace('<body','<body onload="init()"',$buffer);
}

Nota che, se fossi in te, non darei per scontato che il codice sopra sia già completamente robusto. Dubito che gestirà tutti i casi limite visto che l'ho buttato giù velocemente per rispondere alla tua domanda, ma almeno ti mostra come gestire il caso normale. Con qualche test sugli use case sono sicuro che riuscirai a fargli gestire anche i casi limite importanti (tipo cosa succede se '<BODY' è in maiuscolo, ecc.)

25 ago 2010 10:50:12
0

Ecco del codice JavaScript per aggiungere dinamicamente una callback al caricamento della pagina, con o senza jQuery:

function add_onload() {
    ?>
    <script type="text/javascript">
    my_onload_callback = function() { alert('Ciao!'); }; // funzione di test

    if( typeof jQuery == "function" ) { 
        jQuery(my_onload_callback); // document.ready
    } else {
        document.getElementsByTagName('body')[0].onload = my_onload_callback; // body.onload
    }
    </script>
    <?php
}
add_action( 'wp_footer', 'add_onload' );

Nel tuo caso dovresti semplicemente sostituire my_onload_callback con il tuo metodo init.

25 ago 2010 13:49:35
4

Ho fatto ulteriori ricerche e ho trovato un modo "migliore" per farlo funzionare (Google rende difficile l'embed dei loro Earth Tours, e il loro gadget non funziona).

Alla fine ho creato un plugin che utilizza una combinazione di shortcode e un campo personalizzato.

26 ago 2010 17:58:06
Commenti

Se puoi, ti consiglierei di pubblicare il codice a beneficio di altre persone che troveranno questo post.

User User
26 ago 2010 18:45:27

Sì, sarebbe anche utile per capire meglio quello che hai chiesto inizialmente. Domanda e risposta dovrebbero andare insieme.

hakre hakre
28 ago 2010 01:46:36

Per chiunque possa volerlo, ecco il plugin. È ospitato sul repository di WP http://wordpress.org/extend/plugins/google-earth-tours/

Norcross Norcross
14 set 2010 23:54:25

Puoi accettare la tua stessa risposta, per indicare che il problema è risolto per te.

Jan Fabry Jan Fabry
4 nov 2010 20:02:38