阅读主题
H5 宿主界面与事件
适用版本:v0.4.0。本页前置为已有 SDK 实例及自己的页面容器。SDK 提供显式挂载的统一账号 UI。openCenter()、showFloating()、hideFloating() 仍只发送事件,不自动创建完整中心与浮球。
仓库 apps/playground 是 React 参考 UI,包含登录、侧边中心、浮球、钱包、订单和客服;安装 .tgz 不会安装或自动挂载该应用。若复用参考实现,需要处理你的宿主 CSS、画布输入、滚动、触摸和生命周期。
统一登录与注册入口
游戏登录路由应移除原生表单和外层登录卡片,仅保留独立挂载容器;不要把 SDK 卡片套在原生“账号/密码”页面内部。游戏背景是否保留由宿主布局决定,mountAuth() 不会删除宿主页面或自动接管路由。
html
<main id="sdk-auth-root" aria-label="游戏账号入口"></main>
<style>
#sdk-auth-root { min-height: 100dvh; display: grid; place-items: center;
padding: 24px 16px; background: #10121f; }
</style>ts
import { sdk } from './sdk';
const authView = sdk.mountAuth(document.getElementById('sdk-auth-root')!, {
mode: 'login',
consentVersion: '2026-09',
termsUrl: 'https://your-game.example.com/terms',
privacyUrl: 'https://your-game.example.com/privacy',
onAuthenticated: async session => {
// 可信 exchange 已完成;由游戏自己的路由进入选服/角色流程。
await enterYourGame(session);
},
});
// 路由离开时清理控件和尚未完成的登录事务。
// authView.destroy();协议 URL 必须是有效 HTTPS 页面,示例域名需替换为真实页面。界面提供独立注册、用户名/已绑定手机登录、协议确认、状态反馈以及按能力显示的可选手机验证。注册成功只提示并返回登录页,不自动登录。Shadow DOM 防止游戏全局 input/checkbox 样式污染控件;外层容器尺寸、路由、背景和画布输入仍由游戏负责。
AuthMountOptions 可传 mode、consentVersion、termsUrl、privacyUrl、onAuthenticated、onCancel 和高级 authenticate 回调;普通接入使用 SDK 默认 login() 即可。返回 setMode('login'|'register') 与 destroy()。短信服务不可用时显示原因,不能把灰置入口当成短信已经接通。
最小事件适配
以下为可运行的原生 DOM 适配示例,页面应先提供这些元素。它展示事件连接方式,不是完整登录、订单或支付页面。
html
<button id="platform-orb" type="button" hidden>账号中心</button>
<dialog id="platform-dialog" aria-labelledby="platform-title">
<h2 id="platform-title">账号中心</h2>
<p id="platform-content"></p>
<button id="platform-close" type="button">关闭</button>
</dialog>
<p id="platform-error" role="status"></p>ts
import { sdk } from './sdk';
const orb = document.querySelector<HTMLButtonElement>('#platform-orb')!;
const dialog = document.querySelector<HTMLDialogElement>('#platform-dialog')!;
const content = document.querySelector<HTMLParagraphElement>('#platform-content')!;
const close = document.querySelector<HTMLButtonElement>('#platform-close')!;
const error = document.querySelector<HTMLParagraphElement>('#platform-error')!;
const openHome = () => sdk.openCenter('home');
const closePanel = () => dialog.close();
const dispose = [
sdk.on('floating', visible => { orb.hidden = !visible; }),
sdk.on('center', ({ view }) => {
content.textContent = view === 'login'
? '请在宿主登录表单完成登录。'
: sdk.getSession() ? '已登录,可读取平台中心数据。' : '请先登录。';
if (!dialog.open) dialog.showModal();
}),
sdk.on('session', session => {
if (!session) { content.textContent = ''; dialog.close(); }
}),
sdk.on('error', problem => { error.textContent = problem.message; }),
];
orb.addEventListener('click', openHome);
close.addEventListener('click', closePanel);
sdk.showFloating();
export function unmountPlatformUI() {
dispose.forEach(unsubscribe => unsubscribe());
orb.removeEventListener('click', openHome);
close.removeEventListener('click', closePanel);
orb.hidden = true;
dialog.close();
}预期:调用 showFloating() 显示宿主按钮;点击后打开宿主对话框;hideFloating() 隐藏按钮。没有订阅器时,这些方法不会产生可见效果。
请求、取消与界面状态
中心数据由 await sdk.center() 获取,不能把 center 事件视为数据已加载。显示加载/空列表/错误/重试状态,并在切号、页面关闭或组件卸载后丢弃旧渲染结果。SDK 会拦截旧认证请求覆盖新会话,但宿主自己的动画、异步渲染及游戏后端请求也要做生命周期校验。
关闭尚在登录中的表单时调用 sdk.cancelLogin(),再关闭表单。关闭普通中心不等于退出;只在用户明确退出时执行 logout()。不要因中心请求断网就清掉 token。
嵌入游戏时必须处理的行为
| 场景 | 宿主责任 |
|---|---|
| 全屏 canvas | 弹窗打开时暂停游戏相关按键/触摸,关闭后恢复,避免点击穿透 |
| iframe | 决定 SDK/UI 所在层级;浮球不能自动越过 iframe;跨窗口消息校验 origin 和结构 |
| 手机浏览器 | 安全区、软键盘、横竖屏、地址栏变化、触摸拖动和滚动冲突 |
| 键盘与辅助功能 | 可聚焦入口、对话框标题、Tab 焦点、Escape 关闭和关闭后的焦点返回 |
| 主题/样式 | 对接已有页面命名空间,避免全局 reset 覆盖宿主;不能假设包内有主题 API |
| 弱网与支付返回 | 显示处理中/查询中,先查询原订单,不用动画完成作为付款成功依据 |
统一账号卡片由本版 SDK 显式挂载;完整平台中心、浮球和 Unity WebGL/Cocos 游戏内桥接仍需宿主集成与实际环境验收。继续查看 会话策略 与 API 参考。
客服列表应保留 tickets() 返回的 nextCursor 并提供加载更多;不要只展示默认首批 50 条就当作全部历史。自定义页面重试支付/权益动作时保存本次 requestId,再调用支持可选 ID 的对应方法。