2010-11-22 15 views
26

Chcę dodać trochę kodu HTML na końcu każdego linku na youtube, aby otworzyć odtwarzacz w liteboksie. To jest mój kod do tej pory:Funkcja nie wywoływania w zdarzeniu 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); 
    } 
}); 

To działa do momentu, w którym wstrzykuje niektóre HTML po link youtube, tak:

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

Ale gdy klikam to funkcja open_litebox() nie zostać wezwanym. Patrząc w konsoli błędów, widzę błąd, który mówi: open_litebox is not defined, ale go zdefiniowałem.

Nie mam pojęcia, co tu jest nie tak, czy ktoś może mi pomóc?

Dzięki.

Odpowiedz

43

Jest to częsty problem po pierwszym uruchomieniu pracy z jQuery. Problem polega na tym, że zdefiniowałeś funkcję w zakresie jQuery, co oznacza, że ​​nie jest dostępna przez zwykłe wywoływanie jej jak normalnej funkcji. Rozwiązaniem problemu jest, aby przenieść swoją definicję funkcji poza anonimowej funkcji gotowe, które pisemnej, tak jak poniżej:

$(document).ready(function() { 

    // do your stuff here 

}); 

// define your functions here 
function my_func() { 

} 

Oh a ja proponuję zrobić to samo dla zmiennych, które zostały określone. Przenieś je również poza funkcję gotową, ponieważ będziesz mieć te same problemy, co w przypadku swoich funkcji.

+0

** Znacznie ** lepiej ** nie ** uczynić funkcji globalną i podłączyć ją do nowoczesnej obsługi zdarzeń, a nie do "obsługi plików onxyz". –

10

Twoja funkcja open_litebox znajduje się w zasięgu innej funkcji, więc nie jest widoczna globalnie. Zamiast tego, co robisz, spróbuj użyć .click():

coś wzdłuż tych linii:

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

trzeba by generować oddzielne identyfikatory dla każdego z połączeń wykorzystujących tę sposób, więc innym sposobem jest sprawienie, aby każdy z tagów <img> miał znany atrybut class, a następnie wybierz go za pomocą $('.abc') (jeśli klasa to abc) zamiast $('#abc') i zrobić to w jednym etapie (tj. jako osobne połączenie po Twoim $('a').each).

2

Powodem jest, że open_litebox() jest zadeklarowane w funkcji document.ready, a zatem niedostępne z zasięgu globalnego.

Można przenieść funkcję poza document.ready, lub zmodyfikować kod, aby dołączyć obsługi onclick jQuery (która odwołuje się do funkcji bezpośrednio):

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

Istnieje wiele schludniej i bardziej jQuery sposób przypisać akcja kliknięcia.

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

Rozwiązuje to problem z zakresu opisany w innych odpowiedziach. Jeśli chcesz wywołać metodę open_litebox() z parametrami, umieść ją wewnątrz anonimowej funkcji, tak jak ja, inaczej funkcja zostanie wywołana, a następnie zwrócona wartość zostanie przekazana do akcji kliknięcia.W przeciwnym razie, bez parametrów, aby zdać, przypisanie jest prostsza:

$(this).click(open_litebox); 
10

innych odpowiedzi są prawidłowe w tej poruszającej swojej deklaracji my_func poza $(document).ready() rozwiąże problemu, ale chciałbym wyjaśnić rozumowanie, ponieważ to nie ma nic wspólnego z jQuery w szczególności.

$(document).ready() to funkcja obsługi zdarzeń, do której przekazujesz anonimową funkcję wywołania zwrotnego, która powinna zostać uruchomiona, gdy przeglądarka powiadomi Cię, że dokument jest gotowy.

Ponieważ zdefiniowano my_func w funkcji wywołania zwrotnego, nie jest ona widoczna w zasięgu globalnym, a zatem nie można jej wywołać z właściwości onclick elementu strony: img.

W JavaScript zakres jest na poziomie funkcji. Wszystko, co nie mieści się w funkcji, zostaje zagnieżdżone w zasięgu globalnym.

Powiązane problemy