Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   после AJAX перестаёт работать event (https://javascript.ru/forum/events/80058-posle-ajax-perestajot-rabotat-event.html)

greenwar 22.04.2020 16:14

после AJAX перестаёт работать event
 
function set_ajax_hover_cb()
{
    var menuShowTimer = 0;
    $('a.ajax_hover').hover(
    function(e)
    {
        // время задержки, если указано
        var wait_time = this.getAttribute('data-time')   || 300;

        menuShowTimer = setTimeout(
        (function()
        {
            // без return function() задержка отсутствует ^^
            return function()
            {
                ajaxGET(e,   $(e.currentTarget).attr('data-ajax'),   $(e.currentTarget).attr('data-ajax-qs'));
            }
        }) (this), wait_time)
    },
    // то что должно происходить при hover
    function()
    {
        clearTimeout(menuShowTimer);
        // тут ещё код...
    });
}

код при hover вызывает ф-ю
вызов этого кода (ссылка, по которой происходит hover) находится в таблице, которая может обновляться через AJAX
и вот после обновления код тот же самый, а вызов уже не работает...
есть нюанс - вызов set_ajax_hover_cb() стоит в самом низу, после таблицы, т.е. вызывается 1 раз.
но даже если его вместе с AJAX вызывать, всё равно НЕ работает :(

greenwar 23.04.2020 12:09

парни, идей нет совсем?

voraa 23.04.2020 12:34

Слишком мало информации
Цитата:

Сообщение от greenwar (Сообщение 523201)
вызов этого кода (ссылка, по которой происходит hover) находится в таблице, которая может обновляться через AJAX

Что означает, что вызов кода находится в таблице?
Как именно обновляется таблица? Что в ней обновляется?
Что делает ajaxGET?

И что?
Так
menuShowTimer = setTimeout(
      function()
            {
                ajaxGET(e,   $(e.currentTarget).attr('data-ajax'),   $(e.currentTarget).attr('data-ajax-qs'));
            }
  , wait_time)

Нет задержки?

На вскидку можно только предположить, что если ссылка (<a>) находится в таблице и меняется (создается новый элемент), то конечно к нему уже не привязаны обработчики событий hover

greenwar 23.04.2020 18:21

Цитата:

Сообщение от voraa (Сообщение 523279)
Как именно обновляется таблица? Что в ней обновляется?

вот это:
<a href='#' class='ajax_hover' data-ajax='/logs_tbl/8744158/ajax' data-ajax-qs='ent=7&id=8744158'>link</a>

Цитата:

Что делает ajaxGET?
он и заменяет таблицу на новую, и все вот эти вышеобозначенные линки.
Цитата:

Нет задержки?
есть, ради неё и юзаю такой код.

Цитата:

На вскидку можно только предположить, что если ссылка (<a>) находится в таблице и меняется (создается новый элемент), то конечно к нему уже не привязаны обработчики событий hover
вооот... А как их обратно перепривязать? Я же запускаю ф-ю снова, а толку нет...

voraa 23.04.2020 18:54

Надо смотреть, как вы обновляете таблицу и как потом перепривязываете обработчики к элементам.

voraa 23.04.2020 19:31

А вообще странное решение.
Мышь приходит на эту ссылку и остается.
Вы обновляете ее, новая ссылка оказывается под мышью. К ссылке привязывается обработчик, и малейшее движение мышью, хоть на пиксель, вызывает его срабатывание и все по новой...

greenwar 23.04.2020 20:25

так, стоп, я попутал...
эта ссылка с ajaxGET() вызывает fancybox с инфой
а таблицу обновляет поиск в отдельном <input ...>
это вообще отдельная история
но вот когда таблица обновилась (обновляется так же - через AJAX jQuery, там никакой магии), то походу и слетают все привязки
и потом почему-то не привязываются...

voraa 23.04.2020 20:46

Цитата:

Сообщение от greenwar (Сообщение 523315)
но вот когда таблица обновилась (обновляется так же - через AJAX jQuery, там никакой магии), то походу и слетают все привязки
и потом почему-то не привязываются...

Ну там есть кое-какая магия.
Процессы асинхронны. Нужно ждать, пока сервер ответит, ссылки создадутся, подключатся к DOM и только после этого привязывать обработчики.
Не видя кода обновления трудно сказать, что не так.

greenwar 23.04.2020 21:31

ну ф-я то вот:
function tbl_search_func(next_page_div_id, id, qs = '')
{
    $('#' +next_page_div_id).hide();
    ajaxPOST(id, qs);
    set_ajax_hover_cb(); // ф-я из первого поста
}

вызов:
<input type=text name='search_input' id='search_str' value='' onmousedown='$(this).select();return false;' oninput='tbl_search_func(`tbl-next-page-btn-div`, `#tbl_search`, `ent=43`)'

voraa 23.04.2020 23:27

Вот-вот.
Тут то и магия.
ajaxPOST(id, qs) там идет обращение к серверу. И асинхронное получение результата и его обработка, каким нибудь обратным вызовом success. Но никто не ждет пока success выполнится. Оно выполнится потом, когда с сервера придет ответ. А ajaxPOST спокойно завершается и начинает выполняться set_ajax_hover_cb(). Данные еще с сервера не пришли, таблицы и линки не обновились, и обработчики вешаются на старые линки.

Вызов set_ajax_hover_cb() надо ставить в ту функцию, которая формирует новые линки, сразу после того, как они вставляются в DOM/

greenwar 24.04.2020 00:32

так "та функция", это как раз ф-я ajaxPOST(), которая через jQuery вставляет новую таблицу.
там есть:
success: function(data) {ajaxRESULT(data);}

туда чтоли вставлять?
сейчас она стоит ПОСЛЕ неё... и всё равно не работает ^^

laimas 24.04.2020 02:49

Почему бы не $(родитель).on('mouseenter', 'a.ajax_hover' , ..., без надобности в set_ajax_hover_cb() ?

voraa 24.04.2020 07:08

Цитата:

Сообщение от greenwar (Сообщение 523320)
так "та функция", это как раз ф-я ajaxPOST(), которая через jQuery вставляет новую таблицу.
там есть:
success: function(data) {ajaxRESULT(data);}

туда чтоли вставлять?
сейчас она стоит ПОСЛЕ неё... и всё равно не работает ^^

После нее стоит - не значит, что после нее работает. В ajaxPOST() очевидно есть часть, которая работает асинхронно. Есть функция, которая работает, только, когда пришел ответ от сервера, после ответа от сервера идет изменение таблицы. И именно после этого изменения нужно вызывать set_ajax_hover_cb()

Вот представьте, что вы сейчас после вызова set_ajax_hover_cb() поставите вызов какой-нибудь функции foo().
Вызовется set_ajax_hover_cb(), затем foo(). А те функции, которые описаны в set_ajax_hover_cb(), как реакция на наведение мыши когда вызовутся? Когда нибудь потом, когда мышь наведется.
Так же и тут. в ajaxPOST() есть функция

function(data) {ajaxRESULT(data);}

которая работает "когда нибудь потом", когда придет ответ от сервера. Вот там, после изменения таблицы и надо делать вызов set_ajax_hover_cb()
Так можно сделать

success: function(data) {ajaxRESULT(data); set_ajax_hover_cb();}

greenwar 24.04.2020 10:35

Цитата:

Сообщение от laimas (Сообщение 523322)
Почему бы не $(родитель).on('mouseenter', 'a.ajax_hover' , ..., без надобности в set_ajax_hover_cb() ?

$( selector ).hover( handlerIn, handlerOut )

это ведь сокращённая версия для:
$( selector ).mouseenter( handlerIn ).mouseleave( handlerOut );

а вы хотите set_ajax_hover_cb() в handlerOut ? Что это даст?

greenwar 24.04.2020 10:38

Цитата:

Сообщение от voraa (Сообщение 523324)
success: function(data) {ajaxRESULT(data); set_ajax_hover_cb();}

там проблемка, она фиксирована, т.е. я её не создаю отдельно для этого вызова, а юзаю готовую...
и запихнуть туда ф-ю как?

laimas 24.04.2020 10:40

Цитата:

Сообщение от greenwar
это ведь сокращённая версия для

Нет, это делегирование обработки события родителю.

Цитата:

Сообщение от greenwar
а вы хотите set_ajax_hover_cb() в handlerOut ?

Я бы эту функцию вообще бы выбросил, как и не понимаю зачем тут таймер.

greenwar 24.04.2020 10:46

таймер, потому что это может быть "мышь проехала мимо", а выводить ничего не надо
а вот когда мышь остановилась на ссылке и прошло 0.5 сек, тогда уже точно надо
в предыдущей версии (которая рабочая, кстати, там нет этой проблемы)
там в конце таблицы так:
$('.tbl1 a.waitFB').hover(abc1,abc2);

и после обновления таблицы ничего не надо вставлять вроде
но я придумал не вставлять каждый раз 2 ф-и, а заменить на одну

laimas 24.04.2020 11:04

В таком случае таймер очищать можно и по ответу сервера, то есть обрабатывать нужно только заход на ... А делегирование решит остальные проблемы.

voraa 24.04.2020 11:20

Цитата:

Сообщение от laimas (Сообщение 523339)
В таком случае таймер очищать можно и по ответу сервера, то есть обрабатывать нужно только заход на ... А делегирование решит остальные проблемы.

Не должно быть обращения к серверу, если мышь задержалась на элементе меньше, чем на 0.5 сек. Как по ответу очищать, если не было обращения?

laimas 24.04.2020 11:34

Точно. Хотя не мала ли задержка в таком случае, в смысле насколько это полезно?

voraa 24.04.2020 11:54

Цитата:

Сообщение от laimas (Сообщение 523341)
Точно. Хотя не мала ли задержка в таком случае, в смысле насколько это полезно?

Это к автору
Хотя, как он писал
>> эта ссылка с ajaxGET() вызывает fancybox с инфой
То вполне нормально

laimas 24.04.2020 12:23

Может быть, ну тогда таймер->очистка и запрос/нет по условию, то есть уход в общем то можно и не обрабатывать.

PS. То есть просто проверить по срабатываю над кем в это время находимся.

greenwar 24.04.2020 12:59

там 300ms, этого достаточно, чтобы на "промах" мышки не реагировать.

так, вопрос: почему даже при том, что я сначала гружу аяксом таблицу, а в конце таблицы ставлю вызов set_ajax_hover_cb(), даже в этом случае всё равно не прописывается как надо...
таблица то уже загружена
все ссылки обозначены
этот set_ajax_hover_cb() должен выставить events на уже существующие ссылки...
но не выставляет :(

voraa 24.04.2020 13:19

Сложно ответить не видя, как вы формируете таблицу.
Проще самому просто залезть в отладчик и по шагам смотреть, что когда выполняется, Находятся ли новые ссылки.

greenwar 24.04.2020 13:20

ну в смысле как?
сервер отдаёт строку, эта строка втыкается в <div>
втыкает её jQuery через AJAX
как он там её втыкает...

а как отладку по шагам смотреть?

voraa 24.04.2020 13:49

Цитата:

Сообщение от greenwar (Сообщение 523354)
втыкает её jQuery через AJAX

Через AJAX строку можно получить. Но сам AJAX ее никуда не вставит.
Это вы должны вставить полученную строку div.

Цитата:

Сообщение от greenwar (Сообщение 523354)
а как отладку по шагам смотреть?

В любом браузере есть отладчик. Там можно видеть код, ставить на операторах точки останова, смотреть значение переменных...
Так же можно просмотреть все элементы, которые есть в DOM, посмотреть их стили, какие классы CSS к ним применились...
Как можно без отладчика что то делать?

voraa 24.04.2020 13:59

Цитата:

Сообщение от greenwar (Сообщение 523336)
success: function(data) {ajaxRESULT(data); set_ajax_hover_cb();}

там проблемка, она фиксирована, т.е. я её не создаю отдельно для этого вызова, а юзаю готовую...
и запихнуть туда ф-ю как?

Кто фиксированная? Вы получаете строку. Она в data. Очевидно ajaxRESULT вставляет эту строку в div. Ну и потом надо навесить обработчики с помощью set_ajax_hover_cb();

greenwar 24.04.2020 15:02

вот этот success: находится в ф-и ajaxPOST(), которая одна для всех
(фиксирована)
я её не создаю каждый раз заново
и как туда воткнуть внутрь success что-то?

success: function(data) {ajaxRESULT(data); set_ajax_hover_cb();}

вот так всё работает, кстати... Тогда надо через переменную передать название ф-и и запускать её внутри...

greenwar 24.04.2020 15:12

Цитата:

Сообщение от voraa (Сообщение 523358)
Через AJAX строку можно получить. Но сам AJAX ее никуда не вставит.
Это вы должны вставить полученную строку div.

ну вставляю я эту строку с html-кодом таблицы в div... на что смотреть то?
там опять же нет никакой магии. string с куском кода.

Цитата:

В любом браузере есть отладчик. Там можно видеть код, ставить на операторах точки останова, смотреть значение переменных...
Так же можно просмотреть все элементы, которые есть в DOM, посмотреть их стили, какие классы CSS к ним применились...
Как можно без отладчика что то делать?
да, я ошибки там смотрю. Прям чтобы по шагам отлаживать пока не сталкивался...

greenwar 24.04.2020 15:42

Цитата:

Сообщение от greenwar (Сообщение 523363)
вот этот success: находится в ф-и ajaxPOST(), которая одна для всех
(фиксирована)
я её не создаю каждый раз заново
и как туда воткнуть внутрь success что-то?

success: function(data) {ajaxRESULT(data); set_ajax_hover_cb();}

вот так всё работает, кстати... Тогда надо через переменную передать название ф-и и запускать её внутри...

в общем сделал, работает :dance:
спасибо всем за участие
извините, что столько времени отнял с очевидной проблемой


Часовой пояс GMT +3, время: 10:10.