vivo H5游戏详情页规范及SDK接入文档

一、版本记录

版本 修改内容 修改时间
v1.0.0 -
v1.0.1 新增game-vivo-config.js配置项
新增adsense脚本加载完成事件
-
v1.0.2 adsense脚本加载完成返回值修改
新增adsense脚本加载时长埋点上报
2026-06-23
  1. 若游戏页使用iframe在详情页内嵌打开,查看目录二、目录三
  2. 若游戏页使用一个新的webview打开,查看目录二、目录四

二、游戏详情页代码包

2.1 详情页规范介绍

详情页设计稿

2.2 代码包目录说明

├── index.html     # 游戏详情页
├── detal/         # 游戏详情页静态资源
│   ├── xxx.js
│   └── xxxx.css
├── manifest.json  # 配置项(配置说明见2.3)
├── game-vivo-config.js  # 同manifest.json(若同manifest与本身项目配置冲突,可以改用这个)
├── icon.png       # 游戏icon(需要替换)
├── sdkAds.js      # 广告通信和API初始化(需自行实现广告逻辑)
├── game.html      # 游戏页面(需要替换)
└── game.js        # 游戏静态资源(游戏页面相关静态资源可在根目录创建game文件进行管理)

2.3 配置项说明

  1. 修改manifest.json/game-vivo-config.js配置项
// mainifest.json
{
  "iframeOpen": true, // 游戏页使用iframe内嵌,更多查看目录三
  "gameInfo": {
    "gameLink": "game.html?a=xxxx", // 根目录的game.html,后面可根据需要拼接参数
    "gameName": "游戏名称",
    "icon": "icon.png", // 请替换根目录下的icon
    "adsenseAccountId": "ca-pub-xxxxxxxxxxx",
    "gameDesc": "游戏介绍",
    "score": 4.3,
    "adList": ["广告1号位", "广告2号位"],
    "recommendList": [
      // 8个游戏推荐
      {
        "gameLink": "https://xxxxxx", // 游戏完整链接
        "gameName": "游戏名称",
        "icon": "游戏icon链接"
      }
    ]
  }
}
  1. 替换根目录下的icon.png为当前游戏的图标
  2. 将游戏代码包和详情页代码包合并,记得覆盖根目录下的game.html文件

2.4 代码包下载

更新jssdk版本时,请同步更新代码包

对应js sdk版本 代码包 修改内容 修改时间
v1.0.0 - -
v1.0.1 下载 1. 添加深色适配
2.优化广告banner尺寸
v1.0.2 下载 1. play按钮曝光埋点新时长参数
2.根据Adsense加载完成返回修改监听方法
3.修复iframe方式下详情页停留时长上报丢失
4. play按钮在广告banner显示后延迟1s 或者 adsense加载完成延迟5s显示
2026-06-29

2.5 详情页页面测试

  1. 在详情页链接上添加env=test,详情页的广告将会启用测试模式

三、iframe内嵌打开游戏页

3.1 前提

manifest.json配置"iframeOpen": true

3.2 在game.html向父window发送消息

function postMessageToParent(params) {
  window.parent.postMessage(
    JSON.stringify(params),
    "https://xxxxxxx", // 父window的域名
  );
}

3.3 注册消息接收

window.addEventListener("message", (e) => {
  // 根据消息是否来自父window的域名,判断是否过滤
  if (e.origin !== "https://xxxxxxx") {
    console.warn("其他消息(来自:" + e.origin + ")");
    return;
  }
  console.log(e, "从父window发过来的消息");
  try {
    const paramsFromParent = JSON.parse(e.data);

    // 根据methon类型,执行不同逻辑
  } catch (error) {
    console.log(error);
  }
});

3.4 调用页面加载性能数据

为了便于平台分析游戏页面加载性能并进行优化,请在游戏首屏加载完成(例如:首个可交互画面展示)调用getPerformanceTrack() 方法,并将性能数据通过postMessage上报给父页面。

由于父窗口无法准确获取 iframe 内页面的性能指标,因此需要在 游戏页面内部执行该方法 并主动上报

  1. 使用示例
async function reportGameLoading() {
  const performanceData = await getPerformanceTrack();

  postMessageToParent({
    method: "gameLoadingCompleted",
    data: performanceData,
  });
}
  1. 性能采集方法 请将以下getPerformanceTrack方法添加到你的项目中:
function getPerformanceTrack() {
  return new Promise((resolve) => {
    let count = 0;

    function check() {
      if (window.performance && window.performance.timing) {
        const timing = window.performance.timing;

        // 等待 loadEventEnd 产生
        if (timing.loadEventEnd === 0) {
          if (count++ > 100) {
            resolve({});
            return;
          }
          setTimeout(check, 100);
          return;
        }

        const paints = performance.getEntriesByType("paint");
        const fcp = paints?.find(
          (paint) => paint.name === "first-contentful-paint",
        );
        const fp = paints?.find((paint) => paint.name === "first-paint");

        const calc = (end, start) => {
          return end > 0 && start > 0 && end >= start ? end - start : 0;
        };

        const {
          navigationStart,
          responseStart,
          domContentLoadedEventEnd,
          loadEventEnd,
          domainLookupEnd,
          domainLookupStart,
          connectEnd,
          connectStart,
          secureConnectionStart,
          domComplete,
          domLoading,
          domInteractive,
        } = timing;

        const effectiveLoadEventEnd =
          loadEventEnd > 0
            ? loadEventEnd
            : domComplete > 0
              ? domComplete
              : Date.now();

        resolve({
          ttfb: calc(responseStart, navigationStart),
          wst: calc(responseStart, navigationStart),
          tti: calc(domInteractive, navigationStart),
          ready: calc(domContentLoadedEventEnd, navigationStart),
          load: calc(effectiveLoadEventEnd, navigationStart),
          dns: calc(domainLookupEnd, domainLookupStart),
          tcp: calc(connectEnd, connectStart),
          ssl:
            secureConnectionStart > 0
              ? calc(connectEnd, secureConnectionStart)
              : 0,
          dom: calc(domComplete, domLoading),
          fpt: fp ? Math.max(0, parseInt(fp.startTime.toFixed())) : 0,
          fcp: fcp ? Math.max(0, parseInt(fcp.startTime.toFixed())) : 0,
        });
      } else {
        resolve(null);
      }
    }

    check();
  });
}

3.5 谷歌广告相关

自行在sdkAds.js中实现广告通信以及Ad Placement API初始化

广告详细参数介绍请参考谷歌参数用法:https://developers.google.com/ad-placement/apis/adbreak?hl=zh-cn

四、SDK接入说明

4.1 添加 sdk 依赖

<script :src="`https://sdk.vivofungame.com/${version}/index.min.js`"></script>

按照1.2目录的版本号修改version,目前最新版是v1.0.1

4.2 sdk 初始化

在标签中配置

<script>
  window.vivoSDKConfig = {
    adConfig: {
      adTest: true,  // 启用Adsense测试模式,若想启用正式模式请删掉该字段
      adFrequencyHint: '', // 广告展示频次,默认120s
      adClient: "ca-pub-xxxxx"
    },
    adsComplete: function (state) {
      if (state.done && state.success) {
        console.log("AdSense 已加载完成");
      }

      if (state.done && !state.success) {
        console.log("AdSense 加载结束,但加载失败");
      }
    },
  }
</script>
4.2.1 adsComplete说明

adsComplete 会返回一个 state 对象:

字段 类型 含义
done boolean 本次 AdSense 加载流程是否已经结束。true 代表流程已收口,不会一直等待
success boolean 本次 AdSense 是否加载成功

常见状态可以这样理解:

state.done state.success 含义
true true AdSense 已加载完成,脚本可正常使用
true false AdSense 加载流程已结束,但加载失败,常见于超时、网络异常、域名被拦截等场景

如未传 adsComplete,或者业务存在晚于 SDK 完成时机才开始监听的情况,建议使用以下方式:

window.vivoSDK.onAdsComplete(function (state) {
  if (state.done && state.success) {
    console.log("AdSense 已加载完成");
  }

  if (state.done && !state.success) {
    console.log("AdSense 加载结束,但加载失败");
  }
});

window.addEventListener("vivoSDK:adsComplete", function (event) {
  if (event.detail && event.detail.done && event.detail.success) {
    console.log("AdSense 已加载完成");
  }

  if (event.detail && event.detail.done && !event.detail.success) {
    console.log("AdSense 加载结束,但加载失败");
  }
});

var adState =
  window.vivoSDK && window.vivoSDK.getAdSenseState
    ? window.vivoSDK.getAdSenseState()
    : { done: false, success: false };

if (adState.done && adState.success) {
  console.log("AdSense 已加载完成");
}

if (adState.done && !adState.success) {
  console.log("AdSense 加载结束,但加载失败");
}

4.3 页面加载性能数据:gameLoadingCompleted

请务必把这个方法加到游戏首屏加载完成的时候,上报游戏页面的加载时长数据,便于后续的分析优化

window.vivoSDK.gameLoadingCompleted("game", options);

4.4 游戏内广告

自行实现Ad Placement API广告相关逻辑

五、游戏自动广告规范

5.1 锚定广告:仅限底部,且不允许使用折叠式锚定广告

设置路径:Google AdSense—广告—编辑管理自动广告—重叠式广告格式—锚定广告—高级设置

(1)不勾选:允许折叠式锚定广告等

(2)选择锚定广告位置:仅限底部

参考如下图1:

自动广告规范

5.2 穿插广告

设置路径:Google AdSense—广告—编辑管理自动广告—重叠式广告格式—穿插广告—高级设置

(1)穿插广告展示频次:2分钟

(2)不勾选:允许为穿插广告启用额外触发条件等

参考如下图2:

自动广告规范