1.Web Worker執行緒
JavaScript語言是單執行緒模型,通過Web Worker為JS創造多執行緒環境;
由主執行緒創建Worker執行緒,將一些任務分配給Worker運行,兩者異步執行;
Worker完成計算任務后,再將結果回傳給主執行緒,
優點:可以分擔計算密集型或高延遲的任務,確保主執行緒運行會更加流暢;
缺點:Worker一旦創建成功,為隨時回應主執行緒通信,如不主動關閉結束,
會一直運行,造成資源耗費,
代碼示例:
<script>
// 呼叫Worker()建構式,創建worker執行緒,
// 由于Worker不能讀取本地檔案,因此其引數只能是腳本地址,
var myWorker=new Worker('myWorker.js');
//主執行緒創建監聽事件,接收子執行緒回傳的資訊,
myWorker.onmessage=function (event) {
console.log(event); //子執行緒回傳的資訊為物件,其中,通過data屬性可以回去回傳資料,
console.log('Receive msg:'+event.data);
if(event.data>18){
//主執行緒中使用“terminate()”方法結束Worker子執行緒
myWorker.terminate();
}
clearTimer();
}
function clearTimer() {
//向子執行緒后臺發送訊息,使用”postMessage()“方法,該方法在主執行緒和子執行緒通用,
myWorker.postMessage('Stop');
}
console.log('Hello world.'); //先于Worker執行緒執行,
</script>
// 創建Worker腳本任務
var n=0;
self.postMessage(n);
var timer=setInterval(function () {
n+=3;
//回傳資料結果
postMessage(n);
},1000);
//添加訊息事件監聽,使用“addEventListener”或“onmessage()”兩種方式都可以,
self.addEventListener('message',function (e) {
if (e.datahttps://www.cnblogs.com/husa/p/=='Stop'&&n>15){
clearInterval(timer);
postMessage('The Worker stopped!') //回傳訊息給主執行緒,
//子執行緒中使用“close()”方法關閉Worker執行緒,
self.close();
}
},false);
2.檔案操作
檔案上傳標簽:<input type='file'/>
⑴ files集合
H5中所有“file”型別的元素都具有files屬性,files為包含一組file物件的集合,
每個file物件都具有上傳檔案的所有資訊,包括:name、size、type、lastModifiedDate等,
通過偵聽“change”事件并讀取Files集合,可以獲得每個檔案物件的屬性資訊,
代碼示例:
<body>
<input type="file" id="upLoadFile" multiple/>
<div id="fileInfo"></div>
<script>
var file=document.querySelector('#upLoadFile');
var fileInfo=document.querySelector('#fileInfo');
file.onchange=function () {
console.log(this.files); //結果為物件型別資料,檔案串列,
var fileInfoArr=[];
for (var i=0;i<this.files.length;i++){
var fileData=https://www.cnblogs.com/husa/p/file.files[i];
var j=i+1;
var fileInfoTemp='<br>第'+j+'個檔案<br/>'+'名稱:'+fileData.name+'<br/>型別:'+fileData.type+
// 計算檔案大小時,可利用“Math.round()”方法進行四舍五入,
'<br>大小:'+Math.round((fileData.size/1024/1024)*100)/100+'M<br>修改時間:'+
fileData.lastModifiedDate.toGMTString()+'<br/>'; //可利用“toGMTString”或“toUTCString”方法轉換時間格式,
fileInfoArr.push(fileInfoTemp);
}
console.log(fileInfoArr);
fileInfo.innerHTML=fileInfoArr.join(''); //將陣列轉換為字串,并進行賦值,
console.log(fileInfo.innerHTML);
}
</script>
</body>
⑵ FileReader建構式,
File API提供了FileReader介面用于讀取檔案資料,
① FileReader屬性:
error,讀取檔案時發生的錯誤,
錯誤碼code:1-未找到檔案、2-安全性錯誤、3-讀取中斷、4-不可讀取、5-編碼錯誤
readyState,FileReader物件的當前狀態,狀態常量包括三個:
常量名 值 描述
EMPTY 0 還沒有加載任何資料
LOADING 1 資料正在加載中
DONE 2 已完成全部讀取任務
result,表示讀取到的檔案內容,該屬性只有在讀取操作完成后才有效,
讀取資料的格式取決于讀取操作使用的哪種方法,
② FileReader介面有4個操作方法(前兩個為核心方法):
readAsText(file或Blob,encoding),以純文本形式讀取File或Blob物件的內容,
第二個引數(可選)用于指定編碼型別,默認為“UTF-8”;
readAsDataURL(file或Blob),將檔案讀取為DataURL格式(Base64編碼);
readAsBinaryBuffer(file或Blob),將檔案讀取為二進制編碼形式;(已廢棄)
abort(),終止該讀取操作,
上述3中讀取檔案的方法,讀取結果都保存在“result”屬性中!!
③ FileReader相關事件:
onabort,讀取操作終止時呼叫;
onloadstart,讀取操作開始時呼叫;
onerror,讀取發生錯誤時呼叫;
onload,讀取操作成功完成時呼叫;
onloadend,讀取操作完成時呼叫,不論操作發生錯誤、中斷還是成功,
onprogress,讀取程序中周期性呼叫,
一般情況下,讀取檔案時,首先觸發onloadstart事件,此時readyState狀態值為1,result為空,
讀取檔案程序中,約每隔50ms觸發一次onprogress事件,通過事件物件可以獲取檔案進度資訊,
lengthComputable(是否未完成/有可計算長度)、loaded(已加載)、total(進度總長度),
讀取檔案成功完成時,觸發load事件,此時readyState狀態值為2,result為檔案內容,
如果讀取檔案程序中發生了錯誤,則觸發error事件,而不會觸發load事件,
代碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FileReader</title>
</head>
<body>
<input type="file" id="upLoadFile" multiple/>
<div id="filePreview"></div>
<script>
var file=document.querySelector('#upLoadFile');
var filePreview=document.querySelector('#filePreview');
/* //判斷瀏覽器是否支持FileReader介面
if (typeof FileReader=='undefined'){
filePreview.innerHTML ='瀏覽器不支持FileReader介面!';
// 將檔案選擇控制元件失效,
file.setAttribute('disabled','disabled');
}else {
filePreview .innerHTML ='<p>圖片預覽區域</p>';
}
//創建FileReader函式——readAsDataURL()方法
function readURL(){
// 先判斷選擇的file物件是否為圖片
var uploadFile=document.getElementById('upLoadFile').files[0];
//使用RegExp正則運算式判斷檔案型別是否為圖片,
if (!/image\/\w+/.test(uploadFile.type)){
alert ('請選擇圖片檔案!');
return false;
}
//創建FileReader物件實體,
var reader=new FileReader();
reader.readAsDataURL(uploadFile); //通過“readAsDataURL”方法讀取圖片檔案url地址
reader.onload=function () {
//將讀取到的圖片地址拼接到顯示容器,展示圖片,
filePreview.innerHTML = '<img src="'+this.result+'"/>';
}
}*/
//創建FileReader函式——readAsText()方法
function readText(){
var uploadFile=document.getElementById('upLoadFile').files[0];
if (uploadFile){
//創建FileReader物件實體,
var reader=new FileReader();
//通過“readAsText”方法讀取檔案內容,注意編碼格式引數!
reader.readAsText(uploadFile,'GB2312');
reader.onload=function () {
//將讀取到到內容顯示,
filePreview.innerHTML = this.result;
}
}
}
file.onchange=function () {
readText(); //呼叫FileReader函式
console.log(this.files); //結果為物件型別資料,檔案串列,
}
</script>
</body>
</html>
3.getUserMedia
getUserMedia()方法是H5提供的用于訪問用戶設備媒體(視頻、音頻、位置等)的API介面,
在新版Web標準中,getUserMedia()方法是window.navigator.mediaDevices下的一個方法,
語法:navigator.mediaDevices.getUserMedia(constraints);
說明:
⑴ navigator是window的一個只讀屬性,該物件包含了訪問者瀏覽器的相關資訊;
navigator物件屬性:
appCodeName,瀏覽器的代碼名
appName,瀏覽器的名稱
appVersion,瀏覽器的平臺和版本資訊
cookieEnabled,瀏覽器中是否啟用 cookie 的布林值
platform,運行瀏覽器的作業系統平臺
userAgent,瀏覽器代理資訊,由客戶機發送服務器的user-agent頭部的值
⑵ mediaDevices是Navigator的一個只讀屬性,回傳一個MediaDevices物件,
該物件可提供對相機、麥克風、螢屏共享等媒體設備的連接訪問,
并且該物件是一個單例物件,通常只需直接呼叫改物件的成員,
⑶ getUserMedia()方法提示用戶給予使用一個視頻或音頻輸入設備的許可,
該方法接受三個引數,語法:
navigator.mediaDevices.getUserMedia(constraints,onSuccess,onError);
① constraints,多媒體型別設定
該引數是一個物件,用于設定多媒體型別,即獲取哪些設備;
語法:{
video:true/false, //video引數還可以直接設定解析度
audio:true/false
}; //兩個引數中至少有一個型別被啟用!
video引數值為解析度時,語法:
video:{ width:1280,height:960},
設定video解析度時,除了“width和height”,還可以使用關鍵字“min,max,ideal”;
如果是移動設備時,video引數還可以強制使用前置或后置攝像頭,語法:
video:{facingMode:'user'}, //強制使用前置攝像頭
video:{facingMode:{exact:environment}}, //強制使用后置攝像頭
② promise說明
getUserMedia()方法是一個異步執行的方法,所以不會立即回傳最終的值,
而是回傳一個“Promise”物件,Promise物件代表了異步操作的最終完成或者失敗,
當發生情況之一時,該物件系結的相應回呼函式就會被呼叫,回傳結果也是Promise,
通常使用Promise物件的“then() 和 catch()”方法鏈式排列相關處理程式,
語法示例:
var promise = navigator.mediaDevices.getUserMedia(constraints);
promise.then(function onSuccess(mediaStream){...})
.catch(function one rror(errorObj){...});
或者簡寫為:
navigator.mediaDevices.getUserMedia(constraints).then(onSuccess,onError);
說明:
then()的引數可選,catch(errorCallback) 是 then(null,successCallback)的縮略形式;
catch()之后可以繼續接then(),進行其他鏈式操作,
③ successCallback,成功回呼函式
獲取多媒體設備成功時呼叫該回呼函式,Success回呼函式的引數是一個資料流物件,
資料流物件mediaStream的兩個內置方法“getAudioTracks() 和getVideoTracks()”,
分別回傳一個陣列,陣列成員是資料流包含的音軌audio和視軌video物件,
語法示例:
function onSuccess(mediaStream) {
var video = document.getElementById("video");
video.src = https://www.cnblogs.com/husa/p/window.URL.createObjectURL(mediaStream);
}
說明:
成功(resolve)Promise物件的回呼函式會帶一個“MediaStream”物件作為其引數;
URL.createObjectURL()方法可以將媒體流轉換為一個二進制物件的URL(Blob URL),
該URL可以作為 video元素 src 的屬性值,
④ errorCallback,失敗回呼函式
獲取多媒體設備失敗時呼叫該回呼函式,Error回呼函式接受一個error物件作為引數,
Error物件有三個屬性值,
PERMISSION_DENIED:用戶拒絕提供資訊,
NOT_SUPPORTED_ERROR:瀏覽器不支持硬體設備,
MANDATORY_UNSATISFIED_ERROR:未發現指定的硬體設備,
語法示例:
function one rror(error) {
console.log("錯誤名稱: "+ error.name+"<br/>錯誤資訊:"+error.message);
}
⑷ 視頻拍照
獲取視頻后通過 Canvas API提供的 “ctx.drawImage(video,0,0)”方法實作拍照功能,該方法
可以將視頻的一幀轉換為canvas元素,進行截圖拍照,
語法示例:
var ctx=canvas.getContext('2d'); //創建2d畫筆
ctx.drawImage(video,0,0); //在畫布上繪制影像
⑸ 視頻、截圖示例代碼:
<body>
<video src="" width="360" height="300" id="videoCase"></video>
<input type="button" value="https://www.cnblogs.com/husa/p/開始視頻" onclick="startVideo()"/>
<canvas width="360" height="300" id="canvas"></canvas>
<button id="btn" onclick="takePhoto()">拍照</button>
<script>
function startVideo() {
// 獲取視頻區域元素
var video=document.getElementById('videoCase');
// 設定媒體設備啟動型別
var constraints={
video:{width:360,height:300}, //啟動攝像頭,引數可以直接寫“true”
audio:true //啟動麥克風
}
// 使用”getUserMedia()“方法啟動媒體設備,設備啟動型別”constraints“作為引數,
// 該方法的回傳值為"Promise"物件,Promise物件回傳成功后,它的回呼函式會帶一個“MediaStream”作為引數,
// then()方式是Promise的一個“異步執行”方法,then()前面所有方法執行完成后再執行其內部的程式,避免資料獲取失敗或缺失!
var promise=navigator.mediaDevices.getUserMedia(constraints);
promise.then(function onSuccess (MediaStream) {
console.log(MediaStream); //回傳值:MediaStream {id: "5eDj...jdna", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
console.log(typeof MediaStream); //回傳值:object
video.srcObject=MediaStream;
console.log(video); //回傳值:<video src="https://www.cnblogs.com/husa/p/" width="360" height="300" id="videoCase"></video>
console.log(typeof video); //回傳值:object
video.play(); //或video.autoplay=true;
}).catch(function errorCallback(error) {
console.log(error.name+':'+error.message); //回傳值:NotAllowedError:Permission denied
console.log(error); //回傳值:DOMException: Permission denied
console.log(typeof error); //回傳值:object
})
}
function takePhoto() {
var video=document.getElementById('videoCase');
var canvas=document.getElementById('canvas');
var paintBrush=canvas.getContext('2d');
paintBrush.drawImage(video,0,0,360,300);
}
</script>
</body>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/270863.html
標籤:JavaScript
