多平台 H5 开发基础:HTML5、CSS3、JavaScript ES6+
做跨平台 H5,说白了就是用这三样东西打底:HTML5 搭骨架、CSS3 刷样式、ES6+ 写逻辑。很多新人总盯着框架看,可一旦遇到奇葩的网关或老旧浏览器,框架可能直接罢工。这时候,基本功就是你的救命稻草。
记住一句话:框架是锦上添花,三件套才是雪中送炭。
HTML5 新特性:别再只用 div 打天下
HTML5 带来的不只是新标签,更是一套语义化和能力的升级。我当年在做一个老年手机报项目时,就因为用了 <article> 和 <section>,屏幕阅读器访问量直接翻了一倍。你想想看,这不仅是代码层面的变化。
- 语义化标签:
<header>、<footer>、<nav>、<article>、<section>。不只是 SEO 友好,对无障碍也一样。 - 多媒体能力:
<audio>和<video> 原生支持。我踩过坑:Android 4.4 上video必须加playsinline属性,否则会弹出全屏播放器,用户体验很差。 - 表单增强:
input type="email / url / number / tel / date"等。移动端虚拟键盘会自动切换。 - 本地存储:
localStorage和sessionStorage。存一些用户偏好,别什么都丢 Cookie。 - Canvas / SVG:绘图和图表。
- Geolocation、Web Worker、History API:用得少,但偶尔有大用。
注意:sessionStorage 在移动端(尤其 iOS Safari 的隐私模式)下可能会写入失败。我之前负责的金融 H5 就因为这个崩溃过——建议做一次写入检测。
CSS3:移动端适配的核心武器
CSS3 直接决定了你的页面在各屏幕上的样子。我习惯把适配分成两层:布局层和细节层。
布局层——Flexbox 与 Grid
Flexbox 是目前移动端兼容性最好的布局方案。Grid 虽然强大,但在部分 WebView(比如微信内 X5 内核)上还不完美。我个人习惯:用 Flexbox 做一维布局,Grid 只做二维且已知兼容性时用。
/* 经典三列等分,自动换行 */
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 1 33.33%;
/* 移动端可以改成: flex: 1 1 50%; 甚至 100% */
}
细节层——圆角、渐变、阴影、动画
| 特性 | 兼容性提醒 | 我的处理 |
|---|---|---|
border-radius |
几乎全兼容 | 放心用 |
linear-gradient |
iOS 8 以下有 bug | 加 fallback 纯色 |
box-shadow |
Android 低版本性能差 | 少用扩散,或配合 will-change |
transform |
3D 变换因设备而异 | 尽量不用 rotateX/Y/Z |
animation / transition |
部分国产浏览器丢帧 | 动画前加 translateZ(0) 开启 GPU 加速 |
我曾经在一个 H5 活动页上用了大量 box-shadow,结果红米 Note 3 滚动时卡得像 PPT。解决办法:把阴影换成 border 伪元素,或者只在视觉焦点元素上保留阴影。
JavaScript ES6+:让代码更简洁、更健壮
ES6 的普及度相当高,但某些内嵌浏览器(比如低版本 WebView 或老款车机)可能不支持所有特性。我建议用 Babel 编译后再加 polyfill,但也要控制 polyfill 的体积。
常用 ES6+ 特性及兼容要点
- let / const:放心用,除非你还在支持 iOS 9 以下。
- 箭头函数:注意它不绑定
this,在事件回调中很实用。 - 模板字符串:拼接 HTML 太方便了,但别放太大的模板,可读性会下降。
- 解构赋值:
const { name, age } = userObj;减少临时变量。 - Promise / async-await:告别回调地狱。但要注意:某些低版本机型的
Promise.prototype.finally不支持,要手动 polyfill。 - Map / Set:比 Object 和 Array 更擅长去重和快速查找。我在网关鉴权场景里用 Set 存已请求过的 值,避免重复刷新。
// 用 async/await 实现一个简单的图片加载
async function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
// 使用
try {
const img = await loadImage('https://example.com/logo.png');
document.body.appendChild(img);
} catch(e) {
console.warn('图片加载失败,使用兜底图');
}
避坑提醒:模块化与 Class
import / export 在原生浏览器中需要 type="module",但很多网关环境(比如阿里系的 UC 内核)不支持模块化脚本。我习惯用 Webpack 或 Rollup 打包成一个文件,保证兼容。
至于 class 语法糖,它本质还是原型链。不过记得,低版本浏览器不认 class,所以必须经过 Babel 转码。
核心原则:所有 ES6+ 代码在实际发布前,务必用 Babel 降级 + core-js polyfill。千万不要盲目相信“现代浏览器都支持”。
小结
HTML5、CSS3、ES6+ 这三根柱子缺一不可。在写多平台 H5 时,我会先确定目标设备和浏览器清单,然后针对性地选择特性:能用原生就用原生,不能就垫 polyfill。记住,先写标准代码,再考虑优雅降级,而不是反过来。这样你的页面在大部分主流环境里都能跑得稳。
嗯,接下来就该看看怎么把这些东西跟网关对接了——那是另一套考验。