我有很多像这样的用户输入值的输入:
<INPUT TYPE=TEXT NAME="Milk" ONKEYUP="convcase(document.convert.Milk.value)">
<INPUT TYPE=TEXT NAME="Buckwheat" ONKEYUP="convcase(document.convert.Buckwheat.value)">
还有很多这样的计算:
document.convert.Fe.value = BuckwheatFe * document.convert.Buckwheat.value + PeaFe * document.convert.Pea.value + MilkFe * document.convert.Milk.value + ...
document.convert.Hexadecanoic.value = BuckwheatHexadecanoic * document.convert.Buckwheat.value + PeaHexadecanoic * document.convert.Pea.value + MilkHexadecanoic * document.convert.Milk.value + ...
所以计算后的结果动态显示,当程序有数百个产品时,输入和计数之间的延迟太大。我计算所有产品:牛奶、荞麦……即使用户没有输入它们的值(value)。
你能告诉我如何修改算法以减少延迟吗?
最佳答案
我会像下面这样处理它。需要在计算中使用的输入可以用一个类表示,比如“itemValue”,并检索一次然后缓存。这假定它们不会改变。
标记可以如下所示:
<form name="convert">
Milk: <input class="itemValue" name="Milk" onkeyup="convcase(this)"><br>
Buckwheat: <input class="itemValue" name="Buckwheat" onkeyup="convcase(this)"><br>
Fe value: <input name="Fe"><br>
Hex value: <input name="Hexadecanoic"><br>
</form>
诸如 Fe 和 Hexadecanoic 值之类的东西也可以被缓存。如果将节点集合转换为数组以便可以使用内置数组函数,这也会有所帮助。这些可能比使用 for 循环慢,所以如果是,请将 reduce 调用转换为循环。
// Helper to convert a NodeList to an array so built-in methods can be used
function toArray(list) {
var i = list.length, arr = [];
while (i--) {
arr[i] = list[i];
}
return arr;
}
执行实际工作的函数:
var convcase = (function() {
// Cache stuff in a closure. Note that the names of each factor set
// must match the form control name where the related total is written
var factors = {
Fe: {Buckwheat:0.5, Milk:0.75},
Hexadecanoic: {Buckwheat:0.6, Milk:0.82}
};
var nodes;
return function (el) {
// Only get nodes the first time, assumes they don't change, and convert to Array
// This can be done before validation as it's not dependent on it
nodes = nodes || toArray(el.form.querySelectorAll('input.itemValue'));
// Validate el.value here and deal with invalid values.
// Only proceed if it's a valid value
// For each set of factors, do all the calculations and write totals to form
for (var factor in factors) {
// Get the factor set
var set = factors[factor];
// Write the total to the related form control
el.form[factor].value = nodes.reduce(function(sum, node){
sum += node.value * set[node.name];
return sum;
}, 0);
}
};
}());
我不会在 keyup 上执行此操作,我会等待 change 或 blur 事件,因此只有在用户很有可能暂时完成时才进行计算,否则可能会有很多无用的计算。
关于javascript - 如何修改算法以减少延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26382711/