具有记忆功能,如何不进行每次评估?

时间:2014-12-24 10:54:56

标签: javascript jquery html

我正在编写一个简单的jQuery函数,它会在某些视口上交换其他HTML元素。这个想法很简单:

<div data-swap-for="#element" data-swap-on="phone"></div>

当当前媒体查询对应于电话时,将在该行之后插入标识为#element的元素(有关如何完成此操作的详细信息并不重要)。

我的功能如下:

jq.fn.swapElements = function(viewport) {

    var targets = jq('[data-swap-for][data-swap-on='+viewport+']');

    if (targets.length) {
        console.log('Found elements to swap for', viewport);

    } else {
        console.log('Found no elements to swap for', viewport);
    }

    return {
        on: function() {
            console.log('Should swap elements for', viewport);
        },
        off: function() {
            console.log('Should restore elements', viewport);
        }
    }
};

因此,只要屏幕进入手机布局,就会调用:

jq().swapElements('phone').on();

哪个应该进行所有DOM转换,当它退出电话布局时,它会调用:

jq().swapElements('phone').off();

哪个应该恢复它们。

我的问题是这两个正在创建var targets...部分的新评估,结果是:

console output

作为控制台中的输出,我需要此函数来缓存或记住它使用的变量,以便生成的控制台输出为:

> Found elements to swap for phone
> Should swap elements for phone

也就是说,每次调用只评估元素并保存变量一次(不同的viewport值应该调用新的评估。)

我一直在研究高阶函数和memoization,但我对如何在这种情况下应用它特别是jQuery函数感到困惑。

请帮帮忙?

由于

2 个答案:

答案 0 :(得分:0)

您可以使用一些变量(对象或数组)来缓存已经定位的元素。

var cache = {}; // Should be out of function

if (viewport in cache) {
    var targets = cache[viewport];
} else {
    var targets = jq('[data-swap-for][data-swap-on='+viewport+']');
    cache[viewport] = targets;
}

我会采用稍微不同的方法:

jq.fn.swapElements = {
var cache;
getTargets: function(viewport) {
    if (viewport in this.cache) {
        return cache[viewport];
    } else {
        var targets = jq('[data-swap-for][data-swap-on='+viewport+']');
        if (targets.length) {
            console.log('Found elements to swap for', viewport);
        } else {
            console.log('Found no elements to swap for', viewport);
        }
        this.cache[viewport] = targets;
        return this.cache[viewport];
    }
}
on: function(viewport) {
    console.log('Should swap elements for', viewport);
},
off: function(viewport) {
    console.log('Should restore elements', viewport);
}
};

伪代码可能在特定情况下不起作用,但你明白了。每当您需要目标时,请拨打swapElements.getTargets(viewport)功能。

答案 1 :(得分:0)

我很确定你不需要一个更高阶的memoize函数(尽管你在编写一个函数时可以轻松地应用它)。

您需要做的是将jq().swapElements('phone')的结果存储在变量中,当屏幕进入/退出手机布局时,您应该调用该变量上的方法,而不是创建新实例。