年纪大了,不写项目总结总有一天会忘记的。
这次的项目似乎不能暴露是谁做的,暂时称作某项目吧。
某项目从2月初开始,因为其大型活动是在3月底四月初开始,所以原本计划是3月初上线,结果因为客户经常不睬我们,项目最后是3月中旬上线的。
这次项目因为客户不肯给钱所以PM说不用做的太细。
不过因为本人入了某教所以对此项目一腔热血,2月底就几乎把前端功能都做好了。
去掉后端功能,简单来说就是给图像加装饰。
后端是Rails,并且估算了下工时足够我玩,所以尝鲜用了 react-rails 。
项目中一共两个页面,一个DIY图片的页面,一个Twitter头像更新成功后的反馈页面。
第一个页因为要给图片加装饰,便用了 fabric.js ,一个很强大的canvas plugin,适合DIY画布。
第二个页面没啥东西,就是展示修改好的图片而已。
- react-rails第一次用,完全不知道会有多少坑。实际用下来感觉还是挺不错。
缺点是必须按照文档的结构来写,不知道怎么用 redux 和 flux。
Component Class 全部暴露在 Global 环境中,尝试过闭包 + import/export,无果。
看了下 issue 里也有好多人提出这个问题。不过为了少折腾,所以这次没深究。
可以将 react 模版 写在 html 里,还是挺新颖的。
好像也可以写在 controller 里,没试过,不过不推荐。
也许这就是传说中的 server rendering 。// slim = react_component "Generator", props={authToken: "#{form_authenticity_token}"}, html_options={class: "body-container"}
这次 component 里有个 form ,所以把 token 作为 props 传给了js。
找了很多,这似乎是比较正规的解决方式。
另外,因为没有用 flux , component 之间的数据传输有点麻烦。 - CORS单独领出来写,原因是被坑了好长时间。
给 twitter 头像加装饰后把新头像传给 twitter 需要把 canvas 转成 base64 URI。
因为 twitter 头像是来自其它域名的图片,所以画在 canvas 上时会出现 CORS 问题。
twitter API 请求次数有上限, local 开发的时候用的是本地图片替代了 twitter profile image 。开发的时候也就没有注意到 cross-origin 的问题。
到测试的时候这个问题浮现了出来,写了好几个解决方式,后来用了:// slim = image_tag src, crossorigin: "Anonymous"
这便给上线后埋下了祸根。
很多文档上大多提到了只要设置 img 的 crossOrigin 属性就能解决 CORS 问题。
但是上线后在一部分人的浏览器里出现了问题。如果是第一次访问这个页面不会有问题,但是如果在有缓存的情况下,还是会报 crossOrigin 的错误。
后来在某个 stackflow 的帖子里找到说,crossorign 必须在图片加载完成前付给图片才有效。我只能猜测在某些情况下,因为从缓存读图片比浏览器解析DOM attribute 还快,所以导致了 crossorigin 没有生效。
最后老实的用了 new Image() 的方法来 preload 这张唯一的跨域图片。// slim div.preload#preload_remote data-key="origin" data-group="origin" data-url=@img_url
// javascript _createAvatarImg() { let avatarData = document.getElementById('preload_remote'), avatar = new Image(); avatar.crossOrigin = "Anonymous"; avatar.dataset.group = avatarData.dataset.group; avatar.dataset.key = avatarData.dataset.key; avatar.src = avatarData.dataset.url; return avatar; }
另外要说下,这个 bug 我在任何浏览器任何网络任何设备上都没发再现,公司测试也是,后端开发A也是。后端开发B和PM和运维却碰到了。根据 twitter 反馈,确实有一部分人会出现这个图片 Cache 导致的问题。PM是safari下,运维是在Android Chrome下,后端开发B是Mac下任何浏览器。
所以,至今我都不知道如何再现这个 bug 。
当然,其实 fabric.js 支持 CORS DrawImage ,但是这次我没有用。
因为 fabric.js 加载成功后是直接画在画布上的,没有 fadeIn 的效果。
本来对于 react 和 fabric 不是很了解,这次就没有在 Canvas 效果上多写什么。 - Node.ChildNodes一如既往没有用 jQuery 和 lodash ,而是 Vanilla JS 。
第一次用 Node.ChildNodes ,一开始以为和 jQuery 的 children() 一样。
上线后 CORS 问题迟迟解决不了后,才偶然发现原来自己想的太简单了。
TextNode 也是 node !
TextNode 也是 node !
TextNode 也是 node !
重要的事情说三遍。
没错,我其实还取到了很多 <code>/\s*\n/</code> 。
我还在那里天真的 forEach ,天真的取他们的 dataset,天真的给它们绑定 onload 。
重新把 ChildNodes 过滤了一遍。这才取到了正确的 ElementNodelet childNodes = document.getElementById('preload_local').childNodes, avatar = this._createAvatarImg(), imgArray = [avatar]; // remove text / comment node Array.prototype.forEach.call(childNodes, (node) => { if (node.nodeType === 1) imgArray.push(node); });
不过现在想如果想避免取到 TextNode 的话其实可以用 querySelectorAll 。
基本就是以上这些。
总结下来自己对 js / react / promise / canvas 都不是很了解。前端路还长着呢。