Подтвердить что ты не робот

Функция, не вызывающая внутри события 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, но я ее определил.

Я почти не знаю, что здесь происходит, может ли кто-нибудь дать мне руку?

Спасибо.

4b9b3361

Ответ 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 );