本文由
伯乐在线
-
刘健超-J.c
翻译,
进林
校稿。未经许可,禁止转载!
英文出处:davidwalsh.name
debounce
对于高耗能事件,debounce 函数是一种不错解决方案。如果你不对 scroll
、resize
、和 key*
事件使用 debounce 函数,那么你几乎等同于犯了错误。下面的 debounce
函数能让你的代码保持高效:
// 返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用 N 毫秒后,再次调用它才会得到执行。如果有传递 ‘immediate’ 参数,会马上将函数安排到执行队列中,而不会延迟。
function
debounce(func, wait, immediate) {
var
timeout;
return
function
() {
var
context =
this
, args = arguments;
var
later =
function
() {
timeout =
null
;
if
(!immediate) func.apply(context, args);
};
var
callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if
(callNow) func.apply(context, args);
};
};
// 用法
var
myEfficientFn = debounce(
function
() {
// 所有繁重的操作
}, 250);
window.addEventListener(
'resize'
, myEfficientFn);
debounce
函数不允许回调函数在指定时间内执行多于一次。当为一个会频繁触发的事件分配一个回调函数时,该函数显得尤为重要。
poll
尽管上面我提及了 debounce
函数,但如果事件不存在时,你就不能插入一个事件以判断所需的状态,那么就需要每隔一段时间去检查状态是否达到你的要求。
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
32
|
function
poll(fn, callback, errback, timeout, interval) {
var
endTime = Number(
new
Date()) + (timeout || 2000);
interval = interval || 100;
(
function
p() {
// 如果条件满足,则执行!
if
(fn()) {
callback();
}
// 如果条件不满足,但并未超时,再来一次
else
if
(Number(
new
Date()) < endTime) {
setTimeout(p, interval);
}
// 不匹配且时间消耗过长,则拒绝!
else
{
errback(
new
Error(
'timed out for '
+ fn +
': '
+ arguments));
}
})();
}
// 用法:确保元素可见
poll(
function
() {
return
document.getElementById(
'lightbox'
).offsetWidth > 0;
},
function
() {
// 执行,成功的回调函数
},
function
() {
// 错误,失败的回调函数
}
);
|
Polling 在 web 中已被应用很长时间了,并在将来仍会被使用。
ONCE
有时候,你想让一个给定的功能只发生一次,类似于 onload 事件。下面的代码提供了你所说的功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
function
once(fn, context) {
var
result;
return
function
() {
if
(fn) {
result = fn.apply(context ||
this
, arguments);
fn =
null
;
}
return
result;
};
}
// 用法
var
canOnlyFireOnce = once(
function
() {
console.log(
'Fired!'
);
});
canOnlyFireOnce();
// "Fired!"
canOnlyFireOnce();
// nada
// 没有执行指定函数
|
once
函数确保给定函数只能被调用一次,从而防止重复初始化!
从一个字符串变量得到一个绝对 URL,并不是你想象中这么简单。对于某些 URL
构造器,如果你不提供必要的参数就会出问题(而有时候你真的不知道提供什么参数)。下面有一个优雅的技巧,只需要你传递一个字符串就能得到相应的绝对 URL。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
getAbsoluteUrl = (
function
() {
var
a;
return
function
(url) {
if
(!a) a = document.createElement(
'a'
);
a.href = url;
return
a.href;
};
})();
// 用法
getAbsoluteUrl(
'/something'
);
// http://davidwalsh.name/something
|
a 元素的 href
处理和 url 处理看似无意义,而 return 语句返回了一个可靠的绝对 URL。
剩下的:http://web.jobbole.com/82540/