You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:16:35