晚上直播写代码啦!如果有人看的话,大概10点半到11点半。
以 Web 相关技术为主,写的多半是各种 side project。
地址:http://www.douyutv.com/meathill
欢迎光临,可以点播。
晚上直播写代码啦!如果有人看的话,大概10点半到11点半。
以 Web 相关技术为主,写的多半是各种 side project。
地址:http://www.douyutv.com/meathill
欢迎光临,可以点播。

图文终于相关一回
晒出住院照之后,各路亲朋好友基本都送来早日康复的祝福,这里一并感谢。不过有几位似乎很关注 Surface 的使用情况。经过这几天密集使用,尤其是在医院病房这种本身不是为办公设计的环境中使用(之前即使用多半也是在办公室里),我自觉积累了一些经验,在此分享给大家。
整体环境请看照片。基本上,就是一张床,一个床头柜,一把椅子。床头柜有可以拉出来的小餐桌,旁边有足够多的插座。Surface 可以放在床头柜上,高低比较合适;小餐桌拉出来放键盘轨迹球;手机可以卡在键盘后面。病房里空间还算富裕,所以我可以放心霸占自己这条过道。
我觉得底座还是很有必要的。首先 Surface 为了放便携带重量较轻,很容易移动,或者说,被线扯动。有了底座之后,稳定很多。其次,像我随身携带好多设备,充电也是个大问题,底座自带5个USB,基本可以不需要别的插头了。
而且我还要使用键盘鼠标,Surface 本身只有一个USB,即使扩展也很难满足。想象一下,没有底座的 Surface,为了连上这些设备,拖一个巨大的 USB Hub,还能稳定使用么?
有了底座,还可以更好的规制其它线缆,比如耳机。
键盘盖是个好东西,不过可能只在咖啡厅好用,这个时候我还是喜欢分离的键鼠。首先,机械键盘的手感自不消说。其次,带着键盘盖实际上对平面的要求更高,反而不如分解后适应性强。这点普通笔记本也一样。最后,键盘盖上的触摸板使用面积太小,实在不方便。
最后说到应用优化。由于大部分 Windows 设备都是标准分辨率,跟苹果刚好相反,所以绝大多数 Windows 应用都没有针对高分屏做过优化,导致的结果就是可视面积可操作面积很小,虽然Surface是触屏,但真正能用指头点的机会并不多——Windows平板应用也太少太差。笔就更不用提了,手臂悬空点来点去想想就累。所以鼠标仍然是最重要的操作媒介。而狭小空间里,轨迹球就是最佳选择,操作精准,反应迅速。
应用软件仍然是 Windows 系统下最大的优势,虽然 iOS 和 Android 也有一些类似产品,但使用体验实在不可同日而语,比如完全不支持快捷键,输入定位很糟糕,大量功能缺失等等。这也没办法,面对纯触摸设备设计的产品,它们的交互要求必然是简单直接,传统桌面软件借助键盘鼠标实现精准操作的体验很难达到。
新的交互方式出现之前,平板类产品只能作为消费产品,很难成为生产工具。
Surface 是个很棒的产品,便携性一流,配置完善,散热也很好。Windows 10也不错,新版界面和触摸屏相得映彰。只是其它应用要么未经优化,要么压根就没有,整体使用体验并不好,无法离开键盘鼠标,自然对环境的要求也比较高。不过软件本身的性能效果都很棒,远非平板类能及。
语出我妈。
小时候我经常被我妈用这句教训。长大了之后教训少了,于是便作了起来。来到广州之后,一来天热,二来也没人管束,一时间忘乎所以,把饮料当水喝,终于喝出糖尿病。
于是这辈子第一次住院,而且一住就是半个月。感谢我司领导允许我在医院半工半休,感谢家人的支持。
奉劝各位不要不信邪,大家都是普通人,有问题赶紧看,平时要自律。
我好饿。
PS:好的方面是许了3年的105KG即将达成……

(自古图文不相关)
同事问为什么要用 array_map,array_filter之类的函数,用 foreach 不就好了?
答:这样写出来的代码语义更清晰,阅读更容易。
那么如何使用其它变量呢?global 么?
答:global 肯定不合适,不过怎么写我也不知道。待我查查。
在PHP中,不能像JS那样直接使用闭包里的其它变量,必须通过声明继承的语法,写出来是这样的:
<?php
$arr = [1, 2, 3];
$split = 2; // 分界
$arr = array_map(function ($value) use ($split) {
return $value < $split ? 0 : $value;
}, $arr);
var_dump($arr);
// 输出
// 0, 2, 3
重点是那个 use ($split)。
参考:

使用 npm 可以直接调用 package.json 里面 scripts 标签里定义的脚本。比如,Astinus 项目中,index.js 是入口JS,并且需要 ES6 支持,就可以这样:
// package.json
{
"scripts": {
“start": "node index --harmony"
}
}
然后直接运行
npm start
即可。
那么怎么终止进程呢?
首先要在 index.js 里增加一句
process.title = 'astinus';
声明该应用的标题是“astinus”,然后增加脚本:
{
"scripts": {
"start": "node index --harmony",
"stop": "killall SIGINT astinus"
}
}
之后就可以
npm stop
参考:

问题不大,不过很诡异。代码如下:
SASS:
.some-class
display: none
.other-class:blank
display: none
HTML:
<div class="some-class">...</div>
理论上说,这样这个div应该不显示。在本项目中,它的确没显示;但是在另外一个将本项目作为依赖的项目中,它却显示出来了。
经检查,本地开发和部署时,直接使用 compass compile 生成CSS,compass 配置中,设置输出模式(output_style)为 compressed,结果是这样的:
.some-class{display:none}.other-class:blank{display:none}
而在作为依赖时,用到的则是 grunt-contrib-cssmin 处理过的CSS,刚才那句就被压缩成
.some-class,.other-class:blank{display:none}
:blank伪类尚未被Chrome中支持,于是整条规则都被忽略,导致div显示出来。

时势造英雄。
IT科技几十年来诞生过不少概念,但直接拿来就能作为宣传材料的不多,HTML5算一个。借助智能手机、微信微博快速普及带来的平台优势,HTML5快速成长,接连攻陷投资界、创业界、广告界,现在说起H5,在我的圈子里几乎无人不知无人不晓。
资金充裕,整个行业自然地位上升,财务上升;继而自然从业者增加;继而就会出产大量的产品。而作为前端从业人员,最大的感觉就是:轮子真TM多啊……这不,我前几天计划学习一下近来出现的各种新技术,今天正好看到Bable最新入门The Complete Guide to ES6 with Babel 6,正好我写xgame-api的时候饱受node不能完全支持ES6之苦,马上坐正准备好好看。
然后就看到:
Keeping up to date
Here’s a little story: while writing these guides, I learned that the require hook in babel-core used by Gulp and Mocha is already set to be deprecated.
跟上变化
讲个段子:就在我写这套入门的时候,babel-core里的
require钩子,就是Gulp和Mocha使用的那个,被标记为“弃用”
Babel6是24天之前发布的,这套文章是上周写的,核心API已经发生变化了。这让我不禁去想,紧跟业界潮流的成本会不会太高了?ES6的确提供了不少语法糖,以及终于像样的模块管理。如果现在就开始使用ES6,不仅可以提前享受到这一切,到标准真正到来的时候,可以省去升级的时间。
不过这里面之考虑了标准变化,没有考虑需求变化和产品变化。如果是抽象性很强的代码,比如某种算法库,或者某个功能组件,那么从开发之日起,遇到的变化可能不会太多太大。但如果是业务代码,就不得不遭遇各种各样的修改和变化,于是功能稳定便于维护就更加重要。紧跟潮流,意味着必须付出多余的精力去应对各种不稳定导致的节外生枝,一不小心,业务逻辑就要延期交付鸟。
又有个切身例子。Tiger Prawn(后面简称TP)立项的时候,模块管理无论是AMD还是CMD还是sea.js都难以让人满意,所以我就用了最简单的直接引用和命名空间。前几日用Browserify感觉不错,赶上TP遇到个问题,就寻思着重构下。结果努力一天之后,架构变化还是太复杂,遂放弃。次日修正实际问题只花了半天。生产中,还是优秀的架构设计更重要,毕竟开发和维护效率至上;追新追潮流几乎都可以算是作死的行为。
那么什么时候学习新技术呢?程序员都应该做业余项目,不是私活,而是根据一些平日里瞎想出来的需求,用一些新技术去实现,即使实现不了,也能够实地演练各种新技术。这样,有朝一日新技术成熟了,就可以很快应用到新产品中。

按惯例先介绍本文角色:
Browserify 是一款让我们在浏览器端使用require('modules')来管理模块的工具。它会分析代码中的依赖关系,然后进行编译,打包成一个文件,我们只需要在HTML中引用生成的文件即可。
WebStorm 则是JetBrains出品的开发利器,集成了各种开发工具和环境,价格不贵,速度很快,样式好看,我非常喜欢。
Browserify 也提供了个工具,叫 watchify ,可以监控文件变化,即时编译。不过我更喜欢让WebStorm帮我处理这些事情,所以小小研究了一下,配置成功。
npm install browserify -g
点击“+”按钮,没有内建方案,所以选择“<custom>”
名字(Name)随便写,描述(Description)可以留空,重点是下面几项
FileType 选择 JavaScript
Scope 监控范围,内建的都不合适,所以点“…”按钮,弹出自定义的监控范围
新建一个域,名字和项目一样,好认。展开项目目录,选择存放JS文件的目录,点右侧的“Include”和“Include Recursively”将该目录下所有文件和文件夹都包含进来。OK保存。
Program 是要执行的程序,这里自然是 Browserify,Mac下通常在/usr/local/bin/browserify
Arguments 参数,参考 Browserify 的文档介绍,常规命令是
browserify index.js -o bundle.js --debug
其中 index.js 是我的入口JS,那么直接去掉 browserify 就好了。
Working Directory 工作目录,点击右侧的“Insert Macros”按钮,选择 “$ProjectFileDir$”。后面接上目录“/js/”。
完成!
前面我们设置监控范围的时候比较粗放,这样生成 bundle.js 之后会再跑一遍,有点不爽,所以图中我把 bundle.js 过滤掉了
确保这个File Watcher正常工作后,可以去把 Show console 设置成Never,这样在编辑到一半的时候就不会有错误提示了。

早先看到过一个用socket服务在线调试PHP的工具,后来怎么也找不到,于是决定自己造轮子。socket.io提供WebSocket服务,nodejs(今天竟然发布了5.0stable,简直丧心病狂) + express.js做服务器端。以前没有正经用过express.js,不过感觉上把Web所需的内容和nodejs所需的内容混在一起应该不是什么最佳实践,还是分开比较好。
使用express.static('public')可以把public目录映射为web根目录。但是用bower管理依赖的话,默认安装目录在项目的根目录,虽然也可以映射出去,不过实际路径和项目路径有异,Webstorm里的黄色波浪线看起来也很不舒服。
Google一下果然bower可以解决这个问题。在项目根目录下创建.bowerrc文件,按照JSON的写法,写入:
{
"directory": "public/components"
}
就可以指定别的目录作为安装依赖的位置。然后可以移动原来的依赖文件夹,也可以重新执行bower install。

先说下环境,Mac OS El Capitan + Chrome 46,框架是Backbone + Boostrap。
我做了一个自动搜索组件,独立测试时一切正常,放到产品中,别的都没问题,只有回车会出问题。代码在这里
不用说,这个问题很诡异,调试了半天没有头绪,只能通过观察现象去推测:
keyUpHandler都能被正确触发看来看去,第4条最可疑——我按的是回车,它会什么会跳到别的单元格呢?
这次运气比较好,表单中的接下来的几个元素刚好是日期,用到Bootstrap Datetimepicker这个插件,focus之后会自动填充日期。于是我发现,每次跳到的“其它元素”,都是原先空白的,而且是required的;不会跳到固定的,或者紧挨着的那个文本框。
于是我便想,会不会是:
submit在keydown之后触发required元素,于是跳到该元素并提示focus时间,填入日期,提示消失blur事件,隐藏列表keyup事件触发,但是输入框已没有焦点,就没有触发这个推测看起来有点道理,于是我把侦听的事件改成keydown,问题果然解决。