2010-11-22 29 views
26

Je souhaite ajouter du code HTML à la fin de chaque lien YouTube pour ouvrir le lecteur dans une litebox. Ceci est mon code à ce jour:Fonction n'appelant pas dans un événement 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); 
    } 
}); 

Il fonctionne au point où il injecte du code HTML après le lien youtube, comme ceci:

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

Mais quand je clique sur cette fonction ne open_litebox() être appelé. En regardant dans la console d'erreur, je peux voir une erreur qui dit open_litebox is not defined, mais je l'ai défini. Je n'ai aucune idée de ce qui ne va pas ici, quelqu'un pourrait-il me donner un coup de main?

Merci.

Répondre

43

Ceci est un problème courant lorsque vous commencez à travailler avec jQuery. Le problème ici est que vous avez défini la fonction dans la portée jQuery, ce qui signifie qu'elle n'est pas accessible en l'appelant simplement comme une fonction normale. Une solution à votre problème est de déplacer votre définition de fonction en dehors de la fonction prêt anonyme qui vous écrit, comme ceci:

$(document).ready(function() { 

    // do your stuff here 

}); 

// define your functions here 
function my_func() { 

} 

Oh et je vous conseille de faire la même chose pour vos variables que vous avez définies. Déplacez-les en dehors de votre fonction prête, car vous aurez les mêmes problèmes que vous avez fait avec vos fonctions.

+0

** Beaucoup ** préférable de ne pas ** ** rendre la fonction globale, et de le brancher avec la gestion des événements modernes, pas les gestionnaires d'attributs 'onxyz'. –

10

Votre fonction open_litebox est dans le cadre d'une autre fonction, elle n'est donc pas visible globalement. Au lieu de ce que vous faites, essayez d'utiliser .click():

Quelque chose le long de ces lignes:

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

vous devez générer des ID séparés pour chacun des liens utilisant cette façon, donc une autre façon est de faire de chacun des <img> un attribut connu class, puis sélectionnez-le en utilisant $('.abc') (si la classe est abc) au lieu de $('#abc') et le faire en une seule étape (c.-à-d. en tant qu'appel séparé après votre $('a').each).

2

La raison est que open_litebox() est déclarée à l'intérieur de la fonction document.ready, et n'est donc pas accessible depuis une portée globale.

Vous pouvez déplacer la fonction en dehors de document.ready, ou modifier le code pour attacher le gestionnaire onclick utilisant jQuery (qui fait référence à la fonction directement):

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

Il y a beaucoup plus propres et plus façon jQuery assigner l'action de clic.

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

Ceci résout le problème d'étendue comme décrit dans les autres réponses. Si vous devez appeler open_litebox() avec des paramètres, placez-le dans une fonction anonyme comme je l'ai fait, sinon la fonction sera appelée et la valeur de retour sera transmise à l'action click.Dans le cas contraire, sans paramètres à passer, la mission est plus simple:

$(this).click(open_litebox); 
10

Les autres réponses sont correctes dans votre déclaration que le déplacement my_func en dehors de $(document).ready() résoudra votre problème, mais je voudrais clarifier le raisonnement, parce que cela n'a rien à voir avec jQuery en particulier.

$(document).ready()$(document).ready() est un gestionnaire d'événements auquel vous transmettez une fonction anonyme en tant que rappel qui doit être exécuté lorsque le navigateur vous informe que le document est prêt. Parce que vous avez défini my_func dans la fonction de rappel, il n'est pas visible à partir de l'étendue globale et ne peut donc pas être appelé à partir de la propriété onclick de l'élément img de votre page.

En JavaScript, la portée se trouve au niveau de la fonction. Tout ce qui n'est pas dans une fonction est regroupé dans la portée globale.