一、调用本地摄像头
1、input:file 方案
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html {
font-size: 36px;
}
input {
display: none;
}
label {
display: block;
}
span {
display: block;
text-align: center;
height: 50px;
font-size: 12px;
margin: 50px;
border: 1px solid #ccc;
padding: 10px;
line-height: 50px;
}
</style>
</head>
<body>
<label>
<span>打开相册,可以选择一张图片</span>
<input type="file" accept="image/*" />
</label>
<label>
<span>打开相册,可以选择多张图片</span>
<input type="file" multiple accept='image/*'>
</label>
<label>
<span>打开照相机</span>
<input type="file" accept="image/*" capture="camera" />
</label>
<label>
<span>打开录像机</span>
<input type="file" accept="video/*" capture="camcorder" />
</label>
<label>
<span>打开录音机</span>
<input type="file" accept="audio/*" capture="microphone" />
</label>
</body>
</html>
2、getUserMediaAPI 方案
getUserMediaAPI 是 H5 为我们提供的新的 API。该 API 最早是直接挂在 navigator 对象上面的,但是目前做了调整,navigator.getUserMediaAPI 已经被废弃,取而代之的是 navigator.mediaDevices.getUserMedia。
示例
<!-- 可以在电脑上展示 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
button {
width: 200px;
height: 50px;
font-size: 32px;
margin: 20px;
}
</style>
</head>
<body>
<button id="btn1">开启摄像头</button>
<button id="btn2">关闭摄像头</button>
<video id="video" controls width="100%" height="700px"></video>
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var video = document.querySelector("#video");
var myConstraints = {
video: {
facingMode: "user", // 优先调用前置摄像头
},
};
// 开启摄像
btn1.onclick = function () {
navigator.mediaDevices.getUserMedia(myConstraints).then(
(stream) => {
video.srcObject = stream;
//播放视频
video.play();
// 关闭摄像
btn2.onclick = function () {
stream.getTracks().forEach((track) => track.stop());
};
},
(error) => {
console.error(error.name || error);
}
);
};
</script>
</body>
</html>
环境
有下面三种情况是可以调起设备的,也就是 navigator.mediaDevices 不为 undefined:
- 地址为 localhost://
- 地址为 https://
- 为文件访问 file:///
兼容性
如果不考虑比较旧的浏览器的话,整体来讲也可以放心的去用。
二、方向变化事件 orientation
该事件的兼容性不是太好,作为了解即可。下图是 caniuse 上的兼容性情况:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 200px;
height: 200px;
background: green;
color: #fff;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
/*
deviceorientation 方向变化事件
alpha:设备围绕z轴方向旋转的度数,范围:0~360(顶部指向地球的北极,alpha此时为0)
beta:设备围绕x轴方向旋转的度数,由前向后,范围:-180~180
gamma:设备围绕y轴方向旋转的度数,由左向右,范围:-90~90
*/
const box = document.querySelector(".box");
window.addEventListener("deviceorientation", (ev) => {
box.innerHTML = `
z轴偏移的度数为:${ev.alpha.toFixed(2)}<br>
x轴偏移的度数为:${ev.beta.toFixed(2)}<br>
y轴偏移的度数为:${ev.gamma.toFixed(2)}<br>
`;
});
</script>
</body>
</html>
三、横竖屏切换 orientationchange
该事件的兼容性也不是太好
横竖屏切换也是移动端应用中一个非常常见的需求。
在早期的时候,我们可以监听 orientationchange 事件来判断用户是横屏还是竖屏,例如:
/*
window.orientation
检测横竖屏
0 竖屏(头朝上)
180 竖屏(头朝下)
90 横屏(头朝左)
-90 横屏(头朝右)
orientationchange
模竖屏幕切换事件(window身上的,ios中也可以加给document,但是不建议这么使用)
*/
//alert(window.orientation);
window.addEventListener('orientationchange',()=>{
if(window.orientation==90 || window.orientation==-90){
alert('横屏');
}else if(window.orientation==0 || window.orientation==180){
alert('竖屏');
}
});
但是目前这个 API 已经被完全废弃,如下图所示:
取而代之的是 ScreenOrientationAPI。ScreenOrientationAPI 为 Web 应用提供了读取设备当前屏幕方向、旋转角度、锁定旋转方向、获取方向改变事件的能力。使得特定应用在屏幕方向方面增强用户体验,如视频和游戏。
MDN 文档地址:https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation
可以简单的测试你的浏览器是否支持:
if(window.ScreenOrientation){
alert("OK");
} else {
alert("No");
}
出于一些安全方面的考虑,锁定方向时必须使页面处于全屏状态
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
<p>类型: <span id="type"></span></p>
<p>角度: <span id="angle"></span></p>
</div>
<div>
<select id="mode">
<!-- 竖屏状态并且旋转角度为 0 度,也就是设备的自然位置 -->
<option value="portrait-primary">portrait-primary</option>
<!-- 竖屏状并且即旋转角度为 180 度,也就是倒着拿的位置 -->
<option value="portrait-secondary">portrait-secondary</option>
<!-- 横屏状态并且旋转角度为 90 度 -->
<option value="landscape-primary">landscape-primary</option>
<!-- 横屏状态并且旋转角度为 270 度 -->
<option value="landscape-secondary">landscape-secondary</option>
</select>
<button id="lock">lock</button>
<button id="unlock">unlock</button>
</div>
<script>
const btn_lock = document.getElementById("lock");
const btn_unlock = document.getElementById("unlock");
const sel_mode = document.getElementById("mode");
const txt_type = document.getElementById("type");
const txt_angle = document.getElementById("angle");
// 锁定屏幕
btn_lock.addEventListener("click", function () {
document.documentElement.requestFullscreen().then(() => {
screen.orientation.lock(sel_mode.value).catch(() => {
alert("锁定失败");
});
});
});
// 解锁屏幕
btn_unlock.addEventListener("click", function () {
screen.orientation.unlock();
})
function updateTxt() {
txt_type.innerHTML = screen.orientation.type;
txt_angle.innerHTML = screen.orientation.angle;
}
screen.orientation.addEventListener("change", updateTxt);
window.addEventListener("load", updateTxt);
</script>
</body>
</html>
四、重力加速度 DeviceMotionEvent
官方文档地址:https://w3c.github.io/deviceorientation/
-
我们所使用的移动设备,和 PC 有一个区别在于会内置陀螺仪、罗盘及加速器等硬件,而作为开发者则可以从各个内置传感器那里获取未经修改的传感数据,并观测或响应设备各种运动和角度变化,这些传感器包括陀螺仪、加速器和磁力仪(罗盘)。
-
加速器和陀螺仪的数据都是描述沿着设备三个方向轴上的位置,对于一个竖屏摆放的设备来说,X 方向从设备的左边(负)到右边(正),Y 方向则是由设备的底部(-)到顶部(+),而 Z 方向为垂直于屏幕由设备的背面(-)到正面(+)。
DeviceMotionEvent 会在设备发生有意义的摆动(或运动)时产生,事件对象封装有产生的间距值,旋转率,和设备加速度。
如果要使用 DeviceMotionEvent,开发者可以监听 devicemotion 事件从而能够监听手机加速度的变化。该事件的事件对象提供了 4 个只读属性:
- accelerationIncludingGravity:重力加速度(包括重心引力9.8)
- acceleration:加速度(需要设备陀螺仪支持)
- rotationRate(alpha,beta,gamma):旋转速度
- interval:获取的时间间隔
其中关于 rotationRate 的 3 个属性值 alpha、beta、gamma 说明如下:
alpha 以设备坐标系 z 轴为轴的旋转速率,如下图所示:
beta 以设备坐标系 x 轴为轴的旋转速率,如下图所示:
gamma 以设备坐标系 y 轴为轴的旋转速率,如下图所示:
示例: 摇一摇更换背景颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
手机摇一摇,改变手机屏幕颜色。
<p>x 方向</p>
<p id="x"></p>
<p>y 方向</p>
<p id="y"></p>
<p>z 方向</p>
<p id="z"></p>
<script>
/**window.DeviceMotionEvent:判斷浏览器是否支持*/
if (window.DeviceMotionEvent) {
/**
* speed:速度,根据摇一摇的动作幅度可以适当增加或减小
* cx、cy、cz:分别是当前在 x,y,z 3个方向上的加速度
* lastX、lastY、lastZ:分别是上一次在 x,y,z 3个方向上的加速度
*/
var speed = 20;
var cx = 0;
var cy = 0;
var cz = 0;
var lastX = 0;
var lastY = 0;
var lastZ = 0;
/**注册devicemotion(设备运动)事件
* Window.prototype.addEventListener = function(type,listener,useCapture)
* type:事件类型,如 devicemotion、deviceorientation、compassneedscalibration 等
* listener:事件触发的回调函数,也可以提取出来单独写
* useCapture:是否捕获
* */
window.addEventListener("devicemotion", function (evenData) {
/**获取重力加速度
* x、y、z 三个属性,分别表示 3 个方向上的重力加速度
* */
var acceleration = evenData.accelerationIncludingGravity;
cx = acceleration.x.toFixed(2);
cy = acceleration.y.toFixed(2);
cz = acceleration.z.toFixed(2);
/**只要手机有稍微的抖动,就会进入此回调函数
* 当某一个方向上的加速度超过 speed 的值时,改变背景色
*/
if (
Math.abs(cx - lastX) > speed ||
Math.abs(cy - lastY) > speed ||
Math.abs(cz - lastZ) > speed
) {
// 设置随机的颜色
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
document.body.style.backgroundColor = `rgb(${r},${g},${b})`;
/** 将数据打印出来瞧一瞧*/
document.querySelector("#x").innerHTML = "cx:" + cx + "\r\n";
document.querySelector("#y").innerHTML = "cy:" + cy + "\r\n";
document.querySelector("#z").innerHTML = "cz:" + cz + "\r\n";
}
lastX = cx;
lastY = cy;
lastZ = cz;
},
true
);
} else {
alert("您的浏览器不支持摇一摇功能.");
}
</script>
</body>
</html>
五、打电话/发短信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<a href="tel:13333333333">点击给我打电话</a>
<a href="sms:10086?body=哈哈哈哈,这是一个测试!">发送短信</a>
</body>
</html>
六、其他
1、JS-SDK
微信 JS-SDK 是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信 JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
详细的文档可以参阅:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
2、HTML5+
HTML5+ 是 HTML5 中国产业联盟,是工信部下属单位,是为了更好的推进 HTML5 的商用、更好的为 HTML5 开发者服务而由产业链厂商共同组成的一个联盟。
文档地址:https://www.html5plus.org/doc/h5p.html
HTML5+ 所开发的应用严格来讲并不是 WebApp,而是应该属于 HybridApp,在 uniapp 中内置了 HTML5+ 引擎,让 js 可以直接调用丰富的原生能力。因此也可以将 HTML5+ 看作是一个运行时,在此运行时下提供了一个名为 plus 的对象,扩展了 HTML5 的能力范围。
3、JSBridge
它是原生APP 中提供了一个WebView组件,正因为有这个组件,所以原生应用也能很轻松的打开网页。
而在 WebView 中,又提供了一个 JSBridge 的组件,该组件是 JS 和 Native 之间进行双向通信的一个桥梁。