Daniel Hyuuga
Daniel Hyuuga

Reputation: 466

Javascript - Removing array item & DOM

I'm trying to learn Javascript and so I made a little code, but there is something wrong with it that I can

var array = new Array("Apple","Mangosteen","Durian","Pineapples");
...
...
function B() {
    ...
    ...
    var BP = $("<p></p>");
    BP.text("Click \"x\" on items to be removed").append("<br/>");
    for (i=0;i<array.length;i++) {
        var f = array[i];
        var F = $("<div></div>");
        F.attr({"class":"f"});
        var N = $("<span></span>");
        N.attr({"class":"n"});
        N.text(f);
        var d = $("<span></span>");
        d.attr({"class":"cc sl"});
        d.bind("click", function(e){
            e.stopPropagation();
            e.preventDefault();
            IR(f,F);
        });
        d.html("&times;");
    ...
    ...
}
function IR(f,F) {
    var a = array.indexOf(f);
    array.splice(a,1);
    F.remove();
}

When I added console.log(f); in function IR(), the value passed will always be "Pineapples", regardless if I'm clicking "x" on "Apples" or "Durian", the f value passed will always be "Pineapples". What is wrong with it?

Upvotes: 0

Views: 123

Answers (3)

alisa
alisa

Reputation: 111

When you declare a variable using var it will be declared within a scope of the function. That's why when you click 'x' javascript will pass to the IR function the last value of the variables - "Pineapples" and Pineapples's div. If you want to declare a variable within the 'for' cycle scope, use let. In this case, in every loop of 'for' cycle javascript will create a new variables f and F.

var array = new Array("Apple","Mangosteen","Durian","Pineapples");

function B() {
    var BP = $("<div></div>");
    BP.text("Click \"x\" on items to be removed").append("<br/>");
    for (var i=0;i<array.length;i++) {
        let f = array[i];
        let F = $("<div></div>");
        F.attr({"class":"f"});
        var N = $("<span></span>");
        N.attr({"class":"n"});
        N.text(f);
        var d = $("<span></span>");
        d.attr({"class":"cc sl"});
        d.bind("click", function(e){
            e.stopPropagation();
            e.preventDefault();
            IR(f,F);
        });
        d.html("&times;");
        F.append(N).append(d)
        BP.append(F)
      }
}
function IR(f,F) {
    var a = array.indexOf(f);
    array.splice(a,1);
    F.remove();
}

Upvotes: 1

VISHNU
VISHNU

Reputation: 966

its because the scope of variable "i" is global, so var f = array[i]; will result in var f = array[3]; so you will get only "Pineapples". I will give you a simple sample code to understand the issue. please run below code.

    <script>
var funcs = [];
for (var i = 0; i < 3; i++) {          // let's create 3 functions
    funcs[i] = function() {            // and store them in funcs
        console.log("My value: " + i); // each should log its value.
    };
}
for (var j = 0; j < 3; j++) {
    funcs[j]();                        // and now let's run each one to see
}
</script>

you will get only 3 because "i" is in global scope.

Upvotes: 1

Roysh
Roysh

Reputation: 1550

You call a function inside a for loop - something you can read more about here JavaScript closure inside loops – simple practical example.

For now, if you're using ES6. The easiest way to solve it will be using let in the for loop.

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

Or else, use Array.forEach() instead of the for loop.

In your case it should be something like

array.forEach(function(fruit) {
        var f = fruit;
        var F = $("<div></div>");
        F.attr({"class":"f"});
        var N = $("<span></span>");
        N.attr({"class":"n"});
        N.text(c);
        var d = $("<span></span>");
        d.attr({"class":"cc sl"});
        d.bind("click", function(e){
            e.stopPropagation();
            e.preventDefault();
            IR(f,F);
        });
        d.html("&times;");
    ...
    ...
});

Upvotes: 2

Related Questions