不知不觉,博客已经十年。
十年之前,初入茅庐。
十年之后,2333~
不知不觉,博客已经十年。
十年之前,初入茅庐。
十年之后,2333~
目前,PC端移动端都禁止video自动播放,除非和用户发生了页面交互动作,比如click,touchstart等事件,在事件回调中可以调用播放方法。若加了muted属性,则可以自动播放,但是静音不是我们想要的。
PC端可以使用iframe引入视频文件地址进行自动播放,但缺点是外观不可控。
H5页面暂无有效手段。
微信内置浏览器提供了WeixinJSBridge对象,若是服务器端渲染的页面,可以试试该对象初始化成功后的事件回调中播放视频:
document.addEventListener('WeixinJSBridgeReady', () => video.play(), false);
但若是基于Vue.js等前端渲染的页面,上述方法未必有用,但是经测试,发现另外一个取巧的方法:
if (typeof WeixinJSBridge !== 'undefined') {
WeixinJSBridge.invoke('getNetworkType',{},function (e){
// 利用该方法进行自动播放
video.play()
});
}
微信基本是社交传播的主阵地,能解决微信就能解决80%以上的硬需求了。
先说一个众所周知的作用域问题,看一下代码:
var a = []; for (var i = 0; i < 5; i++) { a.push(function () { console.log(i) }); } a[0](); a[1]();
以上期望输出0, 1,实际输出则是 5,5。因为i的作用域是window(global)全局。
ES6有个解决办法,把var关键字改为let关键字,即可解决作用域问题。原理可以通过babel转换一下源码探知:
var a = []; var _loop = function _loop(i) { a.push(function () { console.log(i); }); }; // 源码是let声明,此处经过了babel转换 for (var i = 0; i < 5; i++) { _loop(i); }
通过循环体封装为_loop函数,把i转为一个函数内部变量,不再受循环外变量影响。
而此时也该点题了,本文题目说的是另外一个隐藏的坑。见以下代码:
const a = []; for (let i = 0; i < 5; ) { a.push(function () { console.log(i) }); i++; // 条件改变放到循环体内 } a[0](); a[1]();
不同之处也已标明:i++的条件改变位置换到了循环体内执行,这时预期结果也不一样了。
执行预期应该是输出0, 1,实际却输出的是 1, 2。
这是为什么呢?同样通过babel转换源码后探知:
var a = []; var _loop = function _loop(_i) { a.push(function () { console.log(_i); }); _i++; // 循环体内的条件改变影响到循环体函数内的局部变量 i = _i; }; for (var i = 0; i < 5;) { _loop(i); } a[0](); a[1]();
最近也是在写一个比较复杂的业务逻辑时,发现这种写法的问题,好在花费了一些时间总算是搞清楚了。
如果循环体是即时执行是不会有问题的,如果是延迟执行的则会暴露该问题。
使用Image对象预加载图片:
const img = new Image(); img.crossOrigin = 'anonymous';
如果设置了crossOrigin,就要小心了。若在html <img/>标签内没有使用该属性,会造成两次图片请求,达不到预加载的效果。
原理是crossOrigin属性会在http请求头增加Origin头,导致两次请求是不同的(类似请求地址增加随机数去缓存效果)。
但是crossOrigin在处理canvas图片跨域报错时,是有用的。
function increaseNumbers(length, startNumber = 0) { return Array.from(new Array(length + startNumber).keys()).slice(startNumber); }
今天发现vue实现动态组件的内置标签<component>有点特殊性,当使用自闭方式使用它时(<component />)对同级的兄弟标签,在component前的可以渲染出来,在component后的则不能渲染。
例如:
<div> <p>aaaa可以渲染出来</p> <component /> <p>bbbb渲染不出来</p> </div
有人总结的很好了,不再复制粘贴,给个传送门:Vue2 几种常见开局方式
这事整的,parcel v2还没有影儿,v1却不支持使用babel.config.js,而babel v7只有使用babel.config.js才去编译node_modules里的代码,干着急没法解决哟~
常见的路由范式,拿产品product举例:
产品列表页: /product
产品详情页: /product/:id
产品编辑新增: /product/edit/:id? 有id表示编辑,无id表示新增
产品删除: /product/delete/:id
比较简单有效,无多余单词,以上供参考。
相对的根据大功能模块扩展,比如文章模块和商城模块,分别在以上范式基础上,加商定的模块前缀:/article 和 /mall
路由一般情况下应可以逐级追溯:例如 /mall/product/:id/comment
第一级:/mall 商城模块主页
第二级:/mall/product 商城产品列表
第三级: /mall/product/:id 某产品详情
第四级: /mall/product/:id/comment 该产品下的评论列表
以上可以作为设计路由时遵循的思路。
在开发maty.js时,遇到一个数组任务,数组项是内部异步执行的函数,期望是同步依次执行每项函数,每项函数执行完本身的异步任务后,继续下一项。
刚开始单纯使用map来循环执行,并且await每项函数。如下所示:
starters.map(async (fn, i)=> { console.log('++++++++++: ', i) await fn(ctx); });
结果是依次先输出了索引i,而不是阻塞每次循环,按期望执行。
搬出Google大法,在https://blog.lavrton.com/javascript-loops-how-to-handle-async-await-6252dd3c795中得到解决办法,对在 for…of 循环语法中使用await是有效的。
for (const fn of starters) { await fn(ctx); }
同时文章中指出使用Promise.all,是无法解决当前问题的,因为all方法是并行运行的。很奇怪为什么没有串行执行的原生方法。