明白了,阿杰,你想做一个 HTML5 项目能同时兼容多端 SDK(Web、App、H5、微信/小程序等) 的小技巧或方案。这里给你整理一些 实用经验与代码示例。
1️⃣ 核心思路:抽象平台差异
- 定义统一接口(统一方法名和参数)
- 在不同端引入对应 SDK 或桥接方法
- 上层业务直接调用统一接口,不关心底层实现
// 定义统一 SDK 接口
const SDK = {
login: function(options){
if(window.AppSDK){
AppSDK.login(options); // 原生 App SDK
} else if(window.WeixinJSBridge){
// 微信 JS SDK
wxLogin(options);
} else {
webLogin(options); // H5 Web fallback
}
},
share: function(options){
if(window.AppSDK){
AppSDK.share(options);
} else if(window.wx){
wxShare(options);
} else {
alert('请复制链接分享');
}
}
};
优势:业务层统一调用
SDK.login()、SDK.share(),无需关心不同端实现细节。
2️⃣ 平台检测技巧
- 通过 User-Agent 或 全局对象 判断平台
- 建议优先检测 SDK 提供的对象或函数
function getPlatform() {
const ua = navigator.userAgent.toLowerCase();
if(window.AppSDK) return 'app';
if(window.wx) return 'wechat';
if(/micromessenger/.test(ua)) return 'wechat';
if(/iphone|ipad|ipod/.test(ua)) return 'ios';
if(/android/.test(ua)) return 'android';
return 'web';
}
console.log('当前平台:', getPlatform());
3️⃣ 封装通用工具方法
- 封装请求接口、分享、支付、摄像头、定位等
- 通过统一接口自动选择 SDK 实现
// 示例:统一获取地理位置
function getLocation(callback){
if(window.AppSDK && AppSDK.getLocation){
AppSDK.getLocation(callback);
} else if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(callback);
} else {
callback({error:'不支持定位'});
}
}
// 使用:
getLocation(pos => console.log('坐标:', pos));
4️⃣ 条件编译/按需加载 SDK
- 对于 H5 可以按需加载 SDK 脚本,减小首屏体积
- 使用动态加载 JS
function loadScript(url, callback){
const script = document.createElement('script');
script.src = url;
script.onload = callback;
document.body.appendChild(script);
}
// 根据平台加载不同 SDK
const platform = getPlatform();
if(platform === 'wechat'){
loadScript('https://res.wx.qq.com/open/js/jweixin-1.6.0.js', () => {
console.log('微信 SDK 加载完成');
});
} else if(platform === 'app'){
loadScript('https://example.com/app-sdk.js', () => {
console.log('App SDK 加载完成');
});
}
5️⃣ 小技巧总结
- 统一接口封装
- 所有业务逻辑调用统一方法,屏蔽 SDK 差异
- 平台检测优先级
- 优先检测 SDK 提供的对象,其次 UA
- 动态加载 SDK
- 按需加载脚本,提升 H5 页面性能
- 提供 fallback
- App SDK、微信 SDK 不可用时,提供 Web fallback
- 事件与回调统一
- SDK 回调接口各不相同,建议封装成 Promise 或统一回调函数
function sdkLogin(){
return new Promise((resolve, reject) => {
SDK.login({
success: resolve,
fail: reject
});
});
}
明白了,阿杰!我帮你整理了一个 HTML5 多端 SDK 封装实战模板,可以同时兼容 Web、App、微信 H5、小程序(部分接口示例),特点:
- 统一接口:登录、分享、定位、拍照
- 自动检测平台
- 按需加载 SDK
- Promise 风格调用,业务层直接用
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H5 多端 SDK 封装模板</title>
</head>
<body>
<h1>H5 多端 SDK 封装 Demo</h1>
<button id="loginBtn">登录</button>
<button id="shareBtn">分享</button>
<button id="locBtn">获取位置</button>
<script>
// ----------------------------
// 1️⃣ 平台检测
function getPlatform(){
const ua = navigator.userAgent.toLowerCase();
if(window.AppSDK) return 'app';
if(window.wx) return 'wechat';
if(/micromessenger/.test(ua)) return 'wechat';
if(/iphone|ipad|ipod/.test(ua)) return 'ios';
if(/android/.test(ua)) return 'android';
return 'web';
}
const PLATFORM = getPlatform();
console.log('当前平台:', PLATFORM);
// ----------------------------
// 2️⃣ SDK 动态加载示例
function loadScript(url){
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.body.appendChild(script);
});
}
// 根据平台按需加载 SDK
async function initSDK(){
if(PLATFORM === 'wechat'){
await loadScript('https://res.wx.qq.com/open/js/jweixin-1.6.0.js');
console.log('微信 JS SDK 加载完成');
} else if(PLATFORM === 'app'){
await loadScript('https://example.com/app-sdk.js');
console.log('App SDK 加载完成');
}
}
initSDK();
// ----------------------------
// 3️⃣ 封装统一接口
const SDK = {
login: function(){
return new Promise((resolve, reject) => {
if(PLATFORM === 'app' && window.AppSDK){
AppSDK.login({success: resolve, fail: reject});
} else if(PLATFORM === 'wechat' && window.wx){
// 微信登录示例(可换成实际接口)
wx.miniProgram.getEnv((res)=>{
resolve({platform:'wechat', env: res.miniprogram});
});
} else {
// Web fallback
resolve({platform:'web', user:'guest'});
}
});
},
share: function(options){
if(PLATFORM === 'app' && window.AppSDK){
AppSDK.share(options);
} else if(PLATFORM === 'wechat' && window.wx){
wx.ready(() => {
wx.updateAppMessageShareData(options);
});
} else {
alert('请复制链接分享: ' + options.link);
}
},
getLocation: function(){
return new Promise((resolve, reject) => {
if(PLATFORM === 'app' && window.AppSDK && AppSDK.getLocation){
AppSDK.getLocation(resolve);
} else if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(resolve, reject);
} else {
reject({error:'不支持定位'});
}
});
},
takePhoto: function(){
return new Promise((resolve, reject) => {
if(PLATFORM === 'app' && window.AppSDK && AppSDK.takePhoto){
AppSDK.takePhoto(resolve);
} else if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia){
// H5 摄像头示例
navigator.mediaDevices.getUserMedia({video:true})
.then(stream => {
resolve({stream});
})
.catch(reject);
} else {
reject({error:'不支持拍照'});
}
});
}
};
// ----------------------------
// 4️⃣ 页面按钮事件绑定
document.getElementById('loginBtn').addEventListener('click', async ()=>{
try{
const res = await SDK.login();
console.log('登录结果:', res);
alert('登录成功: ' + JSON.stringify(res));
} catch(err){
console.error(err);
alert('登录失败');
}
});
document.getElementById('shareBtn').addEventListener('click', ()=>{
SDK.share({
title: '多端 SDK 示例',
desc: 'H5 + App + 微信统一封装',
link: window.location.href
});
});
document.getElementById('locBtn').addEventListener('click', async ()=>{
try{
const pos = await SDK.getLocation();
console.log('位置:', pos);
alert('经纬度: ' + JSON.stringify(pos));
} catch(err){
console.error(err);
alert('获取位置失败');
}
});
</script>
</body>
</html>
🔹 使用说明
- 平台自动检测
PLATFORM变量:app、wechat、web、ios、android
- 统一接口调用
SDK.login(),SDK.share(),SDK.getLocation(),SDK.takePhoto()- 返回 Promise,业务层可统一
await
- 按需加载 SDK
- 微信 JS SDK / App SDK 动态加载
- Web fallback 不依赖任何 SDK
- 业务层无感知差异
- 无需关心底层平台差异
- H5、App、微信环境都可调用同一接口
发表回复