Для начала давайте вернемся к тому как подключать кастомные javascript файлы к нашей теме. В файле .libraries.yml нужно подключить js:
global-styling: version: 1.x css: theme: css/style.css: {} css/print.css: { media: print } js: js/custom.js: {} dependencies: - core/jquery - core/jquery.once
Важно соблюдать отступы, чтобы он был в два пробела. Итак, мы подключили файл js/custom.js. Но этого не достаточно чтобы у нас работал jQuery. Дело в том что ядро друпала не требует jQuery и jQuery не подключается. Его нужно подключать отдельно:
dependencies: - core/jquery
Также мы будем использовать jQuery.once(), это отдельный плагин для jQuery, для того чтобы навешивать события и методы на селектор только однажды.
dependencies: - core/jquery - core/jquery.once
Дело в том, что мы будем писать код javascript, который будет вызывать друпалом несколько раз по разным событиям. Поэтому нам будет нужен этот метод .once().
Теперь давайте добавим немного кода в файл custom.js:
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { $(context).find('.click-me').once('myCustomBehavior').click(function () { alert('Hello, World!'); }); } }; })(jQuery);
Давайте разберем по порядку, что это все значит.
(function ($) { })(jQuery);
Мы оборачиваем код jQuery в такую конструкцию, потому что jQuery в друпале запускается в режиме .noConflict(). Это нужно для того чтобы использовать знак доллара $, и это не конфликтовало с другими javascript фреймворками Prototype, MooTools. Вряд ли вам придется встретиться с этими фреймворками, jQuery плотно занял лидирующие позиции. Но в эту конструкцию вам придется оборачивать весь jQuery-код.
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { } }; })(jQuery);
Вот мы и подошли к behavior'ам. Если вы пишите jQuery код в друпале, вам нужно его во-первых обернуть в function($), а во-вторых в behavior. Имя behavior'а должно быть уникальным, у нас в примере myModuleBehavior, но вам нужно для каждого behavior писать свое имя:
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { } }; Drupal.behaviors.productPageBehavior = { attach: function (context, settings) { } }; })(jQuery);
Используйте camelCase для наименования behavior'ов. Behavior вызывается при загрузке страницы, на каждый AJAX-запрос. Таким образом, когда на сайт подгружается новый контент и встраивается в структуру существующего сайта, то вызывается код из behavior, каждый раз. Это значительно отличается от конструкции:
$(document).ready(function () { // Do some fancy stuff. // Не используйте такой код в Drupal 8 (да и в Drupal 7 тоже). });
которая вызывается только один раз при загрузке странице.
Если вы начали использовать behavior'ы и заметили, что у вас происходят странные события с сайтом, например через jQuery блок добавляется несколько раз:
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { // Behavior вызывается несколько раз на странице, не забывайте использовать функцию .once(). $('.inner').append('<p>Test</p>'); } }; })(jQuery);
При каждом ajax-запросе у вас будет добавлять еще один параграф Test. Поэтому нужно добавить функцию .once():
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { // Behavior вызывается несколько раз на странице, не забывайте использовать функцию .once(). $('.inner').once('add-paragraph').append('<p>Test</p>'); } }; })(jQuery);
Еще одна фича behavior это переменная context. Каждый раз когда на сайт добавляется новый контент при загрузке страницы или через ajax, то весь новый контент находится в переменной context. Таким образом нам не нужно проходить все DOM дерево, после каждого ajax запроса, чтобы навесить событие на селектор. Достаточно пройтись только по context'у:
(function ($) { Drupal.behaviors.myModuleBehavior = { attach: function (context, settings) { // Behavior вызывается несколько раз на странице, не забывайте использовать функцию .once(). $(context).find('.inner').once('add-paragraph').append('<p>Test</p>'); } }; })(jQuery);
Теперь добавление параграфа написано в правильном друпал стиле. Конечно, вы можете использовать старую запись с document.ready(), но тогда это будет работать только один раз и медленнее чем через behavior'ы.
Если у вас возникнут вопросы по jQuery/javascript или предложения по дополнительным темам пишите в комментариях.
Комментарии
Добавить комментарий
Здравствуйте. Каким образом
Здравствуйте. Каким образом здесь объявляются js-функции, которые в дальнейшем нужно вызывать, например через onClick?
(function ($) {
Как запустить меню Superrcih
Как запустить меню Superrcih в друпал8
А можно ссылочку на меню, что
А можно ссылочку на меню, что бы глянуть что оно из себя представляет? На drupal.org не нашел его.
Может быть superfish? Его
Может быть superfish? Его можно запустить с помощью модуля superfish:
https://www.drupal.org/project/superfish
Здравствуйте! Подскажите, я
Здравствуйте! Подскажите, я сделал вывод вьюсом блока новостей, с постраничным навигатором по 2 новости, навигатор через аякс.
В одной теме все работает как надо, а включаю другую постраничный навигатор через аякс не работает, просто перегружает страницу. все это через colorbox работает, в обоих темах все js необходимые подключены.
Что еще можно проверить?
Здраствуйте, нужно в первую
Здраствуйте, нужно в первую очередь посмотреть console DOM-инспектора, если там ошибка, то ajax не будет срабатывать. Возможно также файл не подключается какой-нибудь javascript. Ajax может не работать если есть второй Views на этой же странице и там не используется ajax. Если вы открываете страницу через colorbox node в попапе, где уже есть страница с пагинатором, то это тоже может плохо работать, потому что для работы ajax нужна библиотека drupal.
Можно подключить эту библиотеку глобально для темы в файле THEMENAME.libraies.info:
И можно использовать в 8ом друпале вместо colorbox обычную ссылку, просто добавить к ней CSS класс .use-ajax и параметр для открывания в попапе data-dialog-type="modal":
http://www.mediacurrent.com/blog/loading-and-rendering-modal-forms-drupal-8 - здесь можно пример посмотреть формы с попапом.
Создал файл Customjs.js
Создал файл Customjs.js добавил туда код, прописал его в mytheme.libraries.yml. Верхний фрагмент кода должен темизировать чекбоксы, проблема в том, что в модальном окне он выполняется несколько раз, а на странице модуля contact не хочет работать.