2013-01-14 34 views
1

现状

好更新单元格时,所以这里的交易:我给自己定下了以提高我的JavaScript知识是一个挑战。这项挑战涉及创建完全类似Excel的电子表格。目前我所拥有的是具有15列和30行表格单元格的表格,它们允许文本输入。就像在Excel中,每个小区都有自己独特的参考ID(A2,F14,G9等):减少滞后于HTML类似Excel的电子表格

  _________________ 
    _____|__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行的公式,而不会在这个过程中打破互联网?
+0

为什么你必须循环遍历每个单元格?该公式仅影响'this'单元格,您可以将其他单元格的值保存在数组中,只在表格单元格值发生更改时才更改该数组。 –

+0

因为例如,如果该公式在C1中,并且D1引用C1,那么D1将需要其值更新。如果我将所有值存储在一个数组中,每次更改单元格时仍然需要更新这些值。 –

回答

1

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

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

我创建了一个very quick example我的意思。小心使用它,它可能非常麻烦,因为一旦你改变公式,我不会清除引用的单元格。无论如何,我认为这可能看起来很清楚。

理念的核心在于下面的代码片段

$('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中会显示不同于数字的东西)。

+0

这看起来很有前途!目前,我已将每个公式存储在每个单元格的数据属性中,因此已经解决了这个问题。目前工作中,但稍后会尝试这个,谢谢! –

+0

顺便说一句,只是注意到,当您引用具有公式而不是文字的单元格时,此简化版本将不起作用。此外,如果您有循环引用,它将进入无限循环。稍后我会看看我能否解决第一个问题......我也在工作。 – Sam

+0

好吧,我编辑了这个例子,添加了一个简单的递归函数来计算单元格的值,而不是遍历整个表格。 – Sam

2

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

+0

为了回应你对这个问题的第二条评论,如果使用我上面的例子,单元格A1引用了一些其他单元格,你可以解析这个单元格中的数据并完成你在相关单元格上需要的任何操作。您可以简单地在每个引用的单元格上运行一个foreach,并在其内部检查是否有其他单元格被引用并以递归方式继续向下钻取,直到您到达最后。 – Jack

+0

每当引用的单元格发生更改时,这样做是否仍然会使网站滞后?如果B1是最初引用的单元格并且发生更改,则不仅需要更新引用B1的单元格,而且引用已更新的单元格的所有单元格也需要更新。如果可能,逐步更新必要的电池而不是试图一次完成所有电池,会更好吗? –

+0

那么,当然有些操作会需要一些延迟 - 这也会发生在Excel中。但是,与上述方式相反,电子表格上任何事件的发生都不会导致滞后。此外,这些较长的操作仍将比任何导致整个表刷新的单个操作更短,因为您仍未更新整个表。这是做到这一点的最佳方法。 – Jack