...

Обработка браузерных событий в виджете Код

Тема в разделе "Вопросы по платформе", создана пользователем ntts2, 18 авг 2023.

  1. ntts2

    ntts2 Новичок

    Добрый день!
    Обращаюсь за помощью с таким вопросом. Есть потребность в регулировании/отображении кнопок на карточке просмотра элемента в зависимости от значений тех или иных полей. Для этого используется виджет "Код", где на на jquery событие ready вешается обработчик с определенной логикой. И всё работает хорошо при первичном открытии карточки. Но после редактирования и сохранения элемента карточка просмотра открывается заново перерисовываясь, при этом указанное выше событие ready повторно не обрабатывается. В связи с чем получаем некорректное отображение.
    Также прошу пояснить почему браузерные события "load" и "DOMContentLoaded" не отлавливаются вовсе.
    Заранее спасибо за пояснения.

    Вложения:

    Последнее редактирование: 18 авг 2023
  2. vyimova

    vyimova Участник

    Предполагаю, что так из-за того, что $(document).ready() по умолчанию срабатывает один раз при загрузке формы. Функция согласно документации jQuery срабатывает, когда на странице полностью загрузится HTML и DOM. А т.к. виджет на форме просмотра, то, следовательно, должен загрузиться HTML формы просмотра. Когда меняем режим формы на редактирование и затем снова на просмотр, то это мало на что влияет, т.к. основной HTML для формы с виджетом уже отрисован.
    Возможно, вам требуется какое-то другое событие для того, что отлавливать переключение формы.
  3. miliakova

    miliakova Техническая поддержка

    Добрый день!
    Статьи, которые помогут в вопросе: https://community.elma365.com/ru/threads/2192/ и https://community.elma365.com/ru/threads/192/

    Форма просмотра открыта, document ready, нажимаем Редактировать - поверх формы просмотра открывается Форма редактирования. Форма редактирования закрывается, мы возвращаемся на форму просмотра. Форма перерисовалась, но состояние document ready осталось неизменным, здесь обработчик не среагирует на динамические изменения.
    В случае, когда нужно дождаться отображения какого-либо элемента на форме - подойдут варианты setTimeout или модуль wait. Но в случае с Редактированием и возвратом на форму просмотра нам нужен наблюдатель MutationObserver.
    Для примера, воспроизведем такой кейс: на форме просмотра элемента приложения добавлена кнопка удаления элемента Удалить. Скроем ее по необходимости. В сценарии формы поставим условие, при котором вызывается функция скрытия кнопки. Эта функция будет описана в виджете Код, она будет устанавливать слушатель события на весь документ, и при его мутации - скрывать кнопку.

    [​IMG]
    Виджет Код с функцией addListener и опытами по различным слушателям в консоль:


    Код:
    
    <script>
      
    console.log('start script')
      
    console.log('document.readyState ',document.readyState)

      switch (
    document.readyState) {
        case 
    "loading":
          
    console.log('Страница все ещё загружается. document.readyState=loading')
          break;
        case 
    "interactive":
          
    console.log('Страница уже загружена. Теперь мы можем получить доступ к DOM объектам. document.readyState=interactive')
          break;
        case 
    "complete":
          
    console.log("Страница загружена вместе с дополнительными ресурсами. document.readyState=complete");
          break;
      }

      $(
    document).ready(async()=> {
          
    console.log("test1 document ready")
        })

      if (
    document.readyState === "loading") {
        
    console.log('Загрузка ещё не закончилась')
      } else {
        
    console.log(`Загрузка уже закончилась DOMContentLoaded уже сработал. addEventListener(DOMContentLoaded) перепрыгнут`)
      }

      $(
    document).change(async()=> {
          
    console.log("document change")
      })
     
      
    document.addEventListener('DOMContentLoaded', function(){
        
    console.log("test3 document DOMContentLoaded")
      })

      function 
    addListener(){
        
    // Конфигурация observer (за какими изменениями наблюдать)
        
    const config = {
          
    attributestrue,
          
    childListtrue,
          
    subtreetrue,
        };
        
    // Колбэк-функция при срабатывании мутации
        
    const callback = function (mutationsListobserver) {
          
    console.log('MutationObserver start')
          for (
    let mutation of mutationsList) {
            
    let btn_del document.querySelector(".btn-danger")   
            $(
    btn_del).css("display""none");
          }
        };

        
    // Создаём экземпляр наблюдателя с указанной функцией колбэка
        
    const observer = new MutationObserver(callback);

        
    // Начинаем наблюдение за настроенными изменениями целевого элемента
        
    observer.observe(documentconfig);

        
    // Остановим наблюдение при нажатии на крестик закрытия формы
        
    const button_close document.querySelector("body > elma-form > form > elma-complex-popup > div > section > div > header > div.btn-group.modal-header__controls > button.close.btn.btn-link.btn-style-icon.elma-icons.ng-star-inserted")
        if(
    button_close){
          
    button_close.addEventListener('click',()=>{
            
    console.log('button close click MutationObserver end')
            
    observer.disconnect()
          })
        } else {
          
    console.log('button close not found MutationObserver stop')
          
    observer.disconnect()
        }
      }
    </script>
    "DOMContentLoaded" не отлавливается в виджет Код, потому что DOMContentLoaded сработал до того, как скрипт был запущен.
    $(window).on("load" может отработать до скрипта, в котором мы пытаемся его слушать, может и отловить это событие в скрипте в редких случаях, здесь также и отловился document.readyState interactive:
    [​IMG]
    По предложенному решению с MutationObserver отмечу, что перезагрузка F5 страницы с открытой формой просмотра не найдет элемент кнопки и не скроет ее.