windows下nodejs中node_modules嵌套,造成路径过长File Path is Too Long

一直都知道,windows下文件路径有260字符长度限制,可以通过调用Unicode版的Windows API函数来绕过限制。但是一直没有当回事,因为几乎没有遇到过类似问题。但自从接触前端,使用nodejs开发后,却总是遇到这个问题。
今天更是窝火,项目中的依赖性,嵌套了N层node_modules文件夹。真不知道npm的开发人员是怎么想的,难道他们之前从来没有在windows下开发过吗?即便不考虑windows下的路径长度限制,单单是这种无限层次的依赖嵌套,就多么浪费空间和性能。
好在开发人员现在也意识到了这个问题,在npm3中将尽可能把依赖性放置于一级node_modules中,尽可能避免嵌套过深。不过在官网下载的node 4.2.1仍然自带npm 2.14.7,需要我们自行升级为npm 3.3.10,升级方式参考下面的链接。

Flat, flat, flat!
https://github.com/npm/npm/releases/tag/v3.0.0

Upgrading on Windows
https://github.com/npm/npm/wiki/Troubleshooting#upgrading-on-windows

Path too long! 关于Windows 最多260字符文件路径限制
https://www.mgenware.com/blog/?p=2769

How to deploy Node.js application with deep node_modules structure on Windows?
http://stackoverflow.com/questions/13318364/how-to-deploy-node-js-application-with-deep-node-modules-structure-on-windows

Error: File Path is Too Long
http://stackoverflow.com/questions/12204186/error-file-path-is-too-long

Long Paths in .NET, Part 1 of 3 [Kim Hamilton]
http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx
Long Paths in .NET, Part 2 of 3: Long Path Workarounds [Kim Hamilton]
http://blogs.msdn.com/b/bclteam/archive/2007/03/26/long-paths-in-net-part-2-of-3-long-path-workarounds-kim-hamilton.aspx
Long Paths in .NET, Part 3 of 3 Redux [Kim Hamilton]
http://blogs.msdn.com/b/bclteam/archive/2008/07/07/long-paths-in-net-part-3-of-3-redux-kim-hamilton.aspx

Naming Files, Paths, and Namespaces
https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx

Windows长路径文件删除工具
http://download.csdn.net/detail/netplaier/5073907

无法删除 NTFS 盘上的文件或文件夹
https://support.microsoft.com/zh-cn/kb/320081

使用pdf.js在线浏览pdf文件

不用转换为flash,不依赖于本地插件,纯粹基于html5,支持IE9+及其它现代浏览器。

PDF.js官网
http://mozilla.github.io/pdf.js/
Github仓储
https://github.com/mozilla/pdf.js
常见问题解答
https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
Viewer参数
https://github.com/mozilla/pdf.js/wiki/Viewer-options
API文档
http://mozilla.github.io/pdf.js/api/draft/index.html
api.js源码
https://github.com/mozilla/pdf.js/blob/master/src/display/api.js
调试pdf.js
https://github.com/mozilla/pdf.js/wiki/Debugging-PDF.js
更多学习资源
https://github.com/mozilla/pdf.js/wiki/Additional-Learning-Resources

label中包含input,绑定在label的事件触发两次

今天同事遇到这个很奇怪的问题,深入探查了一下,才发现其中奥妙。
最初怀疑是重复绑定造成的,但精简代码到最小,仍然出现。在排查了jQuery版本,css覆盖层,各种能想到的可能性后,仍一筹莫展。
静下心来慢慢梳理,通过输出事件来源,才猛然发现,原来绑定不同的元素,其事件来源是不同的。

找到了事件来源,似乎看到了蛛丝马迹,赶紧顺藤摸瓜。推测如下:
1.绑定在label。单击input后,触发input本身的click事件。单击label后,首先触发label本身的click事件,然后由于“某种原因”触发了input的click事件,进而事件冒泡至label,再次触发label的click事件。
2.绑定在input。单击input后,触发input本身的click事件。单击label后,由于“某种原因”触发了input的click事件。

将该示例在IE8-11、chrome中测试,表现相同。突然想起来,label是有一个for属性,标准的用法如下:

标准用法中,单击label,仍会触发input的click事件。

对以上两个示例进一步测试,替换input:radio为其他类型(如input:checkbox或input:text),表现相同。
由此可以得出结论,上述“某种原因”,是浏览器的特性。当单击与input相关(嵌套或for属性指定)的label时,自动触发input的click事件。

原来是个之前从未留意过的“坑”,如果不是今天遇到,还不知要潜伏多久。

移动端填坑

一个移动端页面,简单的展示和输入功能,时间又是压得很紧(其实每次都是这样-_-!)。原以为有了上次的经验,会很快搞定。但事与愿违,还是踩到了几个坑。

1.iscroll中input:text触发
iscroll中的input:text元素,不能直接触发。可通过在Tap事件中触发focus事件,模拟用户操作。
但在IOS中Safari下,非用户主动触发的focus事件,是不能调起输入法的。表现为需要点击两次,第一次获取焦点,第二次调起输入法。
根本原因在于Safari中keyboardDisplayRequiresUserAction属性的默认配置,没有什么好的解决方案。而网上的方案,大都是通过遍历页面,绕过iscroll对input元素浏览器默认事件的屏蔽,以允许用户触发focus事件。
其他还有“光标移位”、“文本框被遮盖”等,是由于transform造成,就不一一列举了。切记iscroll并不适用于所有情况,要选择合适的场景使用。

2.浏览器对input:datetime和input:datetime-local支持不足
需求中要输入日期和时间,且对于展示格式有要求。原本计划使用HTML5中的标准标签,可惜浏览器太支持太差。对于input:date的支持倒是相对较好,可以不满足输入时间的要求。并且,这些元素都不能满足对于展示格式的要求。
无奈只能使用第三方方案。找来找去发现了一家mobiscroll,效果可以用惊艳来形容。但问题是,他是收费的,只有15天的试用期。好在这家公司良心大大的,提供了一个单一功能的开源版本,用着还不错。

3.浏览器对input:file调用媒体设备的支持不一致
需求中要求直接调用摄像头拍照或选择文件上传照片。好在目前这个支持都还可以,只是有些属性不同的设备解析不同。multiple属性会造成IOS下无法调用摄像头,capture=”camera”属性会造成MIUI7下无法选择文件。最兼容的使用方式是,只设置accept=”image/*”属性。
文件上传的方式,可参考mozilla开发者中心。使用File对象访问文件信息,使用window.URL.createObjectURL方法预览图片,使用FormData对象配合XMLHttpRequest对象实现文件的异步上传。好在这些特性移动端支持的还不错,统一标准万岁!

参考链接:
Mobile Safari Autofocus text field
keyboardDisplayRequiresUserAction
HTML Media Capture
如何在web应用程序中使用文件
H5拍照应用开发经历的那些坑儿

javascript连等赋值与运算符的优先级

从运算符优先级的角度思考(“.”优先级高于“=”),会简单很多,不用这么绕。

零:声明a、b、c、d,均为undefined。
一:a、b、c、d被赋值,均指向对象Object_1,现在为{a:1}。
二:对象Object_1被声明属性x,现在为{a:1, x:undefined},a.x即为Object_1.x。
三:对象Object_1被声明属性y,现在为{a:1, x:undefined, y:undefined},b.y即为Object_1.y。
四:对象Object_1被声明属性z,现在为{a:1, x:undefined, y:undefined, z:undefined},c.z即为Object_1.z。
五:c被赋值,指向对象Object_2,现在为{}。
六:c.z即Object_1.z,被赋值,指向对象Object_2。
七:b被赋值,指向对象Object_2。
八:b.y即Object_1.y,被赋值,指向对象Object_2。
九:a被赋值,指向对象Object_2。
十:a.x即Object_1.x,被赋值,指向对象Object_2。
结:此时a、b、c、d.x、d.y、d.z均指向对象Object_2,现在为{}。d指向Object_1,现在为{a:1, x:{}, y:{}, z:{}}。

参考链接:
纠结的连等赋值
Operator_Precedence
javascript 连等赋值问题