我正在尝试创建一个函数包装器,它可以使用DOM元素作为参数来调用,并将返回一个唯一的去抖动函数,该函数绑定到其中包含一些逻辑的DOM元素。
我将一步一步地阐明我的思维过程:
以下是原始的去抖动函数
hideElementWhenIdle = _.debounce(($el) => {
if($el.is(":hover"))
hideElementWhenIdle($el);
else
$el.removeClass("visible");
}, 5000);现在,这个函数工作得很好,直到我意识到我将debounced函数绑定到调用它的第一个元素。所以,如果我想创建:
hideElementWhenIdle( $("selector-1") );
hideElementWhenIdle( $("selector-2") );他们基本上会互相揭穿对方。我想要的是每个元素都有独特的功能。
肮脏的解决方案
我当然可以这样做:
hideElementWhenIdle = function($el) {
let fn = _.debounce(($el) => {
// ... same as above
}, 5000);
return fn;
}
hideSelector1WhenIdle = hideElementWhenIdle( $("selector-1") );
hideSelector2WhenIdle = hideElementWhenIdle( $("selector-2") );现在我将有两个可以调用的独立函数。然而,这显然是肮脏的和不可伸缩的(不过,公平地说,我只有两个元素需要应用于函数)。
失败的尝试
我以为我可以wrap和memoize我的函数来实现我想做的事情,但在尝试了几次之后,我无法理解发生了什么(或者这是不是正确的解决方案)。这是我最新的尝试:
var hideElementWhenIdle = _.wrap(
_.memoize(
function($el) {
var fn = _.debounce(() => {
// ... same as above
}
),
function(func, $el) {
return func($el);
}
);我猜我这里的问题是_.debounce总是返回相同的值,所以无论$el如何,我总是缓存相同的值。
发布于 2017-07-23 21:51:50
在我看来,你肮脏的解决方案才是正确的选择。或者你需要你自己的解决器:
function debounce(func,time){
var debouncing=new Map();
return function(el){
if(!debouncing.get(el)){
debouncing.set(el,setTimeout(_=>debouncing.set(el,null),time));
return func(el);
}
};
}使用案例:
var func=debounce(function(el){
$el=$(el);
if($el.is(":hover"))
hideElementWhenIdle($el);
else
$el.removeClass("visible");
}, 5000);
func("#sth");
func("#sth");//debounced
func("#sthelse");//not debounced注意:这不适用于传递jquery对象,因为它们是唯一的。DOM节点将起作用。
http://jsbin.com/bujocoravu/1/edit?js
https://stackoverflow.com/questions/45265530
复制相似问题