IE7 и 8 не запускают события нажатия jQuery для элементов, добавляемых в таблицу - PullRequest
13 голосов
/ 22 апреля 2009

У меня ошибка IE, которую я не знаю, как исправить.

Использование jQuery Я динамически перемещаю меню для отображения элемента при наведении курсора.

Мой код (упрощенный) выглядит примерно так:

$j = jQuery.noConflict();

$j(document).ready(function()
{
    //do something on the menu clicks
    $j('div.ico').click(function() { alert($j(this).parent().html()); });

    setUpActions('#tableId', '#menuId');
});

//on mouseover set up the actions menu to appear on mouseover
function setUpActions(tableSelector, menuSelector)
{
    $j(tableSelector + ' div.test').mouseover(function()
    {
        //note that append will move the underlying
        //DOM element with all events from it's old
        //parent to the end of this one.
        $j(this).append($j(menuSelector).show());
    });
}

Похоже, что это меню неправильно регистрирует события для меню после его перемещения в IE7, IE8 и IE8-as-IE7 (да, MS, это действительно «новый движок рендеринга» в IE8, мы все вам верим) .

Работает как положено во всем остальном.

Вы можете увидеть поведение в базовой демонстрации здесь .

В демоверсии вы можете увидеть два примера выпуска:

  1. Изображение под кнопками должно меняться при наведении курсора (выполняется с помощью селектора CSS: hover). Он работает при первом наведении мыши, но затем сохраняется.
  2. Событие click не запускается - однако с помощью инструментов dev вы можете вызвать его вручную, и оно все еще подписано.

Вы можете увидеть (2) в инструментах разработчика IE8:

  1. Открыть страницу в IE8
  2. Open dev tools
  3. Выберите вкладку «Сценарий» и вложенную вкладку «Консоль»
  4. Введите: $j('#testFloat div.ico:first').click() для ручного вызова любых подписанных событий
  5. На странице будет предупреждение

Это означает, что я не теряю подписки на события, они все еще там, IE просто не вызывает их, когда я нажимаю.

Кто-нибудь знает, почему возникает эта ошибка (кроме как из-за почтенного движка IE)?

Есть ли обходной путь?

Может ли быть что-то, что я делаю неправильно, просто так работает, как и ожидалось во всем остальном?

Ответы [ 4 ]

10 голосов
/ 26 апреля 2009

Странно, хотя ваше событие щелчка не срабатывает в IE, если вы измените его на mousedown или mouse up, оно будет работать так, как вы ожидаете, хотя у вас все еще есть проблема с наведением изображения.

$j('div.ico').mouseup(function() { alert($j(this).parent().html()); });
2 голосов
/ 01 сентября 2011

У меня была такая же проблема, но ни одно из предыдущих решений не сработало. Проблема оказалась в том, что IE7 (я не тестировал другие версии IE) не будет регистрировать .click, если он связан после функции анимации. Так что это будет НЕ работа:

$("div.menubar-item").animate({
    color:"#000"
}, 0)

.click(function()
{
    //not firing
})

Но это БУДЕТ работа

$("div.menubar-item").click(function()
{
    //firing!
})

$("div.menubar-item").animate({
    color:"#000"
}, 0)

РЕДАКТИРОВАТЬ : То же самое верно для ввода мыши, отпускания мыши и т. Д.

РЕДАКТИРОВАТЬ 2 : Он по-прежнему будет запускать события и анимировать, если вы включите функцию анимации ПОСЛЕ щелчка, так что это тоже "допустимо":

$("div.menubar-item").click(function()
{
    //firing!
})

.animate({
    color:"#000"
}, 0)
1 голос
/ 23 апреля 2009

IE не копирует события в элементы, динамически добавляемые в DOM.

Попробуйте связать событие клика после добавления того, что вам нужно, или используйте .live ()

если вы используете clone (), не забудьте передать clone (true), чтобы явно запросить копирование обработчиков событий.

var actionMenu = $j(menuSelector);

//actionMenu is now an Instance of jQuery, not the DOM object
//because jQuery is chainable

actionMenu.hide();

// notice the clone(true)

$j(this).append( actionMenu.clone(true) );

jQuery является цепным, поэтому вы также можете написать это в синтаксисе «jQuery» как:

var clone = $j(menuSelector)
               .clone(true)
               .css('background-color', $j(this).css('background-color') );

$j(this).append(clone);

Я не думаю, что вам нужно показывать / скрывать, потому что это происходит так быстро.

0 голосов
/ 22 апреля 2009

Я бы настоятельно рекомендовал использовать живые события вместо последней jquery.

таким образом вы можете привязать элементы к классу css, которые не были созданы в начале, но привязка клика будет добавлена, когда будут добавлены новые элементы:

http://docs.jquery.com/Events/live

...