2010-11-22 13 views
26

Desidero aggiungere un po 'di codice HTML alla fine di ogni link di youtube per aprire il lettore in una litebox. Questo è il mio codice finora:Funzione che non chiama all'interno di un evento onclick

$(document).ready(function() { 
    var valid_url = new RegExp('youtube\.com\/.*v=([a-zA-Z0-9_-]+)'); 
    var image_data = 'base64 encoded image'; 

    init(); 

    function init() { 
    $('a').each(function() { 
     if (valid_url.test($(this).attr('href'))) { 
     $(this).after(' <img src="' + image_data + '" onclick="open_litebox(\'hi\');" />'); 
     } 
    }); 
    } 

    function open_litebox(param) { 
    alert(param); 
    } 
}); 

Si lavora per il punto in cui si inietta un po 'di HTML dopo il link youtube, in questo modo:

<img src="base 64 data" onclick="open_litebox('hi')"> 

Ma quando scatto questo la funzione open_litebox() non lo fa essere chiamato Guardando nella console degli errori posso vedere un errore che dice open_litebox is not defined, ma l'ho definito.

Sono piuttosto all'oscuro di cosa sta andando storto qui, qualcuno potrebbe prestarmi una mano?

Grazie.

risposta

43

Questo è un problema comune quando si inizia a lavorare con jQuery. Il problema qui è che hai definito la funzione all'interno dell'ambito jQuery, il che significa che non è accessibile semplicemente chiamandolo come una normale funzione. Una soluzione al vostro problema è quello di spostare la definizione di funzione al di fuori della funzione di pronto anonima che scritto, in questo modo:

$(document).ready(function() { 

    // do your stuff here 

}); 

// define your functions here 
function my_func() { 

} 

Oh, e vorrei suggerire di fare lo stesso per le variabili che sono stati definiti. Spostali anche al di fuori della tua funzione pronta, perché avrai gli stessi problemi con le tue funzioni.

+0

** Molto ** meglio ** non ** rendere globale la funzione e collegarla con la gestione degli eventi moderna, non con i gestori di attributi 'onxyz'. –

10

La funzione open_litebox è nell'ambito di un'altra funzione, pertanto non è globalmente visibile. Invece di quello che state facendo, provare a utilizzare .click():

Qualcosa in questo senso:

$(this).after(' <img src="' + image_data + '" id='abc' />'); 
$('#abc').click(open_litebox); 

che avrebbe dovuto generare ID separate per ciascuno dei collegamenti utilizzando questo modo, in un altro modo è possibile rendere ciascuno dei tag <img> un attributo noto class e quindi selezionarlo utilizzando $('.abc') (se la classe è abc) anziché $('#abc') e farlo in un unico passaggio (ad es. come chiamata separata dopo il $('a').each).

2

Il motivo è che open_litebox() è dichiarato all'interno della funzione document.ready e pertanto non accessibile da un ambito globale.

È possibile spostare la funzione al di fuori di document.ready, o, modificare il codice per attaccare il gestore onclick utilizzando jQuery (che fa riferimento alla funzione direttamente):

var link = $(' <img src="' + image_data + '" />').click(function() { 
    open_litebox('hi'); 
}); 
$(this).after(link); 
0

C'è una molto più ordinato e più modo jQuery per assegnare l'azione clic.

function init() { 
    $('a').each(function() { 
     if(valid_url.test($(this).attr('href'))){ 
      $(this).click(function() { open_litebox('hi'); }); 
     } 
    }); 
} 

Questo risolve il problema dell'oscilloscopio come descritto nelle altre risposte. Se è necessario chiamare open_litebox() con parametri, inserirlo in una funzione anonima come ho fatto io, altrimenti la funzione verrà chiamata e quindi il valore restituito verrà passato all'azione clic.In caso contrario, senza parametri da passare, l'assegnazione è più semplice:

$(this).click(open_litebox); 
10

Le altre risposte sono corrette in che spostando la sua dichiarazione my_func al di fuori di $(document).ready() risolverà il tuo problema, ma mi piacerebbe chiarire il ragionamento, perché in particolare non ha nulla a che fare con jQuery.

$(document).ready() è un gestore di eventi a cui si passa una funzione anonima come un callback che deve essere eseguito quando il browser notifica che il documento è pronto.

Poiché è stato definito my_func all'interno della funzione di richiamata, non è visibile dall'ambito globale e pertanto non può essere chiamato dalla proprietà onclick dell'elemento img della pagina.

In JavaScript, l'ambito è al livello di funzione. Tutto ciò che non è all'interno di una funzione viene raggruppato nella portata globale.

Problemi correlati