Рейтинг:0

Выполнять поведение только один раз при загрузке страницы

флаг in

При переходе с Dupal 7 на 9 у меня возникла проблема с многократным вызовом поведения javascript. В консоли браузера, когда я загружаю страницу, я вижу:

проверка процесса для [объекта HTMLDocument] pet_guides.js:27:15
проверка процесса для [объекта HTMLUListElement] pet_guides.js:27:15
проверка процесса для https://whiskerdocs-local-d9.pglatz.com/portal/config/user-interface/shortcut/manage/default/customize pet_guides.js:27:15
проверка процесса для [объекта HTMLUListElement] 2 pet_guides.js:27:15
проверка процесса для [объекта HTMLElement] 2 pet_guides.js:27:15

Это мой код:

  Drupal.behaviors.guideTest = {
    прикрепить: функция (контекст, настройки) {
      console.log('проверка процесса для ' + контекст);
    }
  };

Я просматриваю документы на drupal.org и пока не вижу в них смысла. Что я действительно хочу сделать, так это где console.log запустить цикл, например

  $.each($('.section-обертка'), функция(индекс) {
    $(это).addClass('foo');
  });

Каков правильный синтаксис для использования Once(), чтобы это выполнялось только один раз? Если бы у меня было поведение с более чем одним циклом, есть ли способ использовать единую оболочку Once() вокруг них всех, или для каждого вида нужен свой собственный? Я думал, что использование поведения похоже на использование jQuery (документ) .ready (функция ($), поэтому код будет выполняться только тогда, когда DOM будет полностью загружен, и не понимаю, почему он вызывается для пяти разных контекстов.

Рейтинг:1
флаг ru

Я думал, что использование поведения похоже на использование jQuery(document).ready(function ($), поэтому код будет только выполняется, когда DOM был полностью загружен, и не понимаю, почему это вызывается для пяти различных контекстов.

Нет. Если бы это было так, поведение было бы бессмысленным.

  1. Поведения привязаны к одному узлу DOM, потому что в Drupal вы не знаете, когда этот узел DOM визуализируется/вставляется на страницу (вспомните BigPipe, представления Ajax, корзины покупок Ajax и т. д.).
  2. Поведения запускаются в первый раз после того, как DOM готов, И, возможно, очень часто впоследствии, когда в DOM вводятся новые партиалы. Чтобы избежать дублирования прослушивателей событий на уже существующих, старые узлы используют однажды-функция.
  3. контекст просто ускоряет отсоединение и повторное присоединение поведения, если вы опускаете контекст, любая инъекция узла DOM должна искать потенциальные поведения во всем документе, а не только внутри контекста вновь введенного частичного.
  4. Эквивалент $(документ).готов() будет звонить $(документ, контекст).once() внутри поведения, потому что контекст документа передается только один раз.

Код вашего цикла будет выглядеть так:

Drupal.behaviors.myCustomBehavior= {
  прикрепить: функция (контекст, настройки) {
    $('.section-wrapper', контекст).once('myCustomOnceId').each( function(index) {
      $(это).addClass('foo');
    });
  }
};

Так, например. если твой <div class="section-wrapper"> находится внутри строки представления с бесконечной прокруткой, каждый <div> получит ровно один фу класс, независимо от того, когда он загружен.

Продолжая приведенный выше пример с представлением бесконечной прокрутки и классом "foo", после двух инъекций Ajax...

... без использования поведения вы получите что-то вроде
<div class="section-wrapper foo"></div><div class="section-wrapper"></div><div class="section-wrapper"></div>

...используя поведение без однажды, вы получите что-то вроде
<div class="section-wrapper foo foo foo"></div><div class="section-wrapper foo foo"></div><div class="section-wrapper foo"></div>

pglatz avatar
флаг in
Спасибо за понятное объяснение и примеры.

Ответить или комментировать

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