前不久我买了一台新电脑,原打算给孩子用,于是有过一段时间我经常和她视频教她用电脑。

没多久,windows系统就彻底打破了我“远程视频教用电脑”的幻想。

我不是百分百确定只是windows系统的原因,亦或有联想笔记本的加成。因为路由器和笔记本在不同的卧室,所以笔记本wifi很弱——这让我很无语,笔记本的WIFI信号怎么也该比手机强啊?但答案是否定的

后来又出了个怪问题:打开wifi列表,里面空空如也。首先当然使用“网络”里面的疑难解答尝试解决问题,不出所料毫无作用。当时我是没想明白,后来我弟去看,才知道是因为系统服务里一个WIFI的基础服务没有启动,启动了就能看到WIFI列表了

当时我真想骂人(现在想起来还是想骂)!

首先WIFI对笔记本来说可以是最重要的功能了,买回来的时候,连接WIFI是没问题的,怎么用着用着连WIFI列表都显示不出来呢?

其次,基础服务没启动导致看不到WIFI列表,你windows系统能不能显示个提示啊?没提示,好吧,那我疑难解答,应该很容易就可以发现这个问题啊?你解答了个P啊

再次,我很好奇为什么那个基础服务会没启动(因为最开始是好的),或者怎么会自己就关闭了呢?那次我弟搞好之后,没多久又是老样子,我通过视频指挥了一下孩子,不一会就果断放弃。现在电脑放那儿吃灰

说到交互,我又想起windows 10打开电脑第一件事:登录,这一块简直劝退。

我有一台笔记本支持指纹登陆,指纹登陆有个通病:时灵时不灵。不灵的时候还分两种情况,一种是没识别到指纹,一种是指纹不对;如果你尝试几十次,就会提示你用其他方式(比如PIN)登录。

问题来了:如果我看到提示说指纹不对,那我想换成PIN登录,要怎么操作?答案是,用鼠标点一下屏幕,在显示的登录选项里点PIN,然后输入pin

之所以强调鼠标,是因为在上面的情况下,按键盘没有任何反应。我想要那种既然你提示指纹不对那我按下任意键你就给我显示输入框让我用pin登录的正常交互完全没有!

很多时候没插鼠标,那抱歉,你就得用触摸板操作;登录选项那几个选项(指纹,密码,PIN)还特小,而且只有图形,需要鼠标指上去才显示具体文字

另外还有,就是没识别到指纹的时候,我一直尝试,它就一直提示,可以提示几十次。何必呢?提示几次不行就显示出其他登录选项又咋了?而且你可以显示其他登录选项并且还保持指纹识别啊

更奇葩的是,有时候尝试几次指纹,没通过的话按下键盘,可以直接显示PIN登录,有时候他妈的又不行,非要你用鼠标点一下桌面,然后从登录选项里找。

windows 10想把登录界面玩出花来,比如自动更新的背景图,但我觉得基础的交互更应该优先做好。

不过,windows 10的系统缺点数不胜数,我有点强人所难了

今天碰到将字符串拆分成数组进行操作的情况,发现如果判断下字符串里有没有需要拆分的特定字符,就可以省下拆分的操作。理所当然用了indexOf。

Javascript一直在更新,比如字符串就有了一个includes方法用来判断是否包含某子串。includes方法用起来要比indexOf简洁。

然后如果要判断一个字符串是否包含好几个不同的子串,自然而然会想到正则。正则在这种情况下是代码最少的,比如:

1
/o|u|l/i.test('Hello world')
,甚至可以忽略大小写

google了一下,发现已经有相关的bench测试了:http://jsbench.github.io/#a4612afd0cd26e911ee8

可以发现indexOf比其余方式也就快个几十上百倍。当然,大家都很快,只是indexOf最快

如果考虑到判断多个子串的情况,我们可以把以上bench里的代码修改一下,把正则改复杂,然后indexOf改成多个,再次运行,你会发现:差距更大了

简单地说,就是复杂的正则,意味着更复杂的处理逻辑,效率也呈几何下降;多个indexOf效率下降很少

当然,即使最慢的正则,也足够平常使用了。不过要注意,避免用在循环里,以及缓存正则不要每次都声明。要考虑高效的话,indexOf吊打其余的,但是如果要写好多个indexOf也让人有点烦,有需要的话可以自己造个函数

记录一种React表单验证的思路。原文参考(English)

表单字段与验证信息分开

就像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
constructor(props) {
  super(props);
  this.state = {
    fullName: null,
    email: null,
    password: null,
    errors: {
      fullName: '',
      email: '',
      password: '',
    }
  };
}

验证信息和表单字段一一对应

每个字段验证错误信息只有一条

比如,fullName的验证提示应该是“2~4个中文”,而不应该分成两个:“至少两个字”、“最多4个字”

显示验证错误信息

验证可能需要3种信息展示:

  1. 默认时的提示文本
  2. 验证没通过时的错误提示
  3. 验证通过后的正确提示

这些可以通过判断errors里的字段按条件展示。拿 errors.fullName 举例:

  1. errors.fullName为空,显示默认信息
  2. errors.fullName为字符串,显示其内容(未通过提示)
  3. errors.fullName===true,显示验证通过信息

这样,在表单提交时,判断表单各字段是否通过验证,并设置 errors 里面对应的提示信息即可

今天查 webpack 文档, 发现版本已经是 4.6 了, 而 webpack 4.0 发布于 2月25日, 距今天不足两个月.

不知道是什么促使 webpack 上演版本大战, 也许有 parcel 的原因吧. 但我要说的是, webpack 4.0+ , 变得更难用了

首先独立出来一个 webpack-cli 就能坑老大一批人

其次说好的零配置(mode设置)也并不全面, 不设置 mode 编译时还有警告; 再加上我用 webpack 本来就不是冲着零配置去的, 我喜欢的就是灵活的配置(比如怎么将打包出来的代码兼容IE8)

然后, 很多插件没有跟上 webpack 的步伐, 导致使用报错. 其中不乏知名且使用率很高的插件如 html-webpack-plugin, extract text plugin

还有就是官方的文档, 更新也严重滞后. 4.0 就废除了 CommonsChunkPlugin , 但官方的文档里还是比比皆是(只有左边的版本号变成了 4.6.0)

4.0发布不久, 我就试用了一下整体流程, 第一个感觉就是坑多.加上文档的滞后, 体验非常不好

就连 CommonsChunkPlugin 废除后用什么, 我都查了老半天—-结论是新的配置项: optimization.splitChunks

好了, 不多说了. 建议保持观望, 不要升级到 4.0 以上—-起码应该等官方文档更新后再说

偶尔我也有意识的读一些关于函数式编程的文章, 虽然在工作中实践的机会不多, 但我十分喜欢函数式编程的风格. 在现代浏览器中, 使用函数式编程实用且高大上.

函数式编程对应的是命令式编程, 函数式编程的核心当然是对函数的运用. 而高阶函数(Higher-order)是实现函数式编程的基本要素

高阶函数可以将其他函数作为参数或者返回结果。所以JS天生就支持函数式编程, 但 java 则不是(最近版本加入了)

下面简单列举一些函数式编程的特性

1, 没有for循环

虽然这根本不是个正经的(真不正经)的函数式特性,但确实是肉眼最容易看出来的特性.就如同用了 for 循环就不是函数式编程了一样

因为函数式编程必定提供替代for循环的方法, 例如随便列举几个大家耳熟能详的方法: forEach, filter, some, every, find, reduce

2,纯函数(pure-function)

纯函数即没有”副作用”的函数. 所谓的副作用是: 函数操作了其自身作用域之外的值.

这个要求对于我这种习惯命令式开发的人有点苛刻, 而且,大部分人都喜欢跨作用域干事.继续阅读

从设计图切图得到了12个小图标,是按钮的两种状态,然后我就寻思着把他们拼成一张sprite图片.

之前用过gulp的sprite插件,但这次我不想搞的太隆重.拼图我知道有个很好用的命令行工具GraphicsMagick及配套的nodejs包gm

首先说下我要拼的图片,我打算将正常状态作为第1行,激活状态作为第2行.这样可以少计算一些background-position.

折腾过程比较痛苦,本来我打算看一下GraphicsMagick与gm的官方文档,结果好多生单词,最后还是放弃了.下面说答案吧:

总的来说有两种方法,

1.使用gm包的append+adjoin方法

这个方法有缺点,就是不能方便的排序成我想要的这种布局.用adjoin我实际上拼了3次图,才最终得到sprite.参考代码如下:继续阅读

gulp是我编译sass与js的不二利器(比webpack好用),但这几天突然发现,gulp watch时,通常莫名其妙的退出,然后实时编译就断了,然后你还在奇怪为什么改了样式没反应。

gulp实现编译sass时,容易频繁出错,比如你写了个ma没按tab就手贱按了保存,sass一编译,不认识ma,就报错了,如果此时导致watch被退出,那后续编译就中断了。报错导致退出,很正常,但如果报错很频繁又每次都导致退出,那人都要疯了。

于是我只有找一下如何让gulp的watch任务在出错时不自动退出。

很简单,我直接说结论

在gulp的task里,加入onerror监听,在监听函数中,处理错误并触发end。代码如下:继续阅读

在线预览(懒更新…)

github地址:https://github.com/wslx520/llazy/

图片懒加载,是一个非常实用且使用非常广泛的功能。由于历史悠久,所以此功能的实现也达成了不少共识,我先简单列举几点:

  1. 需要后端配合:在输出html代码时,不能直接将图片真实地址赋给img.src,而是用自定义属性保存起来,图片的初始src里放一个占位图
  2. 无论是从左往右,从右往左,从上向下,从下向上,都需要能动态lazyload
  3. 初始图片(占位图)如果有明确的宽高信息就好了,不然load时会发生抖动(这也要靠后台,在输出时输出width与height)

网上有太多太多的实现,大部分都很好,完全可以满足使用需求。不过我是一个任何事情都想自已尝试下用起来心中才踏实的人,所以花了点时间自己写了个llazy.js

兼容性

网上有很多jquery的lazyload插件,而做成jq插件,就可以兼容到jq兼容的浏览器,因为最难兼容的就是选择器了。而llazy不想有依赖,所以只兼容到IE8。为什么?因为IE8就支持querySelector了啊!

判断load的时机

很多lazyload插件在判断load时机时都比较麻烦。其实load的时机从人的角度来说很简单,即:图片框出现在了可见区,就可以load了。关键就在于,如何判断图片出现在了可见区。

对这个问题,大家各显神通,什么 offset, client, page, screen, scroll等属性一长串,能把人看晕。甚至有的人实现出来才发现,只能从上向下拖时触发load,其余情况又不兼容,非常尴尬。

而我就在想,图片,是一个矩形;图片的容器,也是一个矩形。当这两个矩形相交时,不就表示可以触发load了吗?

于是google了一下:如何判断两个矩形相交,获得了一个公式——虽然公式是c语言的,但套入JS一点困难也木有。继续阅读

本文属于《Javascript基础纪要

今天在看一个模板引擎的源码里,发现一个函数:

1
2
3
4
5
function regexpLiteral(source) {
        return source.replace(/[\^\[\]\$\(\)\{\}\?\*\.\+]/g, function (c) {
            return '\' + c;
        });
    }

这函数本来没有问题。但在用于模板引擎中,在解析模板语法的过程中,可能大量调用,此时就会有一个潜在问题——或者说,可以优化之处:

函数中给replace传入了一个正则表达式,是直接使用正则表达式字面量传入的,而这实际上相当于,每次执行这个函数,都会创建一个正则表达式。继续阅读

nodejs,本来是用来开发网站的,但用它来写小工具真是好用到不行,反而用纯JS语法来开发一个整站,看起来不那么容易和靠谱。不过经过这么几年的发展,nodejs已经从0.12升级到了7.5(不得不说版本变化太快同样会给人“不稳定”的印象),大量框架纷纷发布,日益成熟。用来做web开发,应该是足够了。

比如现在想开发一个网站,可使用的框架有: Hapi, Express.js, Restify 与 Koa。

记得我刚开始学习nodejs建站时,网上全是express的文章,没办法,因为当时除了express,其他框架都还没出生,更别提推广了。

而express给我的印象,并不好。首先是他默认的模板引擎jade,让我很抵制——我并不认为有什么比html语法更具描述性,嵌套能力更强的文本标记语言了;其次是express太轻量级了,处理一个表单都要引入“中间件”,在我看来,处理表单(以及文件上传)不应该是一个web框架最基本的能力吗?偏偏要独立出来。基于这两个主要原因,一直没能将express学完。

restify,我也用过,人如其名,他主要是用来做restful的网络接口,要用来做整站(比如动态生成静态html, 处理文件上传等)那就是用错地儿了。继续阅读