原文:How to Schedule Background Tasks in JavaScript
翻译:涂鸦码龙

即使忘了 JavaScript 的一切知识,也不会忘记:它是阻塞的。

想象一下,你的浏览器里住着一个魔法小精灵,负责浏览器的正常运转。不论渲染 HTML,响应菜单命令,屏幕渲染,处理鼠标点击,或者执行 JavaScript 函数,所有事情都归一个小精灵处理。它哪忙得过来,一次只能处理一件事情。如果同时丢给它一堆任务,它会列一个长长的待办列表,按顺序完成它们。

人们常常希望初始化组件和事件处理的 JavaScript 可以尽快被执行。可是,有些不太重要的后台任务不会直接影响用户体验,比如:

  • 记录统计数据
  • 发送数据到社交网络(或添加‘分享’按钮)
  • 预加载内容
  • 预处理或预渲染 HTML

他们对时序要求不严格,但是为了让页面仍然响应,直到用户滚动页面或者与内容交互时才被执行。

选择之一是 Web Workers ,它可以在独立的线程同时执行代码。用于预加载和预处理再好不过,但是你没有权限直接访问或更新 DOM。你可以在自己的代码中避开这点,但是无法保证第三方脚本比如 Google Analytics 永远不需要这个。

阅读全文 »

原文:Negating Predicate Functions in JavaScript
翻译:涂鸦码龙

如果你从没听过这个概念,那么至少用过谓语函数。谓语本质上是一个函数,根据它的参数,可以判断返回结果是 true 或者 false。一般都以“isX”命名,比如 isEven 或者 isNumber

假如我们有个程序,需要处理漫画书里的英雄和坏蛋,以下面的简单对象为例:

1
2
3
4
5
var superman = {
name: "Superman",
strength: "Super",
heroism: true
};

程序中难免会用到一些谓语,像这些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function isSuperStrong (character) {
return character.strength === "Super";
}
function isNotSuperStrong (character) {
return character.strength !== "Super";
}
function isHeroic (character) {
return character.heroism === true;
}
function isNotHeroic (character) {
return character.heroism !== true;
}
// Outputs: false
console.log(isNotSuperStrong(superman));
// Outputs: false
console.log(isNotHeroic(superman));
阅读全文 »

原先一直有个疑惑, Github fork 出来的项目,我已经做了部分修改,由于某些原因,无法提交 Pull Request,可是想把原项目的最近更新代码合并进来怎么办?google 了一下才茅塞顿开,年纪大了,这里记录一下吧。

两种方式:

  1. 项目 fetch 到本地,通过命令行的方式 merge
  2. 懒人方法,只用 Github ,不用命令行
阅读全文 »

原文:What forces layout / reflow
笔记:涂鸦码龙

注:本文只摘取了自己认为重要的知识点,并没有逐字逐句翻译

当在 JavaScript 中调用(requested/called)以下所有属性或方法时,浏览器将会同步地计算样式和布局。重排(也有叫 reflow 或 layout thrashing 的),通常是性能瓶颈。

元素

盒子计算

  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()

滚动相关

  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop,设置它们的值,同样会影响

获得焦点

阅读全文 »

前段时间组织优化我们的原生模块 API(iOS、Android 模块封装成 JavaScript 接口),于是学习了几篇 JavaScript API 设计的文章,尽管是旧文,但受益匪浅,这里记录一下。


好的 API 设计:在自描述的同时,达到抽象的目标。

设计良好的 API ,开发者可以快速上手,没必要经常抱着手册和文档,也没必要频繁光顾技术支持社区。

流畅的接口

方法链:流畅易读,更易理解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//常见的 API 调用方式:改变一些颜色,添加事件监听
var elem = document.getElementById("foobar");
elem.style.background = "red";
elem.style.color = "green";
elem.addEventListener('click', function(event) {
alert("hello world!");
}, true);
//(设想的)方法链 API
DOMHelper.getElementById('foobar')
.setStyle("background", "red")
.setStyle("color", "green")
.addEvent("click", function(event) {
alert("hello world");
});
阅读全文 »

前些日子总被人问起 iOS Retina 屏,设置 1px 边框,实际显示 2px,如何解决?
原来一直没在意,源于自己根本不是像素眼……
今天仔细瞅了瞅原生实现的边框和CSS设置的边框,确实差距不小……

上图是原生实现,下图是 CSS 边框,手机上对比更加明显

然后,如何解决呢?搜遍整个谷歌,发现好多人早已开始研究解决方案了。到底有哪些方案,到底好不好用呢?试过才知道,把我试过的结论记录一下。

阅读全文 »

原文:《ELIMINATE JAVASCRIPT CODE SMELLS
作者:@elijahmanor
笔记:涂鸦码农

难闻的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* const */ var CONSONANTS = 'bcdfghjklmnpqrstvwxyz';
/* const */ var VOWELS = 'aeiou';
function englishToPigLatin(english) {
/* const */ var SYLLABLE = 'ay';
var pigLatin = '';
if (english !== null && english.length > 0 &&
(VOWELS.indexOf(english[0]) > -1 ||
CONSONANTS.indexOf(english[0]) > -1 )) {
if (VOWELS.indexOf(english[0]) > -1) {
pigLatin = english + SYLLABLE;
} else {
var preConsonants = '';
for (var i = 0; i < english.length; ++i) {
if (CONSONANTS.indexOf(english[i]) > -1) {
preConsonants += english[i];
if (preConsonants == 'q' &&
i+1 < english.length && english[i+1] == 'u') {
preConsonants += 'u';
i += 2;
break;
}
} else { break; }
}
pigLatin = english.substring(i) + preConsonants + SYLLABLE;
}
}
return pigLatin;
}

为毛是这个味?

阅读全文 »

原文《JavaScript Errors and How to Fix Them
作者:Jani Hartikainen
翻译:涂鸦码农

JavaScript 调试是一场噩梦:首先给出的错误非常难以理解,其次给出的行号不总有帮助。有个查找错误含义,及修复措施的列表,是不是很有用?

以下是奇怪的 JavaScript 错误列表。同样的错误,不同的浏览器会给出不同的消息,因此有一些不同的例子。

如何读懂错误?

首先,让我们快速看下错误信息的结构。理解结构有助于理解错误,如果遇到列表之外的错误会减少麻烦。

Chrome 中典型的错误像这样:

1
Uncaught TypeError: undefined is not a function

错误的结构如下:

  1. Uncaught TypeError:这部分信息通常不是很有用。Uncaught 表示错误没有被 catch 语句捕获,TypeError 是错误的名字。

  2. undefined is not a function: 这部分信息,你必须逐字阅读。比如这里表示代码尝试使用 undefined ,把它当做一个函数。

其它基于 webkit 的浏览器,比如 Safari ,给出的错误格式跟 Chrome 很类似。Firefox 也类似,但是不总包含第一部分,最新版本的 IE 也给出比 Chrome 简单的错误 - 但是在这里,简单并不总代表好。

以下是真正的错误。

Uncaught TypeError: undefined is not a function

相关错误:number is not a function, object is not a function, string is not a function, Unhandled Error: ‘foo’ is not a function, Function Expected

当尝试调用一个像方法的值时,这个值并不是一个方法。比如:

1
2
var foo = undefined;
foo();
阅读全文 »

JSHint,发现错误和潜在问题的社区驱动的工具
JSLint 错误解析

单独安装

1
$ npm install jshint -g
1
2
3
4
$ jshint myfile.js
myfile.js: line 10, col 39, Octal literals are not allowed in strict mode.
1 error

编辑器和IDE插件

Sublime-JSHint

安装

Ctrl+Shift+PCmd+Shift+P
输入 install,选择 Package Control: Install Package
输入 js gutter,选择 JSHint Gutter

使用方法:

Tools -> Command Palette (Ctrl+Shift+P 或者 Cmd+Shift+P) 然后输入 jshint

– 或者 –

Ctrl+Shift+J (或者 Mac 使用 Cmd+Shift+J)

– 或者 –

当前文件右键选择 JSHint -> Lint Code

– 或者 –

打开 JavaScript 文件,菜单 View -> Show Console,然后输入 view.run_command("jshint")

阅读全文 »