2

I'm working on a javascript project in which I use a document fragment to append several span elements at once. Then they are animated with css.

.redCircle {
    float: left;
    height:20px;
    width:20px;
    border-radius:10px;
    box-shadow: 0 0 20px red;
    background-color: red;
    animation: 2s circleFall linear;
}

@keyframes circleFall {
    0%{margin:0;}
    100%{margin:100% 10%;}
}


setInterval(thingyTime, 5000);

function thingyTime() {
    var count = 15,
        spanVar = document.createElement("span"),
        fragment = document.createDocumentFragment();

    for (var i = 0; i < count; ++i) { 

        for (var j = 0; j < 1; ++j) { 
            spanVar = document.createElement('spanVar');
            spanVar.className = "redCircle";
            fragment.appendChild(spanVar);
        }
    }

    document.body.appendChild(fragment);

};

thingyTime();

I'm trying to figure out how to remove the spans after the animation is completed. I have used

setTimeout(function(){

    spanVar.remove(spanVar.selectedIndex);

},2000); // <= animation length

and it works fine when it's only for one element, but I need to remove all the elements in the fragment.

I aprreciate your help.

thinoquinn
  • 27
  • 1
  • 8
  • After the loop `spanVar` will just be a reference to the last span you created (since the for loop overwrites it each time). You are also creating elements of type `spanVar` not actual spans (unsure if thats intentional). Easiest solution, stick all the elements you create in an array, then just iterate that to tidy em up. – Carl Sep 26 '16 at 13:54
  • Yes, @Carl I noticed that it was creating elements with the variable name and I thought it was wierd. I haven't been able to find anything about it after googling. Could you maybe explain it for me? – thinoquinn Sep 26 '16 at 14:16

2 Answers2

2

A few bits (further to my initial comment). For generating, I'd drop the extra createElement("span") at the top, since it never gets used. Then create span's in the loop, rather than spanVar's (assuming the are unwanted). For the create element method you just give it the element type you want it to make.

function thingyTime() {
    var count = 15,
        spanVar,
        fragment = document.createDocumentFragment();

    for (var i = 0; i < count; ++i) { 
        for (var j = 0; j < 1; ++j) { 
            spanVar = document.createElement('span');
            spanVar.className = "redCircle";
            fragment.appendChild(spanVar);
        }
    }
    document.body.appendChild(fragment);
};

For cleanup, easiest way is just use the class you created. Query for em all, & then nuke em one by one.

document.querySelectorAll(".redCircle").forEach(function(c){
    c.parentNode.removeChild(c);
});

If you have other instances of the redCircle you don't want to nuke on the other hand. I'd add a var circlesToCleanup = []; then in the creation loop push each of em on to it circlesToCleanup.push(spanVar)

Then when you call your cleanup, iterate circlesToCleanup rather than the querySelector output.

Carl
  • 1,816
  • 13
  • 17
  • Thanks @Carl this: `document.querySelectorAll(".bossLaser").forEach(function(c){ c.parentNode.removeChild(c); });`worked for me. – thinoquinn Sep 26 '16 at 14:48
  • 1
    Removing each child one by one will cause the browser to redraw and repaint on each child removed. if you have many spans a better solution would be to add the spans to a doc fragment, then to a parent container, and when ready to remove, remove the parent container removing all spans in one reflow. – tech-e Jun 29 '17 at 17:59
  • Not always, modern browser wait for JavaScript execution to be finished, before repainting anything – Walle Cyril Oct 17 '17 at 15:57
  • @tech-e not on a document fragment darlin – Sayan J. Das Sep 19 '19 at 08:56
1

Since you're already specifying a class:

spanVar.className = "redCircle";

you can use that to select all those elements and remove them:

$('.redCircle').remove();
Mike Mannakee
  • 361
  • 1
  • 5