您的位置:首页 > Web前端 > JavaScript

javascript 函数节流

2014-03-30 16:33 323 查看
1.函数节流的概念,意义就不多说了,看腾讯web前端AlloyTeam团队的文章,清晰易懂。给个地址:
http://www.alloyteam.com/2012/11/javascript-throttle/
2.文章中给出3个节流的例子,但是实际项目中需要升级到节流版本的javascript函数太多了,总不能一个个对葫芦画瓢,每个函数依次修改吧。习惯Python装饰器了,决定写一个通用的javascript函数,能够将其他函数简单的包装之后,使其他函数变为节流版本。

上代码:

var throttle = function(targetFunc, delay, mustRunDelay) {
var throttleInstance = {
timer: null,
lastTime: 0,
context: null,
args: null,

delay: function(context, args) {
clearTimeout(this.timer);

var currentTime = +new Date();
if(!this.lastTime) {
this.lastTime = currentTime;
}
this.context = context;
this.args = args;

if(currentTime - this.lastTime >= mustRunDelay) {
this.doAction();
} else {
this.timer = setTimeout(this.timerHandler, delay);
}
},

doAction: function() {
targetFunc.apply(this.context, this.args);
this.lastTime = 0;
},
timerHandler: function() {
throttleInstance.doAction();
}
};
return function() {
throttleInstance.delay(this, arguments);
};
};


使用举例:

1. 包装单独的裸函数

比如需要监听浏览器窗口大小变化事件,每次变化输出一个字符串。

window.onresize = throttle(function(){
console.log("resized...");
},
500, 3000
);


2. 包装全局变量的共有方法

var listener = new Object();
listener.mouseover = function(e){
console.log("mouseover");
}
listener.click = function(e){
console.log("click");
}
有如上 listener全局变量,以及其click和mouseover两个公有方法,两个方法都是即时响应

document.getElementById('test').onclick = throttle(listener.click, 500, 3000);
//或者
document.getElementById('test').onmouseover = function() {
return throttle(listener.mouseover, 500, 3000);
}();//括号不能掉


经过如上包装后,即为节流版本

3.在prototype构造的对象内部包装其公有方法

var Typeahead = function (element, options) {
//do something init...
}
Typeahead.prototype = {
constructor: Typeahead,
keyup: function () {
console.log("keyup");
}//keyup为同步响应
}


此时keyup事件即时响应。如下改变后变为节流版本

Typeahead.prototype = {
constructor: Typeahead,
doKeyUp: function () {
console.log("keyup");
},
keyup: throttle(function(e){
this.realDoKeyUp(e)
}, 500, 3000)
//务必用一层匿名函数嵌套this.realDoKeyUp, 因为在throttle层面访问不到this
}


4.在非prototype方式构造的对象内部包装其公有方法

var HighChartDrawer = {
createNew: function (containerId, conf) {
var drawer = {};
drawer.init = function() {
//do something init...
};
drawer.listenSelectChange = function () {
console.log("change...");
}//listenSelectChange同步响应

return drawer;
}
}
此时drawer对象的listenSelectChange是即时响应的,如下改变后成为节流版本

var HighChartDrawer = {
createNew: function() {
var drawer = {};
drawer.init = function() {
//do something init...
};

drawer.DoSelectChange = function() {
console.log("change...");
},
drawer.listenSelectChange = throttle(function () {
drawer.DoSelectChange(); //转一次手,转而调用真正响应函数 DoSelectChange
}, 500, 3000)

return drawer;
}
}
或者

var HighChartDrawer = {
createNew: function(containerId, conf) {
var drawer = {};
drawer.init = function() {
//do something init...
};

drawer.DoSelectChange = function() {
console.log("change...");
},
drawer.listenSelectChange = throttle(drawer.DoSelectChange, 500, 3000)

return drawer;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: