Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Почему не работает делегирование? (https://javascript.ru/forum/events/76812-pochemu-ne-rabotaet-delegirovanie.html)

seotapki 16.02.2019 17:26

Почему не работает делегирование?
 
Всем привет.

Ребят, помогите.
Подключил к странице JS библиотеку zoom, все работает ОК, но после подгрузки товаров ajax запросом, перестает работать библиотека zoom. Почему перестает работать - разобрался(библиотека получает элементы и работает с ними, после подгрузки по AJAX она о них не знает).

Стал гуглить и понял, что нужно делать делегирование, вот код:

(() => {
    document.body.innerHTML += `<div id="lumos-container">
                                    <img src="" id="lumos-image">
                                </div>`;
    const lummContainer = document.getElementById('content'); // добавил контейнер
    const lumosContainer = document.getElementById('lumos-container');
    const lumosImage = document.getElementById('lumos-image');
    const elements = document.querySelectorAll('[data-action="lumos"]');
    const transitionSpeedInMilliseconds = 250;

    window.addEventListener('keyup', (event) => {
        if (event.key === 'Escape') {
            hideLumos();
        }
    });

    // elements.forEach((element) => {
    //     element.addEventListener('click', () => {
    //         handleElementClick(element);
    //     });
    // });


lummContainer.onclick = (e) => {
   var target = e.target; // элемент который вызвал событие
   var lumoelement = target.getAttribute('[data-action="lumos"]');
   
   if (lumoelement) {
        handleElementClick(lumoelement);
      }
}




    lumosContainer.addEventListener('click', hideLumos);

    function handleElementClick(htmlElement) {
        updateLumosImage(getImageUrl(htmlElement));
        showLumos();
    }

    function getImageUrl(htmlElement) {
        return htmlElement.attributes['data-lumos-src'] === undefined
            ? htmlElement.attributes['src'].value
            : htmlElement.attributes['data-lumos-src'].value;
    }

    function updateLumosImage(imageUrl) {
        lumosImage.attributes['src'].value = imageUrl;
    }

    function showLumos() {
        if (!lumosContainerIsVisible()) {
            lumosContainer.classList.remove('hidden');
            lumosContainer.classList.add('visible');
        }
    }

    function hideLumos() {
        if (lumosContainerIsVisible()) {
            lumosContainer.classList.add('hidden');

            setTimeout(() => {
                lumosContainer.classList.remove('visible');
                lumosContainer.classList.remove('hidden');
                lumosImage.attributes['src'].value = '';
            }, transitionSpeedInMilliseconds);
        }
    }

    function lumosContainerIsVisible() {
        return lumosContainer.classList.contains('visible');
    }
})();


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

<div id="content">

<div class="category-panel-block">
      <div class="sort-block"></div>
</div>

      <div class="row category-products-wrapper-block" data-bal="append-bal">
        

<! -- оставил только один товар, остальные удалил -->
<div id="category-product-block" class="item item-good" data-bal="element-bal">


  <div class="item-good-wrapper">
    <div class="item-good_img">
      <img data-action="lumos" src="/2812201812_test_1323sg0-228x228.jpg" data-lumos-src="/2812201812_test_1323sg0-800x800.jpg" alt="Мужские наручные часы DANIEL KLEIN (Тестовый товар)" class="lumo-zoom-img">
    </div>
  </div>

   <div class="item-good_buttons">
        <button class="btn2 btn2-buy-item btn2-buy_small smca-call-button" type="button" onclick="getOCwizardModal_smca('33','add');"><i class="fa fa-shopping-cart"></i> <span class="hidden-xs hidden-sm hidden-md">Уже в корзине</span></button>
    </div>

 </div>


</div>
</div>
</div>


вроде все правильно пишу, но не работает, что не так??


Библиотека: https://github.com/oliverschwendener/lumos

рони 16.02.2019 17:31

Цитата:

Сообщение от seotapki
document.body.innerHTML +=

попробуйте избавится от этого, есть другие методы.
https://learn.javascript.ru/multi-insert#insertadjacent

seotapki 17.02.2019 07:11

Цитата:

Сообщение от рони (Сообщение 503708)
попробуйте избавится от этого, есть другие методы.
https://learn.javascript.ru/multi-insert#insertadjacent

Пробовал так: http://prntscr.com/mm4zaq

но это тоже не помогает, после Ajax подгрузки товаров не работают новые товары.

Пробовал завернуть все в функцию:

document.addEventListener("DOMContentLoaded", function(event) {
    // здесь код
  });



так все работает(точнее библиотека работает, но ломается AJAX - страница просто обновляется.

рони 17.02.2019 08:01

Цитата:

Сообщение от seotapki
target.getAttribute('[data-action="lumos"]');

???
target.hasAttribute("data-action");

seotapki 17.02.2019 08:34

Цитата:

Сообщение от рони (Сообщение 503717)
???
target.hasAttribute("data-action");

По этому моменту тоже понял, что вернется не элемент, а lumos,

Вопрос в том, что концепция в челом правильная? чтобы это заработало или нет?

рони 17.02.2019 09:10

seotapki,
lummContainer.onclick = (e) => {
   var target = e.target; // элемент который вызвал событие
   var action = target.dataset.action;

   if (action == 'lumos') {
        handleElementClick(target);
      }
}

seotapki 17.02.2019 09:46

Цитата:

Сообщение от рони (Сообщение 503721)
seotapki,
lummContainer.onclick = (e) => {
   var target = e.target; // элемент который вызвал событие
   var action = target.dataset.action;

   if (action == 'lumos') {
        handleElementClick(target);
      }
}

Спасибо большое за помощь, получилось :)


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