JavaScript学习笔记整理(17):HTML5 API
这篇文章整理了HTML5 的API:
- 地理位置
- Blob
- 文件系统 API
- 客户端数据库(IndexedDB)
- 设备震动
- 亮度调节
- 设备方向检测
- 全屏操作 API
1、地理位置(Geolocation API)
if('geolocation' in navigator){
//地理位置可用
}else{
//地理位置不可用
}
1.2 获取当前定位
getCurrentPosition()函数可用来获取设备当前位置:
navigator.geolocation.getCurrentPosition(success,error,option);
参数说明:
success:成功得到位置信息时的回调函数,使用Position对象作为唯一的参数
error:获取位置信息失败时的回调函数,使用PositionError对象作为唯一的参数,可选项
options:一个可选的PositionOptions对象,可选项
注意:使用它需要得到用户的授权,浏览器会跳出一个对话框,询问用户是否许可当前页面获取他的地理位置。如果同意授权,就会调用success;如果用户拒绝授权,则会抛出一个错误,调用error。
1.2.1 授权成功
function success(position){
//成功
}
position参数是一个Position对象。其有两个属性:timestamp和coords。timestamp属性是一个时间戳,返回获得位置信息的具体时间。coords属性指向一个对象,包含了用户的位置信息,主要是以下几个值:
coords.latitude:纬度
coords.longitude:经度
coords.accuracy:精度
coords.altitude:海拔
coords.altitudeAccuracy:海拔精度(单位:米)
coords.heading:以360度表示的方向
coords.speed:每秒的速度(单位:米)
1.2.2 授权失败
function error(PositionError){
//用户拒绝授权
}
PositionError 接口表示当定位设备位置时发生错误的原因。
PositionError.code 返回无符号的、简短的错误码:
1 相当于PERMISSION_DENIED 地理位置信息的获取失败,因为该页面没有获取地理位置信息的权限。
2 相当于POSITION_UNAVAILABLE
地理位置获取失败,因为至少有一个内部位置源返回一个内部错误。
3 相当于TIMEOUT
获取地理位置超时,通过定义PositionOptions.timeout 来设置获取地理位置的超时时长。
1.2.3 options参数
用来设置定位行为
var option = {
enableHighAccuracy : true,
timeout : Infinity,
maximumAge : 0
};
参数说明:
enableHighAccuracy:如果设为true,就要求客户端提供更精确的位置信息,这会导致更长的定位时间和更大的耗电,默认设为false。
Timeout:等待客户端做出回应的最大毫秒数,默认值为Infinity(无限)。
maximumAge:客户端可以使用缓存数据的最大毫秒数。如果设为0,客户端不读取缓存;如果设为infinity,客户端只读取缓存。
1.3 监视定位
watchPosition()方法可以用来监听用户位置的持续改变。它与 getCurrentPosition() 接受相同的参数,但回调函数会被调用多次。错误回调函数与 getCurrentPosition() 中一样是可选的,也会被多次调用。
var watchID = navigator.geolocation.watchPosition(success,error, options);
一旦用户位置发生变化,就会调用回调函数success。这个回调函数的事件对象,也包含timestamp和coords属性。
watchPosition() 函数会返回一个 ID,唯一地标记该位置监视器。您可以将这个 ID 传给 clearWatch() 函数来停止监视用户位置。
navigator.geolocation.clearWatch(watchID);
1.4 完整例子
<div id="myLocation"></div> <script> var ml=document.getElementById("myLocation"); function getUserLocation(){ if("geolocation" in navigator){ var options={ enableHighAccuracy: true, maximumAge: 30000, timeout: 27000 };
navigator.geolocation.getCurrentPosition(success,error,options);
var watchID = navigator.geolocation.watchPosition(success,error, options);
}else{ ml.innerHTML="您的浏览器不支持定位!";
}
}
function success(position){ var coords=position.coords; var lat=coords.latitude; var lng=coords.longitude; ml.innerHTML="您当前所在的位置:经度"+lat+";纬度:"+lng;
//只有firefox支持address属性
if(typeof position.address !== "undefined"){ var country = position.address.country; var province = position.address.region; var city = position.address.city; ml.innerHTML +="您的地址" + country + province + city; } } function error(error){ switch(error.code){ case error.TIMEOUT: ml.innerHTML="连接超时,请重试";break; case error.PERMISSION_DENIED: ml.innerHTML="您拒绝了使用位置共享服务,查询已取消";break; case error.POSITION_UNAVAILABLE: ml.innerHTML="亲,非常抱歉,我们暂时无法为您提供位置服务";break; } ml.style.color="red"; } window.onload=function(){ getUserLocation(); } </script>
2、Blob
Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。比如通过new Blob()创建的对象就是Blob对象.又比如,在XMLHttpRequest里,如果指定responseType为blob,那么得到的返回值也是一个blob对象.
2.1 生成Blob对象
生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对已有的Blob对象使用slice()方法切出一段。
(1)Blob构造函数
var blob = new Blob(data, type)
Blob构造函数接受两个参数:
参数data是一组数据,所以必须是数组,即使只有一个字符串也必须用数组装起来.
参数type是对这一Blob对象的配置属性,目前也只有一个type也就是相关的MIME需要设置 type的值:
'text/csv,charset=UTF-8' 设置为csv格式,并设置编码为UTF-8
'text/html' 设置成html格式
注意:任何浏览器支持的类型都可以这么用
var blob = new Blob(['我是Blob'],{type: 'text/html'});
2.2 属性
blob.size //Blob大小(以字节为单位)
blob.type //Blob的MIME类型,如果是未知,则是“ ”(空字符串)
2.3 slice()
slice()返回一个新的Blob对象,包含了源Blob对象中指定范围内的数据。
blob.slice(
optional long long start,
optional long long end,
optional DOMString contentType };
参数说明:
start 可选,开始索引,可以为负数,语法类似于数组的slice方法.默认值为0.
end 可选,结束索引,可以为负数,语法类似于数组的slice方法.默认值为最后一个索引.
contentType可选 ,新的Blob对象的MIME类型,这个值将会成为新的Blob对象的type属性的值,默认为一个空字符串.
2.4 Blob的使用
使用Blob最简单的方法就是创建一个URL来指向Blob:
<a download="data.txt" id="getData">下载</a>
var data= 'Hello world!';
var blob = new Blob([data], {
type: 'text/html,charset=UTF-8'
});
window.URL = window.URL || window.webkitURL;
document.querySelector("#getData").href = URL.createObjectURL(blob);
上面的代码将Blob URL赋值给a,点击后提示下载文本文件data.txt,文件内容为“Hello World”。
2.5 URL.createObjectURL()
objectURL = URL.createObjectURL(blob);
使用URL.createObjectURL()函数可以创建一个Blob URL,参数blob是用来创建URL的File对象或者Blob对象,返回值格式是:blob://URL。
注意:在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法传入创建的URL为参数,用来释放它。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
2.6 乱码问题
当数据中包含汉字时,导出的文件可能会出现乱码,不过我们可以这样解决:
var data = "\ufeff" + "汉字";
3、文件系统API
3.1 File API
在HTML5中新增了File API,可以让网页要求用户选择本地文件,并且读取这些文件的信息。选择的方式可以是HTML<input>元素,也可以是拖拽。
<input type="file" id="photo">
var selectedFile = document.getElementById('photo');
var file = selectedFile.files[0];
//或者
file = selectedFile.files.item(0)
selectedFile.files返回一个FileList对象(有一个属性length,表示文件(File对象)个数),包含了一个或多个File对象,每个File对象都有自己的属性:
file.name:文件名,该属性只读。
file.size:文件大小,单位为字节,该属性只读。
file.type:文件的MIME类型,如果分辨不出类型,则为空字符串,该属性只读。
file.lastModified:文件的上次修改时间,格式为时间戳。
file.lastModifiedDate :文件的上次修改时间,格式为Date对象实例。
注意:如果要允许用户选取多个文件,需要加上multiple属性
<input type="file" multiple />
一般情况下,我们会为input注册change事件,当文件被选择时,触发change。
selectFile.addEventListener('change',function(){
var fileList = this.files;
for(var i = 0; i < fileList.length; i++){
var file = fileList[i]; //或者 fileList.item(0);
}
},false);
3.1.1 拖拽文件
前面也说过,我们也可以通过拖拽方式选择文件。
<div id="dropbox"></div>
dropbox = document.getElementById('dropbox');
dropbox.addEventListener('dragenter',dragenter,false);
dropbox.addEventListener('dragover',dragover,false);
dropbox.addEventListener('drop',drop,false);
在上面的代码中,ID为dropbox的div就是我们拖放目的区域。
拖放事件:
function dragenter(e){
e.stopPropagation();
e.preventDefault();
}
function dragover(e){
e.stopPropagation();
e.preventDefault();
}
function drop(e){
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
}
在上面的代码中,参数e是一个事件对象,该参数的dataTransfer.files属性就是一个FileList对象,里面包含了拖放的文件。
注意:使用拖放事件时,必须阻止dragenter和dragover事件的默认行为,才能触发drop事件。
3.1.2 FileReader API
在上面我们知道如何获取文件信息,如何使用呢?
这时我们就要用到FileReader API了,此API用于读取文件,,即把文件内容读入内存。它的参数是File对象或Blob对象。
首先,我们需要实例化FileReader对象:
var reader = new FileReader();
对于不同类型的文件,FileReader提供了不同的方法来读取文件:
readAsBinaryString(Blob|File):返回二进制字符串,该字符串每个字节包含一个0到255之间的整数。
readAsText(Blob|File, opt_encoding):返回文本字符串。默认情况下,文本编码格式是’UTF-8’,可以通过可选的格式参数,指定其他编码格式的文本。
readAsDataURL(Blob|File):返回一个基于Base64编码的data-uri对象。
readAsArrayBuffer(Blob|File):返回一个ArrayBuffer对象,即固定长度的二进制缓存数据。
我们来看一个显示用户所选图片的缩略图的例子:
<input type="file" onchange="handleFiles(this.files)"/>
function handleFiles(files){
for(var i = 0; i < files.length; i++){
var file = files[i];
var imageType = /^image\//;
if(!imageType.test(file.type)) continue;
var img = document.createElement('img');
img.file = file;
document.body.appendChild(img);
var reader = new FileReader();
reader.onload = function(e){
img.src=e.target.result;
};
reader.readAsDataURL(file);
}
}
在上面的代码中,我们通过onchange去监听input内文件信息的变化,通过file.type判断用户选择的是否是图片,这里使用File对象的readAsDataURL()方法来返回一个data URL,然后使用onload事件监听文件是否读取完毕,如果读取完毕,我们就可以事件对象e来读取文件内容,也就是e.target.result;
readAsDataURL()方法用于读取文本文件,它的第一个参数是File或Blob对象,第二个参数是前一个参数的编码方法,如果省略就默认为UTF-8编码。该方法是异步方法,一般监听onload件,用来确定文件是否加载结束,方法是判断FileReader实例的result属性是否有值。其他三种读取方法,用法与readAsDataURL方法类似。
注意:如果浏览器不支持FileReader,你也可以使用URL.createObjectURL(file)方法来创建一个data URL来显示图片缩略图。
FileReader API还有一个abort方法,用于中止文件上传。
FileReader API的其他监听事件
onabort方法:读取中断或调用reader.abort()方法时触发。
onerror方法:读取出错时触发。
onload方法:读取成功后触发。
onloadend方法:读取完成后触发,不管是否成功。触发顺序排在 onload 或 onerror 后面。
onloadstart方法:读取将要开始时触发。
onprogress方法:读取过程中周期性触发。
4、客户端数据库(IndexedDB)
IndexedDB(对象数据库)可以说是浏览器端数据库,可以被网页脚本程序创建和操作。它允许储存大量数据,提供查找接口,还能建立索引。
在IndexedDB API中,一个数据库就是一个命名对象仓库(object store)的集合,对象存储区存储的是对象。
IndexedDB特点:
- 键值对存储:在对象仓库中,数据以“键值对”的形式保存,每一个数据都有对应的键名,键名是独一无二的,不能有重复,否则会抛出一个错误。
- 同域限制:IndexedDB数据库的作用域是限制在包含它们的文档源中,每一个数据库对应创建该数据库的域名,两个同源的Web页面互相之间可以访问对方的数据,但非同源的页面就不行。
- 支持事务:IndexedDB支持事务,这就是说对数据库的查询和更新都是包含在一个事务(transaction)中,以此来确保这些操作要么是一起成功,要么是一起失败,并且永远不会让数据库出现更新到一半的情况。
- 异步:IndexedDB的操作不会阻塞浏览器的UI主线程。
- 储存空间大:IE的储存上限是250MB,Chrome和Opera是剩余空间的某个百分比,Firefox则没有上限。
(1)检测浏览器是否支持IndexedDB API
if('indexedDB' in window){
//支持
}else{
//不支持
}
(2)访问数据库
要异步访问数据库,就要调用 window 对象 indexedDB 属性的 open() 方法
var request = indexedDB.open(name[,version])
indexedDB.open方法可传输人两个参数:name是数据库名称,必填;version是数据库版本,是一个大于0的正整数(0将报错)。
open方法返回一个 IDBRequest 对象 (IDBOpenDBRequest),
注意:如果数据库存在,将打开数据库,否则,则会新建该数据库。如果省略第二个参数,则会自动创建版本为1的该数据库。
当打开数据时,有可能触发4种事件:
success:打开成功。
error:打开失败。
upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
blocked:上一次的数据库连接还未关闭。
第一次打开数据库时,会先触发upgradeneeded事件,然后触发success事件。
request.onupgradeneeded = function(e){}
request.onsuccess = function(e){
db = e.target.result;
}
回调函数接受一个事件对象event作为参数,它的target.result属性就指向打开的IndexedDB数据库。
(3)IndexedDB实例对象的方法
3.1 createObjectStore()方法
createObjectStore()方法用于创建存放数据的“对象仓库”(object store)。
db.createObjectStore(name[,options]);
参数说明:
参数name是对象仓库的名字;options是可选参数,用来设置对象仓库的属性,可配置两个属性:keyPath和autoIncrement,分别表示每条记录的键名和是否使用自动递增的整数作为键名,默认为false。
db.createObjectStore('db1', {keyPath: 'user'});
db.createObjectStore('db2', {autoIncrement: true});
由于对象仓库的名字具有唯一性(当创建已存在的数据库时,会报错),所以在创建对象仓库时,我们有必要检测对象仓库是否已存在:
db.objectStoreNames.contains(name)
objectStoreNames属性返回一个DOMStringList对象,里面包含了当前数据库所有“对象仓库”的名称。可以使用DOMStringList对象的contains方法,检查数据库是否包含某个“对象仓库”。
3.2 transaction方法
创建了数据库,当然要使用它,不过数据库的更新、读取和删除是建立在事务的基础上的,所以我们首先要创建一个事务:
var t = db.transaction(array,type)
transcation()方法接受两个参数:参数array是一个数组,包含了所要使用的对象仓库,通常是一个;参数type是一个表示操作类型的字符串,目前只有两种类型:readonly(只读)和readwrite(读写)。
t = db.transaction(['db1','readwrite');
transaction()方法返回一个事务对象,该对象的objectStore()方法用于获取指定的对象仓库:
var store = t.objectStore('db1');
事务对象有三个监听事件:
abort:事务中断。
complete:事务完成。
error:事务出错。
假如事务完成时:
t.oncomplete =function(e){}
3.2.1 数据操作
下面的方法都是在事件对象上。
(1)add()方法
add()方法用来添加数据
var add = store.add(data,key)
参数说明:参数data是所要添加的数据;参数key是这条数据对应的键名(key)。
add()方法是异步的,有success和error事件:
add.onsuccess = funciton(e){}
add.onerror = function(e){}
(2)get()方法
get()方法用来读取数据,它的参数是键名
store.get(key)
get方法也是异步的,也有success和error事件。
(3)put()方法
put()方法用来更新数据,与add()方法类似:
var update = store.put(data,key)
(4)delete()方法
delete()方法用来删除数据,它的参数是键名:
var delete = store.delete(key)
delete方法也是异步的,也有success和error事件。
(5)openCursor()方法
openCursor()方法用来遍历数据:
var cursor = store.openCursor()
openCursor方法也是异步的,也有success和error事件。
cursor.onsuccess = function(e){
var res = e.target.result;
console.log('key',res.key);
console.log('data',res.value);
res.continue()
}
e.target.result属性指向当前数据对象。当前数据对象的key和value分别返回键名和键值(即实际存入的数据)。continue方法将光标移到下一个数据对象,如果当前数据对象已经是最后一个数据了,则光标指向null。
openCursor方法还可以接受第二个参数,表示遍历方向,默认值为next,其他可能的值为prev、nextunique和prevunique。后两个值表示如果遇到重复值,会自动跳过。
3.3 createIndex()方法
createIndex()方法用来创建索引:
createIndex(index,name,options)
createIndex方法接受三个参数,第一个是索引名称,第二个是建立索引的属性名,第三个是参数对象,用来设置索引特性。unique表示索引所在的属性是否有唯一值.
3.3.1 index方法
index()方法用于从对象仓库返回指定的索引。
var index = store.index(index);
var data = index.get(name)
注意:get方法有可能取回多个数据对象,因为name属性没有唯一值。
5、设备震动(Vibration API)
Vibration接口用于在浏览器中发出命令,使得设备振动。
(1)检测是否可用
目前,只有Chrome和Firefox的Android平台最新版本支持它。
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
if (navigator.vibrate) {
// 支持
}
(2)振动
navigator.vibrate(1000);
vibrate()方法的参数就是振动持续的毫秒数,除了单个数值外,还可以接受一个数组作为参数,表示振动的模式。偶数位置的数组成员表示振动的毫秒数,奇数位置的数组成员表示等待的毫秒数。
navigator.vibrate([200,100,300])
上面代码表示,设备先振动200毫秒,然后等待100毫秒,再接着振动300毫秒。
注意:vibrate是一个非阻塞式的操作,即手机振动的同时,JavaScript代码仍然继续向下运行。要停止振动,只有将0毫秒或者一个空数组传入vibrate方法。
6、屏幕亮度(Luminosity API)
Luminosity API用来屏幕亮度调节,不过目前只有Firefox支持。
当移动设备的亮度传感器感知外部亮度发生显著变化时,会触发devicelight事件。
window.addEventListener('devicelight', function(event) {
console.log(event.value + 'lux');
});
上面代码表示,devicelight事件的回调函数,接受一个事件对象作为参数。该对象的value属性就是亮度的流明值。
7、手机设备方向
7.1 方向
Orientation API用于检测手机的摆放方向(竖放或横放)。
(1)检测浏览器是否支持
if(window.DeviceOrientationEvent){
//支持
}else{
//不支持
}
(2)监听方向变化
一旦设备的方向发生变化,会触发deviceorientation事件,可以对该事件指定回调函数。
window.addEventListener("deviceorientation", listener,false);
function listener(event){
var alpha = event.alpha;
var beta = event.beta;
var gamma = event.gamma;
}
上面代码中,event事件对象有alpha、beta和gamma三个属性,它们分别对应手机摆放的三维倾角变化。要理解它们,就要理解手机的方向模型。当手机水平摆放时,使用三个轴标示它的空间位置:x轴代表横轴、y轴代表竖轴、z轴代表垂直轴。event对象的三个属性就对应这三根轴的旋转角度。
alpha:表示围绕z轴的旋转,0~360(度)。当设备水平摆放时,顶部指向地球的北极,alpha此时为0。
beta:表示围绕x轴的旋转,-180~180(度),由前向后。当设备水平摆放时,beta此时为0。
gramma:表示围绕y轴的选择,-90~90(度),从左到右。当设备水平摆放时,gramma此时为0。
7.2 移动(motion)
(1)检测是否支持
if(window.DeviceMotionEvent){
//支持
}else{
//不支持
}
(2)和方向事件一样,移动也有监听事件:devicemotion
window.addEventListener('devicemotion',listener,true)
function listener(event){
var acceleration = event.acceleration;
var accelerationIncludingGravity = event.accelerationIncludingGravity;
var rotationRate = event.rotationRate;
var interval = event.interval;
}
上面代码中,event事件对象有acceleration、accelerationIncludingGravity、rotationRate和interval四个属性。
属性说明:
(1)acceleration、accelerationIncludingGravity
acceleration和accelerationIncludingGravity属性都包含三个轴:
- x轴:西向东(acceleration.x)
- y轴:南向北(acceleration.y)
- z轴:垂直地面(acceleration.z)
(2)rotationRate
rotationRate有三个值:
alpha: 设备沿着垂直屏幕的轴的旋转速率 (桌面设备相对于键盘)
beta: 设备沿着屏幕左至右方向的轴的旋转速率(桌面设备相对于键盘)
gamma: 设备沿着屏幕下至上方向的轴的旋转速率(桌面设备相对于键盘)
(3)interval
interval 表示的是从设备获取数据的频率,单位是毫秒。
更多:检测设备方向
简单的摇一摇功能:
var SHAKE_THRESHOLD = 3000;
var last_update = 0;
var x = y = z = last_x = last_y = last_z = 0;
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', deviceMotionHandler, false);
}
function deviceMotionHandler(eventData) {
var acceleration = eventData.accelerationIncludingGravity;
var curTime = new Date().getTime();
var diffTime = curTime - last_update;
if (diffTime > 100) {
last_update = curTime;
x = acceleration.x;
y = acceleration.y;
z = acceleration.z;
var speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD) {
//dosomething
};
last_x = x;
last_y = y;
last_z = z;
}
}
8、全屏操作(FullScreen API)
全屏API可以控制浏览器全屏显示。
8.1 requestFullscreen()
Element节点的requestFullscreen方法,可以使得这个节点全屏。
function openFullscreen(elem){
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
}
openFullscreen(document.documentElement); //整个页面全屏
openFullscreen(document.getElementById('videoElement'); //使播放器全屏
运行到这里,Gecko 与 WebKit 两个实现中出现了一个值得注意的区别:
Gecko 会为元素自动添加 CSS 使其伸展以便铺满屏幕: "width: 100%; height: 100%"。 WebKit 则不会这么做;它会让全屏的元素以原始尺寸居中到屏幕中央,其余部分变为黑色。
所以为了在 WebKit 下也达到与 Gecko 同样的全屏效果,你需要手动为元素增加 CSS 规则"width: 100%; height: 100%;":
/* html */
:-webkit-full-screen {}
:-moz-fullscreen {}
:fullscreen {}
:-webkit-full-screen video {
width: 100%;
height: 100%;
}
8.2 exitFullscreen()
Document对象的exitFullscreen方法用于取消全屏。
function closeFullscreen(){
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
closeFullscreen()
用户手动按下ESC键或F11键,也可以退出全屏键。此外,加载新的页面,或者切换tab,或者从浏览器转向其他应用(按下Alt-Tab),也会导致退出全屏状态。
8.3 全屏属性和事件
8.3.1 属性
document.fullscreenElement: 当前处于全屏状态的元素 element. document.fullscreenEnabled: 标记 fullscreen 当前是否可用.
var fullscreenElement = document.fullscreenElement || document.mozFullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
var fullscreenEnabled = document.fullscreenEnabled || document.mozFullscreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled;
8.3.2 全屏事件
fullscreenchange事件:浏览器进入或离开全屏时触发。
fullscreenerror事件:浏览器无法进入全屏时触发,可能是技术原因,也可能是用户拒绝。
document.addEventListener('fullscreenchange',function(){
if(document.fullscreenElement){
//进入全屏
}else{
//退出全屏
}
},false);