Как я могу использовать Drupal.behaviors, чтобы уведомить H5P о том, что он меняет размер?
У меня нет опыта работы с Drupal. Мы перешли с Drupal 7. Был функционал, который настраивает все элементы и после нажатия на определенные кнопки части сайта становятся видимыми.
С переходом на Drupal 10 все было интегрировано в .
Теперь мне нужно добавить несколько элементов H5P. Так как первая загрузка сайта начинается сdisplay: none;
высота элементов H5P становится 0 пикселей.
Я нашел этот .
Но я не могу заставить эту работу работать в нашем .
Вот код, который работает аналогично:
(function ($, Drupal) {
Drupal.behaviors.myModule = {
attach : function(context, settings) {
once('these-tabs', 'these_buttons', context).forEach((these_buttons) => {
$(".switcher_link").click(function () {
$(".paragraph").hide();
$(".paragraph").removeClass("activated");
$(".paragraph-with-h5p-elem").fadeIn();
$(".paragraph-with-h5p-elem").addClass("activated");
});
[...]
});
}
}
})(jQuery, Drupal);
Если я нажму кнопку и запущу инструменты веб-разработчика в своем браузере, все будет работать нормально. Но если я не активирую инструменты, контент H5P не отображается. Итак, я предполагаю, что H5P должен получить уведомление о том, что он должен изменить свой размер. Это происходит во время обновления, вызванного инструментами веб-разработчика.
Я попытался добавить следующее:
[...]
$(window).trigger("resize");
[...]
[...]
$(this).trigger("resize");
[...]
оба, похоже, не уведомляют обработчик H5P.
Если я попытаюсь активировать функцию H5P, описанную документ, описывающий мои проблемыздесь:
[...]
ui.newPanel.css('height', 'auto');
H5P.jQuery(window).trigger('resize');
[...]
он просто говорит мне, что не существует известного пакета «ui» или «H5P». Они не являются частью пространства имен. Но «импортируя» их, просто добавляя})(jQuery, Drupal, H5P);
тоже не работает.
Когда я пытаюсь:
[...]
$(window).reload();
[...]
он говорит мне, что «перезагрузка» не является функцией.
Решение кажется таким простым: уведомить H5P о том, что он должен снова изменить свой размер. Но я пока не могу заставить его работать в Drupal.behaviors.
РЕДАКТИРОВАТЬ Спасибо, user9453575 . Но, к сожалению, вы упустили суть. Чтобы быть более ясным:
(function ($, Drupal) {
Drupal.behaviors.myModule = {
attach : function(context, settings) {
once('these-tabs', 'these_buttons', context).forEach((these_buttons) => {
$(".switcher_link").click(function () {
$(".paragraph").hide();
$(".paragraph").removeClass("activated");
$(".paragraph-with-h5p-elem").fadeIn();
$(".paragraph-with-h5p-elem").addClass("activated");
$(document).ready(function () {
$(".switcher_link").on("click", function () {
console.log("Link for H5P activated!");
$(".paragraph-with-h5p-elem").height("1337px");
H5P.jQuery(window).trigger('resize');
});
});
});
[...]
Не работает с Drupal.behaviors. Его размер должен измениться, нажав кнопку с классом «switcher_link» во второй раз. Вывод в журнале гласит: «Ссылка для H5P активирована!». Таким образом, прослушиватель событий работает так, как задумано. Даже высота выставлена правильно. Но видео не будет показано.
Так что мое сообщение: «Обходной путь, предложенный людьми из H5P, не работает с Drupal.behaviors», тем не менее, остается верным.
Между тем у меня были некоторые идеи по этому поводу: остается пустым! По крайней мере, он должен быть заполнен объектом, найденным в . ИМХО, поэтому он ничего не делает во времяH5P.jQuery(window).trigger('resize');
.
Остальные вопросы:
- Я правильно понял: должен содержать хотя бы один объект? ->
Я доказал, что должен содержать хотя бы один объект H5P. Всякий раз, когда я использую H5P вне модификации кнопок, он заполняется.Не во всех случаях: похоже, есть исключения.2. Почему при использовании остается пустым?
EDIT2: Путем повторной реализации без показа всего, кроме H5P. Пока я ничего не изменю в браузере (включение/выключение инструментов веб-разработчика, переключение полноэкранного режима в браузере и т. д.). Я думал, это не работает сDrupal.behaviors
в Drupal 10. Но я не работаю сjQuery
, слишком. После этого я протестировал разные браузеры: та же проблема. После этого я изменил контент H5P с интерактивного видео на другой контент: все заработало как задумано! Возвращаясь назад: H5P продолжает отсутствовать. Это пахнет жуком.
EDIT3: После использованияconsole.log(document); console.log(window);
в модуле «отладки» javascript я мог бы отследить некоторые детали.
Вdrupal/web/modules/h5p/vendor/h5p/h5p-core/js/h5p.js
я вставилconsole.log("H5P.instance.push: ", instance); console.log("H5P.instances: ", H5P.instances);
сразу послеH5P.instance.push(instance);
(около строки 369). Я имею в виду это. И в jQuery от нас я вставил строчкуif (document.readyState === "complete") { setTimeout(() => {console.log("H5P.instances: ", H5P.instances);}, 2000); };
. Я имею в виду это.
Если я использую пример Hello World
Greeting card
:
«экземпляр» показывает:
Object { options: {…}, id: 17, "$": {…}, contentId: 17, libraryInfo: {…} }
"$": Object { 0: {…}, length: 1 }
contentId: 17
id: 17
libraryInfo: Object { versionedName: "H5P.GreetingCard 1.0", versionedNameNoSpaces: "H5P.GreetingCard-1.0", machineName: "H5P.GreetingCard", … }
options: Object { greeting: "Hello world!", image: {…} }
<prototype>: Object { on: on(type, listener, thisArg), once: once(type, listener, thisArg), off: off(type, listener), … }
h5p.js:370:13
и «H5P.instances» показывает
H5P.instances:
Array [ {…} ]
0: Object { options: {…}, id: 17, contentId: 17, … }
length: 1
<prototype>: Array []
h5p.js:371:13
показывает:
H5P.instances:
Array [ {…} ]
0: Object { options: {…}, id: 17, contentId: 17, … }
length: 1
<prototype>: Array []
our_jquery.js:28:36
Это изменяет размер без каких-либо проблем. Мне даже не нужно вставлять дополнительный код: он автоматически меняет размер, устанавливаяdisplay: block; height: 400px;
к родительскому узлу.
Если я использую
Single Choice Set
:
[1]
«экземпляр» показывает:
H5P.instances.push:
Object { contentId: 18, contentData: {…}, userResponses: [], on: on(type, listener, thisArg), once: once(type, listener, thisArg), off: off(type, listener), trigger: trigger(event, eventData, extras), order: (10) […], setBehaviour: setBehaviour(options), setVideo: setVideo(params), … }
h5p.js:370:13
и содержит:
H5P.instances:
Array [ {…} ]
0: Object { contentId: 18, contentData: {…}, userResponses: [], … }
length: 1
<prototype>: Array []
h5p.js:371:13
Но[2]
показывает только:
H5P.instances:
Array []
length: 0
<prototype>: Array []
our_jquery.js:28:36
Изменение размера в этом случае не работает.
Мое впечатление такое:
- должен содержать элементы, потому что каждый раз, когда он находит HTML-теги с классом
.h5p-content
он наполняется иH5PIntegration.contents
(определено в h5p-integration.js) с разными форматами объектов (см. строки 58 и 59 в ). Действительно, это происходит в каждом протестированном случае, но не в тех случаях, когда изменение размера не работает. Это имеет смысл, потому чтоH5P.trigger(
вh5p.js
определяется только дляinstance
. Дословно:H5P.trigger(instance, 'resize');
(строки 127, 129, 319, 330, 361, 364, 376, 568, 585, 1011, 1359, 1361, 1391 и 1445). -
H5P.instances
кажется, просто сохраняет объекты в определенном формате. Все остальное как будто стирается. Проблема форматирования объекта возникает при полученииvar instance; ...
(строки 929 – 969).
Интересно, почему это происходит?
1 ответ
Кажется, вы вставляете код, даже не пытаясь понять, что он делает. Я думаю, что StackOverflow не должен способствовать этому. Итак, давайте попробуем помочь вам, не предоставляя бесплатную консультационную работу и предоставив полное решение ...
Когда ваш обратный вызов запущен, DOM все еще может бытьloading
. Это означает, что еще не вся страница создана, в частностиH5P
возможно, объект не был помещен в контекст. Вам нужно будет проверить наличиеreadyState
значение и продолжайте только в том случае, если оноinteractive
(по меньшей мере). Даже в этом случае вы все равно можете проверить доступность объекта H5P, если ваша функция присоединения запускается не только для содержимого Drupal, которое может содержать содержимое H5P.
После загрузки H5P ядро H5P будет прослушивать события наwindow
и пересылать их экземплярам типа контента H5P. Вы уже нашли способ вызвать такое событие ($(window).trigger('resize');
илиwindow.dispatchEvent(new Event('resize'));
в ванильном JavaScript, не полагаясь на такую структуру, как jQuery). Кстати, вы можете узнать больше о H5P и его механизме изменения размера .
Вам придется подождать, пока не будет создан экземпляр контента H5P. В противном случае запуск события не будет иметь эффекта. Вы можете добиться этого, используя диспетчер событий H5P, который запускаетinitialized
событие всякий раз, когда был инициализирован контент H5P на странице. Вы можете сделать это так:
H5P.externalDispatcher.on('initialized', () => {
// Do what needs to be done whenever H5P content was initialized ...
});
Вы упомянули, что контейнер, содержащий iframe H5P, возможно, не сможет увеличить высоту (поскольку CSSdisplay
свойство было установлено наnone
). Вам нужно будет убедиться, что это было изменено, прежде чем запускать файл . В противном случае iframe H5P не сможет увеличить высоту, даже если размер содержимого внутри изменится.
Кроме того, вы можете убедиться, что весь ваш обратный вызов выполняется только один раз, поскольку Drupal использует метод
attach
функция . В противном случае вы можете сработать несколько раз, что ничего не сломает, ноresize
может быть дорогостоящим, поскольку может вызвать множество вычислений.
Надеюсь, это поможет вам найти решение.