Drupal10迁移后:如何在Drupal.behaviors中触发H5P自调整大小?
解决Drupal10中隐藏H5P元素显示后高度为0的问题
问题核心
页面初始将元素设为display: none;,H5P初始化时因容器隐藏无法正确计算尺寸,导致显示后高度异常;且部分H5P类型(如Single Choice Set)的实例未存入全局H5P.instances数组,常规触发resize事件无效。
解决方案
1. 通过实例ID精准获取H5P实例
放弃依赖H5P.instances,改用H5P.instancesById(所有H5P实例都会被索引到这里),通过DOM元素的data-h5p-id属性定位实例:
Drupal.behaviors.h5pHiddenContentFix = { attach: function (context, settings) { // 绑定显示按钮的点击事件(确保只执行一次) $('.content-toggle-button', context).once('h5p-resize-trigger').click(function() { var targetContainer = $($(this).data('target')); targetContainer.show(); // 遍历显示区域内的所有H5P容器 targetContainer.find('.h5p-container').each(function() { var h5pInstanceId = $(this).data('h5p-id'); if (H5P.instancesById && H5P.instancesById[h5pInstanceId]) { var h5pInstance = H5P.instancesById[h5pInstanceId]; // 先重置容器高度为auto,清除初始隐藏的0高度影响 $(this).css('height', 'auto'); // 调用实例自身的resize方法 if (typeof h5pInstance.resize === 'function') { h5pInstance.resize(); } // 部分类型需延迟触发window resize确保生效 setTimeout(function() { window.dispatchEvent(new Event('resize')); }, 100); } }); }); } };
2. 处理AJAX加载的H5P内容
如果H5P是通过AJAX动态加载到隐藏区域的,需在AJAX完成后标记待处理,等显示时触发resize:
// 监听AJAX完成事件 $(document).on('ajaxComplete', function(event, xhr, settings) { // 判断请求是否涉及H5P内容 if (settings.url.includes('h5p')) { var ajaxTarget = $(settings.selector); if (ajaxTarget.is(':hidden')) { // 标记该容器需要在显示时处理H5P尺寸 ajaxTarget.data('h5p-await-resize', true); } else { // 直接处理已显示的H5P ajaxTarget.find('.h5p-container').each(function() { var h5pId = $(this).data('h5p-id'); if (H5P.instancesById[h5pId]) { H5P.instancesById[h5pId].resize(); } }); } } }); // 在显示按钮事件中检查标记 $('.content-toggle-button').click(function() { var targetContainer = $($(this).data('target')); targetContainer.show(); if (targetContainer.data('h5p-await-resize')) { targetContainer.find('.h5p-container').each(function() { var h5pId = $(this).data('h5p-id'); if (H5P.instancesById[h5pId]) { H5P.instancesById[h5pId].resize(); } }); targetContainer.removeData('h5p-await-resize'); } });
3. 特定H5P类型的特殊处理
对于像Single Choice Set这类可能不响应通用resize方法的类型,可查看实例的内部方法,调用其专属的尺寸更新函数:
// 在遍历H5P容器时添加 if (typeof h5pInstance.updateDimensions === 'function') { h5pInstance.updateDimensions(); } // 或针对特定类型判断 if (h5pInstance.libraryInfo.machineName === 'H5P.SingleChoiceSet') { // 执行该类型的尺寸更新逻辑 h5pInstance.$container.css('height', 'auto'); h5pInstance.trigger('resize'); }
关键注意点
H5P.instancesById是比H5P.instances更可靠的实例索引,覆盖所有H5P内容类型;- 必须在元素完全显示后再触发尺寸更新,避免容器仍处于隐藏状态时计算错误;
- 小延迟(如100ms)的
setTimeout能确保DOM渲染完成,提升resize的成功率。
内容的提问来源于stack exchange,提问作者keeduu
相关产品推荐
相关产品推荐

