Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   куда пропадает event ? (https://javascript.ru/forum/events/77678-kuda-propadaet-event.html)

greenwar 06.06.2019 09:53

куда пропадает event ?
 
всем привет!

есть такой JQ-плагин - datepicker
и вызывается он кликом по полю:
$( function() {
    $( "#datepicker" ).datepicker();
  } );


так вот, если это делать внутри FancyBox-окна (FB), то после закрытия окна ($('#fb_div').hide())
этот календарь больше НЕ показывается

т.е. если так:
1. открыть FB
2. закрыть FB (.hide())
3. снова открыть FB
4. ткнуть в поле #datepicker
...то календаря нет :(

при этом вот так всё ок:
$('#datepicker').on('mousedown', function(e) {alert('aaaa');});


а вот так опять нет:
$('#datepicker').on('mousedown', function(e) {
    $( '#datepicker' ).datepicker();
});

т.е. работает только в первый раз :-/

как найти и починить косяк??

рони 06.06.2019 10:08

Цитата:

Сообщение от greenwar
FancyBox

создаёт "окна" при открытии, они новые каждый раз, ставить иницициализацию после открытия.
делайте макет.

рони 06.06.2019 10:15

greenwar,
примерно так ...
$(/*  */).fancybox({
	afterShow : function( instance, current ) {
		$( "#datepicker" ).datepicker();
	}
});

Malleys 06.06.2019 10:24

рони, что я сделал не так, оно работает и с
$(function() {
   $("#datepicker").datepicker();
});
https://codepen.io/Malleys/pen/XwwZvd

greenwar 06.06.2019 10:34

рони, я не юзаю fancybox(), у меня свой
он просто делает .show() / .hide()

а полная конструкция такая (внутри FB):
$(function()
{
    $('#datepicker').datepicker();
});

т.е. после загрузки FB там вешается листенер...
а потом походу что-то его обрубает...
как бы понять - что?

greenwar 06.06.2019 10:34

Цитата:

Сообщение от Malleys (Сообщение 508788)
рони, что я сделал не так, оно работает и с
$(function() {
   $("#datepicker").datepicker();
});
https://codepen.io/Malleys/pen/XwwZvd

эта магия походу только там и работает
перенёс в html-файл и нифига не видно FB...

Malleys 06.06.2019 10:50

Цитата:

Сообщение от greenwar
эта магия походу только там и работает

Как будто вы не знаете, что оно не будет работать без соответствующей инициализации! Там или у вас!

Цитата:

Сообщение от greenwar
перенёс в html-файл и нифига не видно FB...

Так надо полностью все ресурсы перенести, которые я добавил...
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-bootstrap/0.5pre/assets/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css">

<style>

html, body {
	height: 100%;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: center;
}

.datepicker-container {
	z-index: 100000 !important;
}

</style>


<div style="display: none;" id="hidden-content">
	<input id="datepicker">
</div>

<button data-fancybox data-src="#hidden-content">
	Trigger the fancybox
</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js"></script>
<script>

$(function() {
   $("#datepicker").datepicker();
});


</script>


Цитата:

Сообщение от greenwar
у меня свой
он просто делает .show() / .hide()

Тогда ничего не должно мешать его работе... Элемент добавленный на страницу на который добавлен обработчик события никак не теряет обработчики... Элемент даже можно отсоединять от принявшего его документа (в jQuery с его ограниченными методами такое по моему нельзя сделать?) и с обработчиками ничего не происходит... Возможно у вас где-то происходит опасный вызов jQuery метода html, который заменяет содержимое... Тогда обработчики будут утеряны! Посмотрите, чтобы у вас не было такого опасного вызова при помощи jQuery!

UPD Ещё обнаружил такой ужас... если в jQuery вызвать на элементе метод off, то он удаляет все обработчики добавленные при помощи jQuery... без различия откуда обработчики были добавлены: вами или "плагином" (а плагины добавляют обработчики неявно, т. е. вы не видите в своем коде метод on, и соответственно думаете, что off выключит только ваши обработчики), поскольку jQuery не изолирует обработчики плагинов от обработчиков вашего приложения... (а laimas-то говорил нам, что библиотека как раз для новичков... всё просто и понятно... а тут столько не очевидностей... ) Проверьте, может вы где вызываете очистку от своих обработчиков при помощи метода off, заодним подчищая обработчики "плагина".

рони 06.06.2019 11:41

Цитата:

Сообщение от Malleys
Ещё обнаружил такой ужас...

мне сложно это понять, я считаю что метод off нормально работает.
Цитата:

Сообщение от Malleys
рони, что я сделал не так,

если у вас ничего не удаляется, то почему что-то должно пропасть.

рони 06.06.2019 11:41

greenwar,
делайте макет!

greenwar 06.06.2019 14:01

Цитата:

Сообщение от Malleys
Так надо полностью все ресурсы перенести, которые я добавил...

ну конечно я всё добавил...
...всё, кроме этого:
<script src='https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js'></script>


ну да, заработало...
кстати, если вызван календарь и нажать на крест, то FB исчезает, а календарь остаётся...
а если нажать на background серый, то всё ок.

.off() есть такой вот:
$(FB_bg).off('mouseup');

(при нажатии на bg)
но его отключение ничего не меняет...

макет щас попробую...

Malleys 06.06.2019 14:14

Цитата:

Сообщение от greenwar
кстати, если вызван календарь и нажать на крест, то FB исчезает, а календарь остаётся...
а если нажать на background серый, то всё ок.

Ну это вопрос к писателям "плагинов" jQuery (а на деле расширятелям прототипа jQuery) почему они любят без дела отменять распространение событии по DOM...

laimas 06.06.2019 14:19

Цитата:

Сообщение от Malleys
а laimas-то говорил нам, что библиотека как раз для новичков... всё просто и понятно... а тут столько не очевидностей...

Блин, можно подумать, что для начинающего JS так же понятна как Мурзилка. Может хватит кости мыть? Кстати, в jQ много чего не так как ожидаем и что из этого?

greenwar 06.06.2019 16:45

Цитата:

Сообщение от Malleys
Возможно у вас где-то происходит опасный вызов jQuery метода html, который заменяет содержимое... Тогда обработчики будут утеряны! Посмотрите, чтобы у вас не было такого опасного вызова при помощи jQuery!

так у меня там кругом одни .html() -ы
и FB через .html()
а что не так?
а как иначе?

Dilettante_Pro 06.06.2019 18:24

Что-то ТС так и не выдает макет...
Если я правильно понял, то что-то вроде этого
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css">
<style>
html, body {
	height: 100%;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: flex-start;
}
#fb {
  display: none;
  border:1px solid black;
}
</style>


<div  id="fb">
	<input id="datepicker">
        <button id = "close">X</button>
</div>

<button id = "open">Open FB</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js"></script>

<script>
$(function() {
   $("#datepicker").datepicker();
   $("#open").on("click", function() {
        $("#fb").show();
        $("#open").hide();
    });
   $("#close").on("click", function() {
        $("#fb").hide();
        $("#open").show();
    });
});
</script>

greenwar 06.06.2019 18:32

с макетом проблемки, там аякс и всё сложно
про .html() можно поподробней, если в нём проблема?

Dilettante_Pro 06.06.2019 18:47

Пример опасного html()
Если не нажимать Переписать - все работает.
Если нажать - все вроде так же, но не работает.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css">
<style>
html, body {
	height: 100%;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: flex-start;
}
#fb {
  display: none;
  border:1px solid black;
}
</style>


<div  id="fb">
	<input id="datepicker">
        <button id = "close">X</button>
</div>

<button id = "open">Open FB</button>
<button id = "rewrite">Переписать</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js"></script>

<script>
$(function() {
   $("#datepicker").datepicker();
   $("#open").on("click", function() {
        $("#fb").show();
        $("#open").hide();
    });
   $("#close").on("click", function() {
        $("#fb").hide();
        $("#open").show();
    });
    $("#rewrite").on("click", function() {
        $("#fb").html('<input id="datepicker"><button id ="close">X</button>');

    });  
});
</script>

greenwar 06.06.2019 19:04

ну вот, мой случай - раз! и не работает
а какое решение вместо .html(), когда надо поместить HTML в блок?

рони 06.06.2019 19:14

Dilettante_Pro,
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">

</head>

<body>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css">
<style>
html, body {
	height: 100%;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: flex-start;
}
#fb {
  display: none;
  border:1px solid black;
}
</style>


<div  id="fb">
	<input id="datepicker">
        <button id = "close">X</button>
</div>

<button id = "open">Open FB</button>
<button id = "rewrite">Переписать</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js"></script>

<script>
$(function() {
   $("#fb").on("click", "#datepicker", function() {
   var datepicker = $(this).data("datepicker");
   datepicker || $(this).datepicker().focus() ;

})

   $("#open").on("click", function() {
        $("#fb").show();
        $("#open").hide();
    });
   $("#fb").on("click", "#close", function() {
        $("#fb").hide();
        $("#open").show();
    });
    $("#rewrite").on("click", function() {
        $("#fb").html('<input id="datepicker"><button id ="close">X</button>');

    });
});
</script>

</body>
</html>

рони 06.06.2019 19:16

Цитата:

Сообщение от greenwar
а какое решение

делегирование, строка 40 пост #18

greenwar 07.06.2019 06:46

у меня так, этот блок:
<div  id="fb">
    <input id="datepicker">
        <button id = "close">X</button>
</div>

изначально то пустой и по клику в него (через AJAX) грузится HTML с этим самым полем #datepicker (и другими, кстати, полями)
грузится через
$('#fb_div').html("код");


+ сами .js и .css файлы с датапикером (но это дело десятое)
а уже только потом клик в поле показывает календарь (или не показывает)

"закрытие" же окна происходит через $('#fb_div').hide();

ПРОБЛЕМА РЕШИЛАСЬ
путём переноса jquery-ui.js в <head></head>
(я его не гружу с инета, это же долго)
а если он подгружался с AJAX, то во второй раз календарь уже не показывался

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


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