Функция, не вызывающая внутри события onclick
Я хочу добавить некоторый HTML в конец каждой ссылки на YouTube, чтобы открыть плеер в litebox. Это мой код:
$(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);
}
});
Он работает до того момента, когда он вставляет некоторый HTML после ссылки на YouTube, например:
<img src="base 64 data" onclick="open_litebox('hi')">
Но когда я нажимаю на это, функция open_litebox()
не вызывается. Глядя в консоль ошибок, я вижу ошибку, которая говорит open_litebox is not defined
, но я ее определил.
Я почти не знаю, что здесь происходит, может ли кто-нибудь дать мне руку?
Спасибо.
Ответы
Ответ 1
Это обычная проблема, когда вы впервые начинаете работать с jQuery. Проблема здесь в том, что вы определили функцию в области jQuery, что означает, что она недоступна, просто называя ее как обычную функцию. Решение вашей проблемы состоит в том, чтобы переместить определение функции за пределы анонимной готовой функции, которую вы написали, например:
$(document).ready(function() {
// do your stuff here
});
// define your functions here
function my_func() {
}
О, и я бы предложил сделать то же самое для ваших переменных, которые вы определили. Переместите их за пределы своей готовой функции, потому что у вас будут те же проблемы, что и ваши функции.
Ответ 2
Ваша функция open_litebox
находится в области действия другой функции, поэтому она не отображается глобально. Вместо того, что вы делаете, попробуйте использовать .click()
:
Что-то в этом роде:
$(this).after( ' <img src="' + image_data + '" id='abc' />' );
$('#abc').click(open_litebox);
Вам придется создавать отдельные идентификаторы для каждой из ссылок, используя этот способ, так что другой способ состоит в том, чтобы каждый из тегов <img>
имел известный атрибут class
, а затем выбирал его с помощью $('.abc')
(если класс abc
) вместо $('#abc')
и сделать это за один шаг (т.е. в качестве отдельного вызова после вашего $('a').each
).
Ответ 3
Другие ответы верны в том, что перемещение объявления my_func
за пределами $(document).ready()
решит вашу проблему, но я хотел бы прояснить рассуждения, потому что это не имеет никакого отношения к jQuery в частности.
$(document).ready()
- это обработчик событий, которому вы передаете анонимную функцию в качестве обратного вызова, который должен выполняться, когда браузер уведомляет вас о готовности документа.
Поскольку вы определили my_func
в функции обратного вызова, он не отображается из глобальной области и поэтому не может быть вызван из свойства onclick
вашего элемента img
.
В JavaScript область видимости находится на уровне функции. Все, что не входит в функцию, попадает в глобальную область.
Ответ 4
Причина в том, что open_litebox()
объявляется внутри функции document.ready
и поэтому недоступен из глобальной области.
Вы можете переместить функцию вне document.ready
или изменить код для присоединения обработчика onclick с помощью jQuery (который напрямую ссылается на функцию):
var link = $(' <img src="' + image_data + '" />' ).click(function () {
open_litebox('hi');
});
$(this).after(link);
Ответ 5
Там намного опрятный и более jQuery способ назначить действие click.
function init() {
$('a').each(function() {
if(valid_url.test($(this).attr('href'))){
$(this).click( function() { open_litebox('hi'); });
}
});
}
Это решает проблему области, как описано в других ответах. Если вам нужно вызвать open_litebox() с параметрами, оберните его внутри анонимной функции, как я, или же функция будет вызываться, а затем возвращаемое значение будет передано в действие click. В противном случае, без параметров для передачи, назначение проще:
$(this).click( open_litebox );