1,多媒体标签
1.1,HTML5多媒体基础
【在线多媒体的发展】
- 早在2000年,在线视频都是借助第三方工具实现的,如RealPlayer和QuickTime等,但它们存在隐私保护问题或兼容性问题。
- 2002年,为了满足使用Flash Video的开发人员需要,引入了Sorenson Spark
- 2003年,使用VP6编解码器引入了外部视频FLV格式。
- 在HTML5之前,要在网页中添加音频和视频,最简单、最直接的方法就是使用Flash。
- 在HTML5中,提供了视频音频的标准接口,通过HTML5中的相关技术,视频、动画、音频等多媒体播放再也不需要安装插件了,只需一个支持HTML5的浏览器就可以了。
【音视频编码解码器】不论是音频文件还是视频文件,实际上都只是一个容器文件,这点类似于压缩了一组文件的ZIP文件。视频文件(视频容器)包含了音频轨道、视频轨道和其他一些元数据。视频播放的时候,音频轨道和视频轨道是绑定在一起的。元数据部分包含了该视频的封面、标题、子标题、字幕等相关信息。原始的视频容器非常大,添加需编码,播放需解码。
- H.264编解码器被广泛应用,因此大多数编码软件都可以编码一个MP4视频。
- WebM是新兴的,但是工具都已经可以使用。
- Ogg是开源的,但是还没有广泛使用,只有少数几个工具可供其使用。
在HTML5之前,要在网页中添加音频和视频,最简单、最直接的方法就是使用Flash。这种方法的缺点是代码较长,最重要的是需要安装Flash插件,并非所有浏览器都拥有同样的插件。在HTML5中,不但不需要安装其他插件,而且实现还很简单。播放一个视频只需要一行代码,如:
<video src="images/movie.mp4" autoplay></video>
<audio src="images/music.mp3"></audio>
HTML5音频和视频的不足:
- 流式音频和视频:目前HTML5对视频的支持仅限于全部加载完毕再播放的方式。
- 跨资源的共享:HTML5的媒体受到HTTP跨资源共享的限制。
- 全屏控制:从安全角度讲,浏览器中的脚本控制范围不会超出浏览器之外。
- 字幕支持:如果在HTML5中对音频和视频进行编程,可能还需要对字幕进行控制,基于流行的字幕格式SRT的字幕支持规范仍在编写中尚未完全纳入规范。
- 编解码支持:缺少通用编解码的支持。
【检查浏览器是否支持HTML5音频和视频】检测浏览器是否支持audio或video最简单的方式是用脚本动态创建它,然后检测特点函数是否存在:
var hasVideo = !!(document_createElement_x_x('video').canPlayType);
另外,可以在audio元素或者video元素中放入备选内容,如果浏览器不支持该元素,这些备选内容就会显示在元素对于的位置。可以把Flash插件方式播放同样视频的代码作为备选内容。
<video src="video.egg">
<object data="videoplayer.swf" type="application/x-shockwave-flash">
<param name="movie" value="video.swf" />
</object>
</video>
上述代码中,如果浏览器支持html5视频,那么html5视频会优先显示,flash视频作为后备。
1.2,在网页中使用HTML5音频
【主流浏览器支持audio标记的情况】
【使用<audio>标签】在网页中使用HTML5中的<audio>标签嵌入音频时,只需要指定<audio>标签中的src属性值为一个音频源文件的路径即可。
<audio src="images/music.mp3" controls>
您的浏览器不支持audio元素
</audio>
control 属性供添加播放、暂停和音量控件。
1.3,在网页中使用HTML5视频
【主流浏览器支持video标记的情况】
【使用<audio>标签】可以使用video元素嵌入视频,其方法与audio元素相似,并且可以在<video>标签中添加width和height属性来控制视频的宽度和高度。
<video src="images/movie.mp4" width="600" height="400">
您的浏览器不支持video元素
</video>
1.4,使用<source>标签
由于各种浏览器对音频和视频的编解码器的支持不一样,为了能够在各种浏览器中都能正常显示音频和视频效果,可以提供多种不同格式的音频和视频文件,这就需要使用<source>标签提供多个备用多媒体文件。
- src属性用于指定媒体数据的URL地址,可以是相对路径,也可以是绝对路径地址。
- type属性用于指定媒体文件的类型,属性值为媒体文件的MIME类型,该属性值还可以通过codes参数指定编码格式。为了提高执行效率,定义详细的type属性是非常必要的。
<audio src="images/music.mp3">
<source src="images/music.ogg" type="audio/ogg">
<source src="images/music.mp3" type="audio/mpeg">
</audio>
<video src="images/movie.mp4" width="562" height="423" controls>
<source src="images/movie.ogg" type="video/ogg" codes="theora.vrobis">
<source src="images/movie.mp4" type="video/mp4">
</video>
由此可以看出,使用source元素代替了<audio>或<video>标签中的src属性,这样浏览器可以根据自身的播放能力,按照顺序自动选择最佳的源文件进行播放。
2,video与audio元素属性
2.1,标签属性
src属性和autoplay属性:
- src属性用于指定媒体数据的URL地址,可以是相对路径,也可以是绝对路径。
- autoplay属性用于指定媒体是否在页面加载后自动播放。
<video controls width="625" height="365" src="video/movie.mp4"></video>
perload属性:该属性用于指定视频或音频数据是否预加载。如果使用预加载,则浏览器会预先将视频或音频数据进行缓冲,这样可以加快播放速度,因为播放时数据已经预先缓冲完毕。该属性有三个可选值,分别是“none”、“metadata”和“auto”,其默认值为“auto”。
- none值表示不进行预加载。
- metadata表示只预加载媒体的元数据(媒体字节数、第一帧、播放列表、持续时间等)。
- auto表示预加载全部视频或音频。
注意:
- 如果标签设置autoplay属性则忽略perload属性。
- preload ="metadata"没有时间,不能设置音量,因为只加载元数据
- preload=" none "具有时间线--不知道为啥不管用
<body>
<video src="video/movie.mp4" controls="controls" width="320" height="250" preload="none"></video>
<video src="video/movie.mp4" controls="controls" width="320" height="250" preload="metadata"></video>
<video src="video/movie.mp4" controls="controls" width="320" height="250" preload="auto"></video>
</body>
poster和loop属性:
- poster(video元素独有属性) 当视频不可用时,可以使用该元素向用户展示一幅替代用的图片。当视频不可用时,最好使用poster属性,以免展示视频的区域中出现一片空白。
- loop属性 用于指定是否循环播放视频或音频。
<video id="v1" src="video/movie.mp4" controls="controls" width="320" height="250" autoplay="autoplay" poster="images/13501252652.jpg"></video>
<video id="v1" src="video/movie.mp4" controls="controls" width="320" height="250" autoplay="autoplay"></video>
controls属性、wdith属性和height属性:
- controls属性 指定是否为视频或音频添加浏览器自带的播放用的控制条。控制条中具有播放、暂停等按钮。
- width属性与height属性( video元素独有属性) 用于指定视频的宽度与高度(以像素为单位)。
<video id="v1" src="video/movie.mp4"></video>
<video id="v1" src="video/movie.mp4" controls="controls" ></video>
<video id="v1" src="video/movie.mp4" controls="controls" width="320" height="250" autoplay="autoplay" loop="loop"></video>
2.2,接口属性
error属性:在读取、使用媒体数据的过程中,在正常情况下,该属性为null,但是任何时候只要出现错误,该属性将返回一个MediaError对象,该对象的code属性返回对应的错误状态码,其可能的值包括:
- MEDIA_ERR_ABORTED(数值1):媒体数据的下载过程由于用户的操作原因而被终止。
- MEDIA_ERR_NETWORK(数值2):确认媒体资源可用,但是在下载时出现网络错误,媒体数据的下载过程被终止。
- MEDIA_ERR_DECODE(数值3):确认媒体资源可用,但是解码时发生错误。
- MEDIA_ERR_SRC_NOT_SUPPORTED(数值4):媒体资源不可用媒体格式不被支持。
注意:error属性为只读属性。
<video id="video" src="video.mp4"></video>
<script type="text/javascript">
var video = document.getElementById('video');
video.addEventListener("error",function(){
var error = video.error;
switch (error.code){
case 1:
alert('取回过程被用户中止。');
break;
case 2:
alert('当下载时发生错误。');
break;
case 3:
alert('当解码时发生错误。');
break;
case 4:
alert('媒体不可用或者不支持音频/视频。');
break;
}
},false);
</script>
networkState属性:该属性在媒体数据加载过程中读取当前网络的状态,其值包括:
- NETWORK_EMPTY(数值0):元素处于初始状态。
- NETWORK_IDLE(数值1):浏览器已选择好用什么编码格式来播放媒体,但尚未建立网络连接。
- NETWORK_LOADING(数值2):媒体数据加载中。
- NETWORK_NO_SOURCE(数值3):没有支持的编码格式,不执行加载。
注意:networkState属性为只读属性。
currentSrc属性、buffered属性:可以用currentSrc属性来读取播放中的媒体数据的URL地址,该属性为只读属性。buffered属性返回一个实现TimeRanges接口的对象,以确认浏览器是否已缓存媒体数据。
<body>
<button onclick="getFirstBuffRange()" type="button">获得首个已缓冲范围</button>
<br>
<video id="video1" controls="controls">
<source src="video/movie.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<script>
myVid = document.getElementById("video1");
function getFirstBuffRange() {
alert("Start: " + myVid.buffered.start(0) + " End: " + myVid.buffered.end(0));
}
</script>
</body>
注意: buffered属性为只读属性。
readyState属性:该属性返回媒体当前播放位置的就绪状态,其值包括:
- HAVE_NOTHING(数值0):没有获取到媒体的任何信息,当前播放位置没有可播放数据。
- HAVE_METADATA(数值1):已经获取到了足够的媒体数据,但是当前播放位置没有有效的媒体数据(也就是说,获取到的媒体数据无效,不能播放)。
- HAVE_CURRENT_DATA(数值2):当前播放位置已经有数据可以播放,但没有获取到可以让播放器前进的数据。当媒体为视频时,意思是当前帧的数据已获得,但还没有获取到下一帧的数据,或者当前帧已经是播放的最后一帧。
- HAVE_FUTURE_DATA(数值3):当前播放位置已经有数据可以播放,而且也获取到了可以让播放器前进的数据。当媒体为视频时,意思是当前帧的数据已获取,而且也获取到了下一帧的数据,当前帧是播放的最后一帧readyState属性不可能为HAVE_FUTURE_DATA。
- HAVE_ENOUGH_DATA(数值4):当前播放位置已经有数据可以播放,同时也获取到了可以让播放器前进的数据,而且浏览器确认媒体数据以某一种速度进行加载,可以保证有足够的后续数据进行播放。
<button onclick="getReadyState()" type="button">获得就绪状态</button>
<br />
<video id="video1" controls="controls">
<source src="video/movie.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<script>
myVid = document.getElementById("video1");
function getReadyState() {
alert(myVid.readyState);
}
</script>
注意: readyState属性为只读属性。
seeking属性和seekable属性:
- seeking属性返回一个布尔值,表示浏览器是否正在请求某一特定播放位置的数据,true表示浏览器正在请求数据,false表示浏览器已停止请求。
- seekable属性返回一个TimeRanges对象,该对象表示请求到的数据的时间范围。当媒体为视频时,开始时间为请求到视频数据第一帧的时间,结束时间为请求到视频数据最后一帧的时间。
<button onclick="getFirstSeekableRange()" type="button">获得首个可寻址范围</button>
<br/>
<video id="video1" controls="controls" onseeking="isSeeking()" onseeked="isSeeking()">
<source src="video/movie.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<p>试着在视频中寻址:<span id="span1"></span></p>
<script>
myVid = document.getElementById("video1");
function getFirstSeekableRange() {
alert("Start: " + myVid.seekable.start(0) + " End: " + myVid.seekable.end(0));
}
function isSeeking(){
document.getElementById("span1").innerHTML=("Seeking: " + myVid.seeking);
}
</script>
注意:这两个属性均为只读属性。
currentTime属性、startTime属性和duration属性:
- currentTime属性用于读取媒体的当前播放位置,也可以通过修改currentTime属性来修改当前播放位置。如果修改的位置上没有可用的媒体数据时,将抛出NVALID_STATE_ERR异常;如果修改的位置超出了浏览器在一次请求中可以请求的数据范围,将抛出INDEX_SIZE_ERR异常。
- startTime属性用来读取媒体播放的开始时间,通常为“0”。
- duration属性来读取媒体文件总的播放时间。
<script type="text/javascript">
function Forward() {
var el=document.getElementById("myplayer");
var time=el.currentTime;
el.currentTime=time+6;
}
</script>
</head>
<body>
<div id="movie">
<video id="myplayer" src="video/movie.mp4" width="625" height="365" controls>
</video>
</div>
<div id="btn">
<input type="button" name="button" id="button" value="快 进" class="btn1" onClick="Forward()">
</div>
played属性、paused属性和ended属性:
- played属性返回一个TimeRanges对象,从该对象中可以读取媒体文件的已播放部分的时间段。开始时间为已播放部分的开始时间,结束时间为已播放部分的结束时间。
- paused属性返回一个布尔值,表示是否暂停播放,true表示媒体暂停播放,false表示媒体正在播放。
- ended属性返回一个布尔值,表示是否播放完毕,true表示媒体播放完毕,false表示还没有播放完毕。
<button onclick="getFirstPlayedRange()" type="button">获得首段已播范围</button>
<button onclick="isVidPaused()" type="button">该视频是否已暂停</button>
<button onclick="hasVidEnded()" type="button">该视频播放是否已结束?</button>
<br />
<br />
<video id="video1" src="video/movie.mp4" width="625" height="365" controls></video>
<script>
myVid = document.getElementById("video1");
function getFirstPlayedRange() {
alert("Start: " + myVid.played.start(0) + " End: " + myVid.played.end(0));
}
function isVidPaused() {
alert(myVid.paused);
}
function hasVidEnded() {
alert(myVid.ended);
}
</script>
注意:三者均为只读属性。
defaultPlaybackRate属性和playbackRate属性:
- defaultPlaybackRate属性用来读取或修改媒体默认的播放速率。
- playbackRate属性用于读取或修改媒体当前的播放速率。
<button id="btn1" onclick="setPlaySpeed()" type="button">2X</button>
<br />
<br />
<video id="video1" src="video/movie.mp4" width="625" height="365" controls></video>
<script>
var i = 1;
myVid = document.getElementById("video1");
function setPlaySpeed() {
if(i<4){
i++;
myVid.defaultPlaybackRate= myVid.defaultPlaybackRate *2 * i;
document.getElementById("btn1").innerHTML = (i * 2 + "X");
}
myVid.load();
}
</script>
volume属性和muted属性:
- volume属性用于读取或修改媒体的播放音量,范围为“0”到“1”,“0”为静音,“1”为最大音量。
- muted属性用于读取或修改媒体的静音状态,该值为布尔值,true表示处于静音状态,false表示处于非静音状态。
<button onclick="getVolume()" type="button">音量是多少?</button>
<button onclick="setHalfVolume()" type="button">把音量设置为 0.2</button>
<button onclick="setFullVolume()" type="button">把音量设置为 1.0</button>
<br />
<br />
<video id="video1" src="video/movie.mp4" width="625" height="365" controls></video>
<script>
myVid=document.getElementById("video1");
function getVolume(){
alert(myVid.volume);
}
function setHalfVolume(){
myVid.volume=0.2;
}
function setFullVolume(){
myVid.volume=1.0;
}
</script>
2.3,video与audio元素的相关方法和事件
【相关方法】
- Load():用于加载媒体文件,通常用于播放前的预加载或用于重新加载媒体文件。
- Play():用于播放媒体文件;如果媒体文件没有加载,则加载并播放;如果是暂停状态,则变为播放,自动改变paused属性为false。
- Pause():用于暂停播放媒体文件,自动改变paused属性为true。
- canPlayType():测试浏览器是否支持指定的媒体类型。
<script type="text/javascript">
var videoEl=null;
function play() {
videoEl.play();
}
function pause() {
videoEl.pause();
}
window.onload=function() {
videoEl=document.getElementById("myplayer");
}
</script>
</head>
<body>
<div id="movie">
<video id="myplayer" src="video/movie.mp4" width="625" height="365" controls>
</video>
</div>
<div id="btn">
<input type="button" name="button" id="button" value="播 放" class="btn1" onclick="play()">
<input type="button" name="button1" id="button1" value="暂 停" class="btn2" onclick="pause()">
</div>
【相关事件】在利用video元素或audio元素读取或播放媒体数据的时候,会触发一系列的事件,如果用JavaScript脚本来捕捉这些事件,就可以对这些事件进行处理了。对于这些事件的捕捉及其处理,可以按两种方式来进行。
- addEventListener(“事件名”,处理函数,处理方式)方法来对事件的发生进行监听。
videoElement.addEventListener(type,listener,useCapture);
videoElement表示页面上的video元素或audio元素。
type为事件名称
listener表示绑定的函数
useCapture是一个布尔值,表示该事件的响应顺序,该值如果为true,则浏览器采用Capture响应方式,如果为false,浏览器采用bubbing响应方式,一般采用false,默认情况下也为false。
- 直接赋值
<video id="myplayer" src="video/movie.mp4" onplay="video_playing()"></video>
- loadstart事件:浏览器开始请求媒介;
- progress事件:浏览器正在获取媒介;
- suspend事件:浏览器非主动获取媒介数据,但没有加载完整个媒介资源;
- abort事件:浏览器在完全加载前中止获取媒介数据,但是并不是由错误引起的;
- error事件:获取媒介数据出错;
- emptied事件:媒介元素的网络状态突然变为未初始化;可能引起的原因有两个:1、载入媒体过程中突然发生一个致命错误;2、在浏览器正在选择支持的播放格式时,又调用了load方法重新载入媒体。
- stalled事件:浏览器获取媒介数据异常;
- play事件:即将开始播放,当执行了play方法时触发,或数据下载后元素被设为autoplay(自动播放)属性。
- pause事件:暂停播放,当执行了pause方法时触发。
- loadedmetadata事件:浏览器获取完媒介资源的时长和字节
- loadeddata事件:浏览器已加载当前播放位置的媒介数据;
- waiting事件:播放由于下一帧无效(例如未加载)而已停止(但浏览器确认下一帧会马上有效);
- playing事件:已经开始播放
- canplay事件:浏览器能够开始媒介播放,但估计以当前速率播放不能直接将媒介播放完(播放期间需要缓冲);
- canplaythrough事件:浏览器估计以当前速率直接播放可以直接播放完整个媒介资源(期间不需要缓冲);
- seeking事件:浏览器正在请求数据(seeking属性值为true);
- seeked事件:浏览器停止请求数据(seeking属性值为false);
- timeupdate事件:当前播放位置(currentTime属性)改变,可能是播放过程中的自然改变,也可能是被人为地改变,或由于播放不能连续而发生的跳变;
- ended事件:播放由于媒介结束而停止;
- ratechange事件:默认播放速率(defaultPlaybackRate属性)改变或播放速率(playbackRate属性)改变;
- durationchange事件:媒介时长(duration属性)改变volumechange事件:音量(volume属性)改变或静音(muted属性)。
2.4,自定义播放器
<!!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定义视频播放控制组件</title>
<link href="style/index14.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
/*定义全局视频对象*/
var videoEl=null;
/*网页加载完毕后,读取视频对象*/
window.addEventListener("load",function() {
videoEl=document.getElementById("myplayer")
});
/*播放/暂停*/
function play(e) {
if(videoEl.paused) {
videoEl.play();
document.getElementById("play").innerHTML="<img src='images/75404.png'>"
}else {
videoEl.pause();
document.getElementById("play").innerHTML="<img src='images/75403.png'>"
}
}
/*后退:后退20s*/
function prev() {
videoEl.currentTime-=20;
}
/*前进:前进20s*/
function next() {
videoEl.currentTime+=20;
}
/*慢放:小于等于1时,每次只减慢0.2的速率;大于1时,每次减1*/
function slow() {
if(videoEl.playbackRate<=1)
videoEl.playbackRate-=0.2;
else {
videoEl.playbackRate-=1;
}
document.getElementById("rate").innerHTML=fps2fps(videoEl.playbackRate);
}
/*快放:小于1时,每次只加快0.2的速率;大于1时,每次加1*/
function fast() {
if(videoEl.playbackRate<1)
videoEl.playbackRate+=0.2;
else {
videoEl.playbackRate+=1;
}
document.getElementById("rate").innerHTML=fps2fps(videoEl.playbackRate);
}
/*速率数值处理*/
function fps2fps(fps) {
if(fps<1)
return fps.toFixed(1);
else
return fps
}
/*静音*/
function muted(e) {
if(videoEl.muted) {
videoEl.muted=false;
e.innerHTML="<img src='images/75408.png'>";
document.getElementById("volume").value=videoEl.volume;
}else {
videoEl.muted=true;
e.innerHTML="<img src='images/75409.png'>";
document.getElementById("volume").value=0;
}
}
/*调整音量*/
function volume(e) {
video.volume=e.value;/*修改音量的值*/
}
function progresss() {
document.getElementById("info").innerHTML=s2time(videoEl.currentTime)+"/"+s2time(videoEl.duration);
}
/*把秒处理为时间格式*/
function s2time(s) {
var m=parseFloat(s/60).toFixed(0);
s=parseFloat(s%60).toFixed(0);
return (m<10?"0"+m:m) +":"+ (s<10?"0"+s:s);
}
window.addEventListener("load",function(){videoEl.addEvenListener("timeupdate",progresss)});
window.addEventListener("load",progresss);
</script>
</head>
<body>
<div id="main">
<div id="movie">
<video width="800" height="450" id="myplayer" src="video/movie.mp4" preload="auto" loop></video>
</div>
<div id="controls">
<div id="slow" onClick="slow()"><img src="images/75402.png" width="50" height="31" alt=""/></div>
<div id="play" onClick="play(this)"><img src="images/75403.png" width="50" height="31" alt=""/></div>
<div id="fast" onClick="fast()"><img src="images/75405.png" width="50" height="31" alt=""/></div>
<div id="prev" onClick="prev()"><img src="images/75406.png" width="50" height="31" alt=""/></div>
<div id="next" onClick="next()"><img src="images/75407.png" width="50" height="31" alt=""/></div>
<div id="muted" onClick="muted(this)"><img src="images/75408.png" width="20" height="24" alt=""/></div>
<div class="volume">
<input id="volume" type="range" min="0" max="1" step="0.1" onChange="volume(this)">
</div>
<div id="time">
<span id="rate">1</span>fps <span id="info"></span>
</div>
</div>
</div>
</body>
</html>
3,HTML5文件操作
3.1,选择单个或多个文件(File和FileList对象)
当创建“file”类型的<input>元素上传文件时,该元素在页面中不再显示为文本框效果,而是显示为一个“选择文件”的按钮,并且在按钮的右侧显示选择上传文件的名称。因为在初始化页面时没有上传文件,所以会显示为“未选择文件”字样。
- multiple:input元素设置multiple属性,可以选择多个文件,文本显示框中会显示选中了几个文件。在这个过程中,用户选中的每一个对象都是一个file对象,用户选中的这个对象的集合就是fileList对象。File对象有两个属性,name属性表示文件名,但不包含文件的路径;lastModifiedDate属性表示文件的最后修改的日期。
- accept:上传文件类型限制,accept表示可以选择的文件MIME类型,多个MIME类型用英文逗号分开;如果不限制上传图片的格式可写成:accept="image/*";
- capture:capture表示可以捕获到系统默认的设备,比如:camera--照相机;camcorder --摄像机;microphone--录音。
在HTML5页面中,一个文件对应一个File对象,在该对象中存在以下两个重要属性:
- name:表示不包含路径的文件名称。
- lastModifiedDate:表示最后修改文件的时间。
当使用file类型的<input>元素选择多个文件时,该元素中就含有多个File对象,从而形成了FileList对象,也就是File对象的列表。Filelist接口有两个重要成员:
- item方法:返回Filelist数组的第index个数组元素。
- length:数组元素的数量。
3.2,使用Blob获取文件的类型和大小
Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的 API(比如 File 对象),都是建立在 Blob 对象基础上的,继承了它的属性和方法。生成 Blob 对象有两种方法:
- Blob构造函数,接受两个参数。第一个参数是一个包含实际数据的数组,第二个参数是数据的类型,这两个参数都不是必需的。
- Blob对象的slice方法,将二进制数据按照字节分块,返回一个新的Blob对象。
Blob对象有两个只读属性:
- size:二进制数据的大小,单位为字节。
- type:二进制数据的MIME类型,全部为小写,如果类型未知,则该值为空字符串。
3.3,FileReader接口
在HTML5网页应用中,FileReader接口提供了一个异步的API,通过这个API不仅可以读取图片文件,而且还可以读取文本或二进制文件。同时,根据该接口提供的事件与方法,可以动态侦察文件读取时的详细状态。当访问不同文件时,必须重新调用FileReader接口的构造函数。因为每调用一次,FileReader接口都会返回一个新的FileReader对象,只有这样才能访问不同文件的数据。
FileReader API用于读取文件,即把文件内容读入内存。它的参数是File对象或Blob对象。对于不同类型的文件,FileReader提供不同的方法读取文件:
- readAsBinaryString(Blob|File):返回二进制字符串,该字符串每个字节包含一个0到255之间的整数。
- readAsText(Blob|File, opt_encoding):返回文本字符串。默认情况下,文本编码格式是’UTF-8’,可以通过可选的格式参数,指定其他编码格式的文本。
- readAsDataURL(Blob|File):返回一个基于Base64编码的data-uri对象。
- readAsArrayBuffer(Blob|File):返回一个ArrayBuffer对象。
在HTML5提供的FileReader接口中,包含了很多常用的事件和一套完整的事件处理机制。通过触发这些事件可以清晰地侦听FileReader对象读取文件的详细过程,以便更加精确地定位每次读取文件时的事件先后顺序,为编写事件代码提供有力的支持。FileReader对象采用异步方式读取文件,常用事件如下:
- onabort方法:读取中断或调用reader.abort()方法时触发。
- onerror方法:读取出错时触发。
- onload方法:读取成功后触发。
- onloadend方法:读取完成后触发,不管是否成功。触发顺序排在 onload 或 onerror 后面。
- onloadstart方法:读取将要开始时触发。
- onprogress方法:读取过程中周期性触发。
- onload事件的回调函数接受一个事件对象,该对象的target.result就是文件的内容。
在调用接口FileReader中的方法正常读取文件时,大部分的文件读取过程都集中在onprogress事件中,该事件耗时最长。如果文件在读取过程中出现异常或中止,那么将结束onprogress事件,直接触发onerror或onabort事件,而不会触发onload事件。另外,onload事件是文件读取成功时触发,而onloadend虽然也是文件操作成功时触发,但该事件不论文件读取是否成功,都将触发。由此可见,要想要正确获取文件数据,必须在onload事件中编写代码。
3.4,URL对象
URL对象用于生成指向File对象或Blob对象的URL:
var objecturl = window.URL.createObjectURL(blob);
上面的代码会对二进制数据生成一个URL,这个URL可以放置于任何通常可以放置URL的地方,比如img标签的src属性。需要注意的是,即使是同样的二进制数据,每调用一次URL.createObjectURL方法,就会得到一个不一样的URL。
这个URL的存在时间,等同于网页的存在时间,一旦网页刷新或卸载,这个URL就失效。除此之外,也可以手动调用URL.revokeObjectURL方法,使URL失效。
3.5,图片拖拽上传
拖放的过程中被拖放的对象被称为源对象,拖放过程中间经过的其他对象被称为过程对象,最终到达的对象称作目标对象。拖放事件可以用这三种对象来分类,不同的事件会被哪一种对象触发。
【源对象】
- dragstart:源对象开始拖放,开始移动时事件触发。
- drag:源对象拖放过程中,移动被拖拽对象时触发。
- dragend:源对象拖放结束,整个拖放操作结束时触发。
【过程对象】
- dragenter:源对象进入过程对象范围内,被拖拽对象进入过程对象时被触发。
- dragover:源对象在过程对象范围内移动,被拖拽对象在过程对象内移动时触发。
- dragleave:源对象离开过程对象的范围,被拖拽对象离开目标对象时触发。
【目标对象】
- drop:源对象拖放到目标对象中,目标对象完全接受被拖拽对象时触发,可理解为在目标对象内松手时触发。
在进行拖放操作时,DataTransfer 对象用来保存,通过拖放动作,拖动到浏览器的数据。它可以保存一项或多项数据、一种或者多种数据类型。
【dropEffect】获取/设置实际的放置效果,它应该始终设置成effectAllowed的可能值之一 。
- 对于 dragstart, drag和dragleave事件,dropEffect会被初始化为 “none”。
- 对于drop和dragend事件,dropEffect将被初始化成期望的动作,这个动作的值是最近的执行dragenter或者dragover事件后的dropEffect的值。
- 可能的值:copy: 复制到新的位置;move: 移动到新的位置.;link: 建立一个源位置到新位置的链接.;none: 禁止放置(禁止任何操作).;
【effectAllowed】 用来指定拖动时被允许的效果。你可以在dragstart事件中设置拖动源数据时期望的动作效果,可以指定的值copy,link ,move,copylink ,linkmove,all,none,uninitialized。
【files】包含一个在数据传输上所有可用的本地文件列表。如果拖动操作不涉及拖动文件,此属性是一个空列表。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#DropZone {
border: 1px solid #CCC;
height: 50px;
}
</style>
</head>
<body>
<input type="file" multiple accept="image/gif,image/png" id="file">
<div id="DropZone"></div>
<div id="imglist"></div>
<div id="Lists"></div>
<script>
var aa = document.getElementById("file");
aa.οnchange = function() {
fileDrop();
}
function fileDrop(e) {
e = e || window.event;
e.stopPropagation(); // 阻止冒泡
e.preventDefault(); //阻止默认行为
var files = e.dataTransfer.files; //FileList
var output = [];
var s = "";
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>' + f.name + '</strong>(' + f.type + ') - ' + f.size + ' bytes</li>');
var reader = new FileReader();
reader.readAsDataURL(f);
reader.onload = function(e) {
var data = e.target.result;
s += "<img src='" + data + "'/>";
document.getElementById('imglist').innerHTML = s;
};
}
document.getElementById('Lists').innerHTML = '<ul>' + output.join('') + '</ul>';
};
function dragOver(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy'; //指定拖放视觉效果
};
var d = document.getElementById('DropZone');
try {
d.addEventListener('dragover', dragOver, false);
d.addEventListener('drop', fileDrop, false)
} catch (ex) {
document.write('something must be wrong!');
}
</script>
</body>
</html>
4,移动端事件
随着触屏设备的普及,w3c为移动端web新增了touch事件。用户在移动端浏览Html5的时候,会使用手指进行一连串的操作,单击、双击、上拉、下拉等等一系列操作:
- touchstart:当在屏幕上按下手指时触发
- touchmove:当在屏幕上移动手指时触发
- touchend:当在屏幕上抬起手指时触发
- touchcancel:当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档等操作。
与移动端相关的interface主要有三个:
- TouchEvent:表示触摸状态发生改变时触发的event
- Touch:表示用户和触屏设备之间接触时单独的交互点(a single point of contact)
- TouchList:表示一组touches。当发生多点触摸的时候才用的到。
4.1,TouchEvent事件
为了区别触摸相关的状态改变,存在多种类型的触摸事件。可以通过检查触摸事件的 TouchEvent.type 属性来确定当前事件属于哪种类型。在很多情况下,触摸事件和鼠标事件会同时被触发(目的是让没有对触摸设备优化的代码仍然可以在触摸设备上正常工作)。如果你使用了触摸事件,可以调用 event.preventDefault()来阻止鼠标事件被触发。
- touchstart:当用户手指触摸到的触摸屏的时候触发。事件对象的 target 就是touch 发生位置的那个元素。
- touchmove:当用户在触摸屏上移动触点(手指)的时候,触发这个事件。一定是先要触发touchstart事件,再有可能触发 touchmove 事件。touchmove 事件的target 与最先触发的 touchstart 的 target 保持一致。touchmove事件和鼠标的mousemove事件一样都会多次重复调用,所以,事件处理时不能有太多耗时操作。不同的设备,移动同样的距离 touchmove 事件的触发频率是不同的。有一点需要注意:即使手指移出了原来的target 元素,则 touchmove 仍然会被一直触发,而且 target 仍然是原来的 target 元素。
- touchend:当用户的手指抬起的时候,会触发 touchend 事件。如何用户的手指从触屏设备的边缘移出了触屏设备,也会触发 touchend 事件。
- touchend 事件的 target 也是与 touchstart 的 target 一致,即使已经移出了元素。
- touchcancel:当触点由于某些原因被中断时触发。有几种可能的原因如下(具体的原因根据不同的设备和浏览器有所不同):由于某个事件取消了触摸:例如触摸过程被一个模态的弹出框打断。触点离开了文档窗口,而进入了浏览器的界面元素、插件或者其他外部内容区域。当用户产生的触点个数超过了设备支持的个数,从而导致 TouchList 中最早的 Touch对象被取消。
- touchcancel 事件一般用于保存现场数据。比如:正在玩游戏,如果发生了 touchcancel 事件,则应该把游戏当前状态相关的一些数据保存起来。
4.2,TouchList事件
一个TouchList代表一个触摸屏幕上所有触点的列表,举例来讲,如果一个用户用三根手指接触屏幕(或者触控板),与之相关的TouchList 对于每根手指都会生成一个 Touch对象,共计 3 个。TouchList有1个属性,2个方法:
- 只读属性:length,返回这个TouchList中Touch对的个数。(就是有几个手指接触到了屏幕)
- 方法:identifiedTouch(),返回值是在TouchList中的第 1 个 Touch 对象,已经被标记为过时,虽然有的浏览器还可以使用,但是不建议使用。
- 方法:item(index),返回TouchList中指定索引的Touch对象。
想获取 TouchList对象,TouchEvent 的三个属性可以获取到 TouchList:
(1)changedTouches:(只读),这个 TouchList对象列出了和这个触摸事件对应的那些发生了变化的 Touch 对象。
- 对于 touchstart 事件, 这个 TouchList 对象列出在此次事件中新增加的触点。
- 对于 touchmove 事件,列出和上一次事件相比较,发生了变化的触点。
- 对于 touchend 列出离开触摸平面的触点(这些触点对应已经不接触触摸平面的手指)。
(2)targetTouches:(只读),这个TouchList列出了那些 touchstart发生在这个元素,并且还没有离开 touch surface 的touch point(手指)。是touches的一个严格子集。
(3)touches:(只读),这个 TouchList 列出了事件触发时: touch suface上所有的 touch point。touches.length>=targetTouches.length。
4.3,Touch事件
Touch表示用户和触摸设备之间接触时单独的交互点(a single point of contact)。这个交互点通常是一个手指或者触摸笔,触摸设备通常是触摸屏或者触摸板。
js对象提供了多个属性来描述Touch对象。这些属性分成两大部分:基本属性(Basic properties)和触摸区域相关属性 (Touch area),Touch area 目前还在试验阶段。我们先不做过多的讨论。
基本属性,这些属性均是只读属性:
- identifier:表示每 1 个 Touch 对象的独一无二的 identifier。有了这个 identifier 可以确保你总能追踪到这个 Touch对象。
- screenX:触摸点相对于屏幕左边缘的 x 坐标。
- screenY:触摸点相对于屏幕上边缘的 y 坐标。
- clientX:触摸点相对于浏览器的 viewport左边缘的 x 坐标。不会包括左边的滚动距离。
- clientY:触摸点相对于浏览器的 viewport上边缘的 y 坐标。不会包括上边的滚动距离。
- pageX:触摸点相对于 document的左边缘的 x 坐标。 与 clientX 不同的是,他包括左边滚动的距离,如果有的话。
- pageY:触摸点相对于 document的左边缘的 y 坐标。 与 clientY 不同的是,他包括上边滚动的距离,如果有的话。
- target:总是表示 手指最开始放在触摸设备上的触发点所在位置的 element。 即使已经移出了元素甚至移出了document, 他表示的element仍然不变。