Wednesday, March 17, 2021

WEB前端第六十五课——H5新特性:Worker线程、Files、FileReader、getUserMedia

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.data=='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=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 onError(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 = 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 onError(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="开始视频" 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="<unknown>" 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>

 









原文转载:http://www.shaoqun.com/a/632769.html

跨境电商:https://www.ikjzd.com/

周宁:https://www.ikjzd.com/w/1647

prime day:https://www.ikjzd.com/w/131.html


1.WebWorker线程  JavaScript语言是单线程模型,通过WebWorker为JS创造多线程环境;  由主线程创建Worker线程,将一些任务分配给Worker运行,两者异步执行;  Worker完成计算任务后,再将结果返回给主线程。  优点:可以分担计算密集型或高延迟的任务,确保主线程运行会更加流畅;  缺点:Worker一旦创建成功,为随时响应主线程通信,如不主动关闭结束,   
淘粉吧官网:https://www.ikjzd.com/w/1725.html
mav:https://www.ikjzd.com/w/2414
智赢:https://www.ikjzd.com/w/1511
史上最最疯狂的年终亚马逊旺季战役打响,用好广告锦囊,Q4收割一整年KPI!:https://www.ikjzd.com/home/132122
紧急注意:有这些美国客户的外贸人须警惕!最新破产、关店清单!:https://www.ikjzd.com/home/18296
亚马逊广告竞价策略:https://www.ikjzd.com/tl/107866

No comments:

Post a Comment