0

使用 JavaScript 访问 DOM 元素很慢,因此为了获得响应速度更快的页面,我们必须执行以下操作

  1. 缓存对访问元素的引用

  2. “离线”更新节点,然后将它们添加到树中

  3. 避免使用 JavaScript 修复布局

谁能告诉我如何做前两件事?

谢谢你

4

1 回答 1

2

这些是一些抽象的问题,甚至不一定相互关联。


1.缓存访问元素的引用

缓存引用是一种实践,有时是必要的。在本地(或者,嗯,全局)维护对元素的引用的行为相当简单。当使用 DOM 方法时document.createElement(),通常会保存一个变量。这是一个可以缓存供以后使用的参考。document.getElementById返回对元素document.getElementsByTagName的引用,返回引用列表,如document.querySelectorAll等。


2.“离线”更新节点,然后将它们添加到树中

当您说“离线”时,我不太确定您所引用的上下文。这是在将任何元素(包括类似的字符串<div>)添加到 DOM 之前吗?

与元素交互的三种主要方式:

  • document.createElement(与elem.appendChild

    在遥远的过去有一天,这是用你的页面内容胡闹的惯用方式。它吸引了“Web 开发人员”社区的子集,他们对类似 API 的编程方式来处理和处理 DOM 及其居民感到满意;它几乎看起来像真正的代码,很难的东西。

    当然,有些代码有点杂乱无章,迭代地创建和附加并附加到那些代码上,对那些不需要生成它的人来说,这看起来很酷。

    如果你很聪明cloneNode,你可以用 DOM 节点得到更合理的结果。但我认为直到最近几年,cloneNode这并不是一个很好的选择。我可能记错了,货物崇拜和所有。如我错了请纠正我。

    然后 IE 出现并给了我们...

  • elem.innerHTML

    惊喜!这是不标准的,伙计。他们怎么可能?唯一的问题是,它真的很快Killer-fast(像 IE6/7 一样从未发生过,我们都想忘记)。

    DOM 是……无论如何,浏览器很慢而且效率低下,而且无论如何都没有真正运行真正的代码,所以 DOM 的缓慢是可以容忍的。但是,不管出于什么原因,innerHTML进入了 stage-left 和 groovy,老兄,它比 DOM 方法快。优雅,以“我喜欢整天盯着标记而不是 DOM 方法”的方式。

    最终,每个人​​都加入了.innerHTML潮流,现在它已成为事实上的标准。它很快,对吧?

    好。依靠。做elem.innerHTML = "<p>Hey!</p>"的很快,是的。也是elem.innerHTML = '<p>Hey!</p><p>Yo!</p><p>What!</p>'。所以人们很自然地认为,它是一种财产,让我们尽情狂欢吧

    for 1..500 element.innerHTML += '<p>Medusa!</p>';
    

    那里的伪代码。问题出在哪里?对我们的冲刺朋友+=来说就像氪石innerHTML, . 疯狂的坏主意,从不做,甚至不去想它的坏主意。为什么?AFAIK,它与.innerHTML攻击内部内容的方式有关,所以当你 时elem.innerHTML += '...mayhem...',你每次都在“拆除”DOM。或者其他的东西。这让 DOM 哭泣。

    不要让 DOM 哭泣。

  • documentFragment

    那么在某个时候(它一直都在那里吗?DOM Level 3,如果这意味着什么的话),documentFragment让场景崩溃了。不过, MDN 的简短说明对此进行了总结。它Node与主 DOM 是分开的。就像你放东西的小盒子,然后把它移到爸爸 DOM。

    速度而言,它大部分都在后面.innerHTML,而且都是 DOM 程序和东西。漂亮。


在缓存方面,很大程度上与您如何构建代码和使用范围来发挥自己的优势有关。举个例子:

window.addEventListener('load', function () {
  var target = document.getElementById('target'),
      source = document.getElementById('source'),
      ...

  source.addEventListener('click', function () {
    var words = source.getElementsByTagName('span'),
        total = words.length,
        word;

    while (word = words[--total]) {
      target.appendChild(word);
    }
  });

});

http://jsfiddle.net/userdude/T6YLZ/

我将targetand保留在处理程序的范围source之上click,以便稍后访问它们时,我已经拥有它们。由于我没有添加wordssourceuntil window.onload,所以我不会得到所有带有to的span元素,直到发生。wordstargetsource.click

您似乎documentFragment在用您的术语描述 s 。他们很酷。我只是最近才遇到它们,尽管显然对于那些知道的人来说,它们似乎已经在那里呆了几年或更长时间。因此,如果您是其中之一,请在插入非片段 DOM 之前must.use.dom.methods(now)使用s 。documentFragment

但是...请记住,有时您会使用elemn.innerHTML,因为您正在添加标记。也许你有模板、AJAX 响应标记等等。

只是不要+=elem.innerHTMLing 时。

于 2013-01-12T13:43:53.033 回答