1

情况

好的,这就是交易:我给自己设定了一个挑战来提高我的 JavaScript 知识。这一挑战涉及创建一个完全前端的类似 Excel 的电子表格。目前我拥有的是一个包含 15 列和 30 行表格单元格的表格,允许文本输入。就像在 Excel 中一样,每个单元格都有自己唯一的参考 ID(A2、F14、G9 等):

           _________________
     _____|__A__|__B__|__C__|
    |__1__|__8__|_____|_____|
    |__2__|_100_|__6__|_____|
    |__3__|_300_|_____|__5__| etc...

这些单元格将允许在其中放置类似 Excel 的实时公式,并且电子表格将相应地自行更新,例如:

           _____________________
     _____|__________C__________|
    |__1__| =(SUM(A1:A3)*C3)+B2 |

    Would translate to: var n = ((8+100+300)*5)+6;

问题

现在这一切都很好,但问题是:每次我只更新一个单元格时,我都必须循环并更新所有单元格以确保数据准确。当只有 9 个可用的单元格(如上面的粗略示例)时,这不是一个大问题,但我当前的表有 15 列和 30 行......其中 450 个!

我目前已经设置好了,每次浏览器的焦点离开一个单元格时,后面的 JavaScript 都会循环并更新每个单元格,以确保数据都是正确的。当只有 5 或 6 个包含数据的单元格时,这本身会导致一点点延迟,所以我担心当我填充电子表格中的每个单元格时,我的浏览器会死在我身上。

我很可能梦想着不可能的事情,但理想情况下,我希望能够呈现一个包含数百列和行的电子表格,这些列和行可以即时更新。所以我给你们的两个问题是:

  • 我能做些什么来防止延迟?
  • 是否有可能在不中断互联网的情况下支持超过 15 列和 30 行的公式?
4

2 回答 2

2

您不需要在每个单元格上运行“刷新”。当一个单元格被更新时,如果其中有一个函数,它将引用一个特定的单元格、行或列。由于它包含该引用,因此您可以对其进行解析以确定需要更新哪些单元格。例如,您=(SUM(A1:A3)*C3)+B2知道它只需要 A1、A2、A3、C3 和 B2 中的值 - 因此您可以直接引用这些单元格,而不是遍历所有内容。由于您知道要使用侦听器更新的最后一个单元格,因此您可以解析单元格引用的数据,然后仅在这些单元格上运行您的脚本(如果触发事件的单元格中的数据需要更新)。您正在控制所有功能和用户选择数据的方式,以便您知道何时需要更新某些内容。

于 2013-01-14T22:04:41.260 回答
1

我认为一个好的解决方案是处理回调而不是遍历整个表格。

每次创建新公式时,您都应该在该公式中查找引用的单元格,并添加一个处理程序来更改每次引用单元格更改时调用该引用单元格的单元格。

我创建了一个非常简单的示例来说明我的意思。小心使用它,它可能非常有问题,因为一旦您更改公式,我就不会清理引用的单元格。无论如何,我认为它可能看起来很清楚作为一个例子。

这个想法的核心在于以下代码片段

$('input').on('change', function(){
  var referencedCells = getReferencedCells($(this).val());
  var $referencer = $(this);  

  for(var i=0 ; i<referencedCells.length; i++){  
    $(referencedCells[i]).on('change', function(){  
      updateValue($referencer);
    });
  }

  updateValue($referencer);

});

假设每个单元格都是input. 每次更改时,您都会在公式中查找引用的单元格,并为它们添加回调。因此,当您更改这些单元格时,您的公式值将更新,而无需查找其公式中调用您更改的单元格的所有单元格。

编辑:每个单元格只接受不以“=”开头的总和(例如:A2+B2+3)(没有空格)或文字。结果显示在警报中,因为更改实际值会弄乱公式(在现实生活中,您可以将实际值保存在属性中来完成此操作)。不要尝试在好的情况下不应该工作的任何公式(任何在 excel 中显示的东西与数字不同的东西)。

于 2013-01-14T22:49:29.583 回答