devamat
devamat

Reputation: 2513

splice not working on array of DOM elements

I'm creating a bubbles effect, but I have an issue removing a bubble when it reaches the top. The bubbles are circle svg elements and are stored in an array. The splice function returns an error. You can see it in the animateBubbles() function. I'm not sure what I'm doing wrong.

SCRIPT438: Object doesn't support property or method 'splice'

let bubbles = [];

let bubblesC = [];

function createBubbles(n, x, y, w, h) {

    for (let i = 0; i < n; i++) {

        let circle = document.createElementNS(svgns, 'circle');

        bubblesC[i] = Math.PI / (Math.random() * Math.floor(10));

        let tmpX =  x + getRandomInt(w);

        circle.setAttribute('cx', tmpX);
        circle.setAttribute('cy', getRandomInt(h)+wHeight);
        circle.setAttribute('r', 3+getRandomInt(10));

        circle.setAttribute("id", "bubble" + i);
        circle.setAttribute("fill", "url(#grad3)");
        circle.setAttribute("stroke", "light");
        circle.setAttribute("opacity", "0.5");

        bubbles.push(circle);

        svg.appendChild(circle);

    }

}

function animateBubbles() {

    for (let i = 0; i < bubbles.length; i++) {

        let bx = parseInt(bubbles[i].getAttribute("cx"));
        let by = parseInt(bubbles[i].getAttribute("cy"));

        bx += Math.round(2 * Math.sin(bubblesC[i]));
        by += -2;

        if (by < wavesY) {
            bubbles[i].setAttribute("fill", "transparent");
            bubbles[i].setAttribute("stroke", "white");
        }

        if (by < wavesY - 20) {
            //by = getRandomInt(wHeight)+wHeight;
            bubbles[i].setAttribute("fill", "url(#grad3)");
            bubbles[i].setAttribute("stroke", "light");
            bubbles[i].setAttribute("opacity", "0.5");
        }

        if (by < wavesY - 40) {

            bubbles[i].splice(i, 1); ////////////////// THIS IS THE PROBLEM

            //bubbles[i].parentNode.removeChild(bubbles[i]);

        }

        bubbles[i].setAttribute("cx", bx);
        bubbles[i].setAttribute("cy", by);

        bubblesC[i] += Math.PI / 8;

    }

}

Upvotes: 0

Views: 673

Answers (2)

NoLogig
NoLogig

Reputation: 116

Array.splice() remove a given number of elements starting at a given index and all the remaining elements shift down. Then the afterthought block of the for-loop increments i by 1. So that a index is skipped.

Take a look at:

let fiboArray  = [ 1, 1, 2, 3, 5, 8 ];

// Array.splice() fails in forward for loops
for (let i = 0; i <= fiboArray.length ; i++) {
    if (fiboArray[i] === 1) {
        fiboArray.splice(i, 1);
    }
}
console.log(fiboArray); // → [ 1, 2, 3, 5, 8 ]

A backward for-loop can handle this special behavior

let fiboArray  = [ 1, 1, 2, 3, 5, 8 ];

// Array.splice() with backward for loops
for (let i = fiboArray.length - 1; i >= 0; i--) {
    if (fiboArray[i] === 1) {
        fiboArray.splice(i, 1);
    }
}
console.log(fiboArray); // → [ 2, 3, 5, 8 ]

But as answered before: splice() can only be used on an Array

change

bubbles[i].splice(i, 1);

to

bubbles.splice(i, 1);

Upvotes: 1

mika
mika

Reputation: 343

splice can only be used on an array not on an object. Use bubbles.splice(i, 1);

Upvotes: 3

Related Questions