V屏幕共享电脑版是一款投屏软件,使用这款工具只需要通过局域网(互联网亦可),就能让电脑显示器显示其他设备的画面,比如另一台电脑或者自己的收集,可以用于办公远程操作,和手机PPT投屏。
来源:http://www.3h3.com/soft/180376.html
EV屏幕共享是一唯科技推出的电脑屏幕共享投屏软件,在同一局域网内,可以让电脑和手机共享同一屏幕,不仅可以给您带来优秀的一站式屏幕交互解决方案,更有着同类软件不可比拟的极简式操作体验!
通过软件只要连接相同的网即可即可支持屏幕共享,支持局域网搜索和手动输入两种方式,任意选择,手机和电脑共享,任意切换摄像头的画面,可以满足用户的视频画质需求,操作简单,支持多人快速打开屏幕共享,没有任何的广告,所有的功能全都可以免费使用。
【快速连接,屏幕共享】
局域网搜索、手动输入,两种方式随意选择。
【超低延迟,屏幕共享】
局域网内超低延迟,手机和电脑屏幕共享。
【前置后置,随意切换】
手机投屏过程中,可以随时切换摄像头的画面。
一、高清大屏,极致体验
现在 你可以直接在电脑屏幕中查看手机里的图片、视频了。
只需将手机连接至同局域网内的电脑,即可轻松投屏手机中的多媒体画面,横屏竖屏随时切换,开启大屏视觉体验!
二、会议演示,不再繁琐
有了EV屏幕共享,你可以更加从容地准备你的会议了。
多人局域网内实时共享屏幕,最多可同步共享4台移动设备/电脑。手机麦克风清晰收音至电脑端,无论是演示文稿,还是工作汇报、小组沟通,用它一定错不了。
三、文档影音,即时传输
QQ、微信传文件早已过时,现在,EV屏幕共享为你开启极速传输。
投屏过程中,可将文档、图片、音乐等多媒体文件,实时一键批量传输至其他共享设备。近乎0压缩的传输技术,绝对捍卫你的图片/视频画质。
1、修复部分已知bug;
2、优化用户体验。
拷贝和深拷贝都是对于 JS 中的引用类型而言的,浅拷贝就只是复制对象的引用,如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。
说到深浅拷贝,必须先提到的是JavaScript的数据类型,之前的一篇文章JavaScript基础心法——数据类型说的很清楚了,这里就不多说了。
需要知道的就是一点:JavaScript的数据类型分为基本数据类型和引用数据类型。
对于基本数据类型的拷贝,并没有深浅拷贝的区别,我们所说的深浅拷贝都是对于引用数据类型而言的。
浅拷贝的意思就是只复制引用,而未复制真正的值。
const originArray=[1,2,3,4,5];const originObj={a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};const cloneArray=originArray;const cloneObj=originObj;console.log(cloneArray); // [1,2,3,4,5]console.log(originObj); // {a:'a',b:'b',c:Array[3],d:{dd:'dd'}}cloneArray.push(6);cloneObj.a={aa:'aa'};console.log(cloneArray); // [1,2,3,4,5,6]console.log(originArray); // [1,2,3,4,5,6]console.log(cloneObj); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}console.log(originArray); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}
上面的代码是最简单的利用=赋值操作符实现了一个浅拷贝,可以很清楚的看到,随着 cloneArray 和 cloneObj 改变,originArray和 originObj 也随着发生了变化。
深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
只要进行了深拷贝,它们老死不相往来,谁也不会影响谁。
目前实现深拷贝的方法不多,主要是两种:
先看看这两个方法吧:
The JSON.stringify() method converts a JavaScript value to a JSON string.
JSON.stringify 是将一个 JavaScript 值转成一个 JSON 字符串。
The JSON.parse() method parses a JSON string, constructing the JavaScript value or object described by the string.
JSON.parse 是将一个 JSON 字符串转成一个 JavaScript 值或对象。
很好理解吧,就是 JavaScript 值和 JSON 字符串的相互转换。
它能实现深拷贝呢?我们来试试。
const originArray=[1,2,3,4,5];const cloneArray=JSON.parse(JSON.stringify(originArray));console.log(cloneArray===originArray); // falseconst originObj={a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};const cloneObj=JSON.parse(JSON.stringify(originObj));console.log(cloneObj===originObj); // falsecloneObj.a='aa';cloneObj.c=[1,1,1];cloneObj.d.dd='doubled';console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}};console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
确实是深拷贝,也很方便。但是,这个方法只能适用于一些简单的情况。比如下面这样的一个对象就不适用:
const originObj={ name:'axuebin', sayHello:function(){ console.log('Hello World'); }}console.log(originObj); // {name: "axuebin", sayHello: ?}const cloneObj=JSON.parse(JSON.stringify(originObj));console.log(cloneObj); // {name: "axuebin"}
发现在 cloneObj 中,有属性丢失了。。。那是为什么呢?
在 MDN 上找到了原因:
If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array). JSON.stringify can also just return undefined when passing in "pure" values like JSON.stringify(function(){}) or JSON.stringify(undefined).
undefined、function、symbol 会在转换过程中被忽略。。。
明白了吧,就是说如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝。
递归的思想就很简单了,就是对每一层的数据都实现一次 创建对象->对象赋值 的操作,简单粗暴上代码:
function deepClone(source){ const targetObj=source.constructor===Array ? [] : {}; // 判断复制的目标是数组还是对象 for(let keys in source){ // 遍历目标 if(source.hasOwnProperty(keys)){ if(source[keys] && typeof source[keys]==='object'){ // 如果值是对象,就递归一下 targetObj[keys]=source[keys].constructor===Array ? [] : {}; targetObj[keys]=deepClone(source[keys]); }else{ // 如果不是,就直接赋值 targetObj[keys]=source[keys]; } } } return targetObj;}
我们来试试:
const originObj={a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};const cloneObj=deepClone(originObj);console.log(cloneObj===originObj); // falsecloneObj.a='aa';cloneObj.c=[1,1,1];cloneObj.d.dd='doubled';console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}};console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
可以。那再试试带有函数的:
const originObj={ name:'axuebin', sayHello:function(){ console.log('Hello World'); }}console.log(originObj); // {name: "axuebin", sayHello: ?}const cloneObj=deepClone(originObj);console.log(cloneObj); // {name: "axuebin", sayHello: ?}
也可以。搞定。
是不是以为这样就完了??当然不是。
我们知道在 JavaScript 中,数组有两个方法 concat 和 slice 是可以实现对原数组的拷贝的,这两个方法都不会修改原数组,而是返回一个修改后的新数组。
同时,ES6 中 引入了 Object.assgn 方法和 ... 展开运算符也能实现对对象的拷贝。
那它们是浅拷贝还是深拷贝呢?
The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
该方法可以连接两个或者更多的数组,但是它不会修改已存在的数组,而是返回一个新数组。
看着这意思,很像是深拷贝啊,我们来试试:
const originArray=[1,2,3,4,5];const cloneArray=originArray.concat();console.log(cloneArray===originArray); // falsecloneArray.push(6); // [1,2,3,4,5,6]console.log(originArray); [1,2,3,4,5];
看上去是深拷贝的。
我们来考虑一个问题,如果这个对象是多层的,会怎样。
const originArray=[1,[1,2,3],{a:1}];const cloneArray=originArray.concat();console.log(cloneArray===originArray); // falsecloneArray[1].push(4);cloneArray[2].a=2; console.log(originArray); // [1,[1,2,3,4],{a:2}]
originArray 中含有数组 [1,2,3] 和对象 {a:1},如果我们直接修改数组和对象,不会影响 originArray,但是我们修改数组 [1,2,3] 或对象 {a:1} 时,发现 originArray 也发生了变化。
结论:concat 只是对数组的第一层进行深拷贝。
The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included). The original array will not be modified.
解释中都直接写道是 a shallow copy 了 ~
但是,并不是!
const originArray=[1,2,3,4,5];const cloneArray=originArray.slice();console.log(cloneArray===originArray); // falsecloneArray.push(6); // [1,2,3,4,5,6]console.log(originArray); [1,2,3,4,5];
同样地,我们试试多层的数组。
const originArray=[1,[1,2,3],{a:1}];const cloneArray=originArray.slice();console.log(cloneArray===originArray); // falsecloneArray[1].push(4);cloneArray[2].a=2; console.log(originArray); // [1,[1,2,3,4],{a:2}]
果然,结果和 concat 是一样的。
结论:slice 只是对数组的第一层进行深拷贝。
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
复制复制复制。
那到底是浅拷贝还是深拷贝呢?
自己试试吧。。
结论:Object.assign() 拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。
const originArray=[1,2,3,4,5,[6,7,8]];const originObj={a:1,b:{bb:1}};const cloneArray=[...originArray];cloneArray[0]=0;cloneArray[5].push(9);console.log(originArray); // [1,2,3,4,5,[6,7,8,9]]const cloneObj={...originObj};cloneObj.a=2;cloneObj.b.bb=2;console.log(originObj); // {a:1,b:{bb:2}}
结论:... 实现的是对象第一层的深拷贝。后面的只是拷贝的引用值。
我们知道了,会有一种情况,就是对目标对象的第一层进行深拷贝,然后后面的是浅拷贝,可以称作“首层浅拷贝”。
我们可以自己实现一个这样的函数:
function shallowClone(source) { const targetObj=source.constructor===Array ? [] : {}; // 判断复制的目标是数组还是对象 for (let keys in source) { // 遍历目标 if (source.hasOwnProperty(keys)) { targetObj[keys]=source[keys]; } } return targetObj;}
我们来测试一下:
const originObj={a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};const cloneObj=shallowClone(originObj);console.log(cloneObj===originObj); // falsecloneObj.a='aa';cloneObj.c=[1,1,1];cloneObj.d.dd='surprise';
经过上面的修改,cloneObj 不用说,肯定是 {a:'aa',b:'b',c:[1,1,1],d:{dd:'surprise'}} 了,那 originObj 呢?刚刚我们验证了 cloneObj===originObj 是 false,说明这两个对象引用地址不同啊,那应该就是修改了 cloneObj 并不影响 originObj。
console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'surprise'}}console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'surprise'}}
What happend?
originObj 中关于 a、c都没被影响,但是 d 中的一个对象被修改了。。。说好的深拷贝呢?不是引用地址都不一样了吗?
原来是这样:
→ 送全套程序员必读资料!
→ 精选技术资料共享!
→ 高手如云交流社群!
介绍,Chrome浏览器中进行的关于网络共享API的实验,预计在2017年4月份才能落幕,进展情况信息更新较快,详情可访问developers.google.com。
Chrome 55版本的发行,为Android系统采用Web共享API提供了可能性,这篇文章主要介绍,如何用Web共享API来丰富当前的分享聚道。
? 要求一
2017年4月份之前,Web共享API都只处于探索时期,因此需要先注册,1天之后会收到一份相关电子邮件。
下一步必须在网站上做好标记:
?要求二
?网站需要通过HTTPS服务
?使用navigator.share(),由用户操作(点击)
?所有属性值必须是字符串
现在可以试着用Web共享API, 如图:
首先,了解一下静态twitter分享链接:
用这种方式,使用不支持API的浏览器,会获得一个链接(看起来似乎像一个按钮),可以在twitter上直接分享网站。
接下来,在网站下方添加一个脚本,使用API来分享链接:
逐一检查代码:添加功能,测试是否支持navigator.share,若支持,直接更改分享链接的文本,从“推特共享”到“分享”显示各种分享聚道。
接下来,给分享链接添加一个EventListener指引,即:navigator.share,用于点击分享,可在此定义标题和网址的属性,也可添加一个文本属性,链接规范的话可直接使用,否则用当前网址。
最后,添加:ev.preventDefault();防止链接自动默认分享。
现在,使用浏览器支持共享API,可以轻松共享所有服务网站了,通过安装服务器或者APP,直接分享twitter链接或复制网址,分享个链接,你也可以在Github中直接找到代码:https://justmarkup.com/web-share-api/using-the-web-share-api.html
注意:为了解决浏览器不支持Web共享API的问题,以便用户更好地参与分享,可使用https://jonsuh.com/blog/social-share-links/,在弹出窗口中加载共享内容。
总结:
Web 共享API功能的实现至少要到2017年4月,我个人比较喜欢文中提到的方法,也是一次很不错的尝试,许多网站已经在使用浏览器实现各种特性,增强用户体验,有兴趣的朋友也可以亲自试试哦。
分享快乐!
智能社撰稿,更多知识请关注微信号zhi_neng_she
*请认真填写需求信息,我们会在24小时内与您取得联系。