开发者

Javascript DOM batch add/remove/edit elements & children with only 2 DOM calls

Some background to understand how it works

I have a hierarchy of Javascript Objects, in this case I will call them Sprites. Each Sprite reference 1:1 an HTML Element.

This is an abstraction layer for HTML & CSS;

Currently when you change a property:

mySprite.set('width', 100);

it will not update the HTML Element in a synchronous way, but will start a timer of milliseconds, in order to wait for other changes applied to this HTML Element.


Ex.:

mySpite.set('width', 100);

after this change, the sprite is invalidated and after 25 milliseconds will update the HTML Element

mySprite.set('height', 100);

now this will restart the timer of 25 milliseconds and will wait 25 milliseconds to update the DOM with the width & height at the same time instead of 2 DOM changes


The problem

Now the problem I'm facing is this: (Hierarchy below represents the Sprites hierarchy, let's call them by the name they have)

I have this hierarchy and imagine that Sprites "aaaba" and "aaabc" changes it's style. Then the Sprite "aaab" adds more 3 Sprite children (they are shown in parenthesis, "aaabd", "aaabe" and "aaabf").

or in steps:

  1. aaaba.set('width', 100);
  2. aaabc.set('height', 45);
  3. aaab.addChildren(...3 children...);

Until now I would not want to make any updates to the DOM. After all Sprites have changed their properties and added and removed other Sprites (HOW DO I DISCOVER THIS MOMENT? with another timer of 25milliseconds?), I would want to work like this:

  1. Remove the Elements from DOM that are about to make major changes: aaa.removeChild(aaab)
  2. Change the style, and as they are not on DOM because their parent was removed in step1 this will not be so costly: aaaba.style.cssText = aaabc.style.cssText = "my new css"
  3. Append the children to the "aaab" element
  4. Append again the "aaab" to "aaa": aaa.appendChild(aaab);

In th开发者_JAVA百科is way is faster to make DOM changes.

 a
 |-aa
 | |-aaa
 | | |-aaaa
 | | |-aaab<
 | | | |-aaaba<
 | | | |-aaabb
 | | | |-aaabc<
 | | | |-(aaabd)<
 | | | |-(aaabe)<
 | | | |-(aaabf)<
 | | |-aaac
 | | |-aaad
 | |-aab
 | | |-aaba
 | | |-aabb
 | |-aac
 |-ab
 | |-aba
 | |-abb
 |-ac
   |-aca
   |-acb


I suppose there is no need to remove something from element tree, which is not part of a document.
Here is algorithm (I know nothing about your object model, so I made everything up)

function applyChanges (sprite, detached) {
    var detach = false, container
    if (!detached) {
        for (var i = 0; i < sprite.childSprites.length; i++) {
            if (areChangesMajor(sprite.childSprites[i])) {
                detach = true
                break
            }
        }
    }
    if (detach) {
        container = sprite.element.parentNode
        container.removeChild(sprite.element)
        detached = true
    }
    // ...
    // your stuff (applying styles, adding child sprites, etc) should be there
    // ...
    for (var i = 0; i < sprite.childSprites.length; i++) {
        applyChanges(sprite.childSprites[i], detached)
    }
    if (detach) {
        container.appendChild(sprite.element)
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜