6

皆さん!今日、次の機能を持つこのスクリプトを作成しました。

  • 配列に新しいアイテムを追加する
  • 配列のすべての項目を一覧表示する
  • 配列からアイテムを削除する

次の 2 つの機能があります。

  • addToFood() - 入力の値を配列に追加し、div の innerHTML を更新します
  • removeRecord(i) - 配列からレコードを削除し、div の innerHTML を更新します

コードには 3 つの for ループが含まれており、 http://jsfiddle.net/menian/3b4qp/1/で確認できます。

私のマスターは、これらの 3 つの for ループがソリューションを重いものにすると言っていました。同じことを行うより良い方法はありますか?ループを減らしてスプライスを使用する方が良いでしょうか? 前もって感謝します。

HTML

<!-- we add to our foodList from the value of the following input -->    
<input type="text" value="food" id="addFood" />

<!-- we call addToFood(); through the following button  -->    
<input type="submit" value="Add more to food" onClick="addToFood();">

<!-- The list of food is displayed in the following div -->    
<div id="foods"></div>

JavaScript

var foodList = [];

function addToFood () {
    var addFood = document.getElementById('addFood').value;
    foodList.push(addFood);

    for (i = 0; i < foodList.length; i++)   {
        var newFood = "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
    };
    document.getElementById('foods').innerHTML += newFood;
}


function removeRecord (i) {

    // define variable j with equal to the number we got from removeRecord
    var j = i;

    // define and create a new temporary array
    var tempList = [];

    // empty newFood
    // at the end of the function we "refill" it with the new content
    var newFood = "";
    for (var i = 0; i < foodList.length; i++) {
        if(i != j) {

    // we add all records except the one == to j to the new array
    // the record eual to j is the one we've clicked on X to remove
            tempList.push(foodList[i]);
        } 
    };

    // make redefine foodList by making it equal to the tempList array
    // it should be smaller with one record
    foodList = tempList;

    // re-display the records from foodList the same way we did it in addToFood()
    for (var i = 0; i < foodList.length; i++) {
        newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
    };
    document.getElementById('foods').innerHTML = newFood;
}
4

4 に答える 4

5

使用する必要がありますarray.splice(position,nbItems)

function removeRecord (i) {
    foodList.splice(i, 1); // remove element at position i
    var newFood = "";
    for (var i = 0; i < foodList.length; i++) {
        newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> "
            + foodList[i] + " <br>";
    };
    document.getElementById('foods').innerHTML = newFood;
}

http://jsfiddle.net/3b4qp/5/

JQueryを使用しています:

$(function(){
    $(document).on('click','input[type=submit]',function(){
        $('#foods')
           .append('<div><a href="#" class="item">X</a> ' 
                + $('#addFood').val() + '</div>');
    });

    $(document).on('click','.item',function(){
        $(this).parent().remove();
    });
});

http://jsfiddle.net/jfWa3/

于 2013-02-11T15:54:04.267 に答える
2

少なくとも、コードの移植性を高めるためのいくつかのヒントを次に示します (パフォーマンスが向上するかどうかはわかりませんが、DOM 操作の方が安価であるため、そうすべきです)。

チップ

  1. まず、イベント ハンドルを HTML から分離します。
  2. 「新しい食べ物」を関数パラメーターとして渡します
  3. ID を使用して配列要素を DOM に結び付ける
  4. 何かが変更されたときに (リストで innerHTML を使用して) すべてを再レンダリングする代わりに、関連するビットを変更するだけです。

利点:

  1. 実際には 1 回だけループします (配列から要素を削除するとき)。
  2. 何かが変更されるたびにリストを再レンダリングするのではなく、要素をクリックするだけです
  3. 追加ボーナス: 移植性が向上しました。
  4. より速くする必要があります

コード例:

フィドル

HTML

<div id="eventBinder">
    <!-- we add to our foodList from the value of the following input -->
    <input id="addFood" type="text" value="food" />
    <!-- we call addToFood(); through the following button -->
    <button id="addFoodBtn" value="Add more to food">Add Food</button>
    <!-- The list of food is displayed in the following div
    -->
    <div id="foods"></div>
</div>

JS

// FoodList Class
var FoodList = function (selectorID) {
    return {
        foodArray: [],
        listEl: document.getElementById(selectorID),
        idCnt: 0,
        add: function (newFood) {
            var id = 'myfood-' + this.idCnt;
            this.foodArray.push({
                id: id,
                food: newFood
            });
            var foodDom = document.createElement('div'),
                foodText = document.createTextNode(newFood);
            foodDom.setAttribute('id', id);
            foodDom.setAttribute('class', 'aFood');
            foodDom.appendChild(foodText);
            this.listEl.appendChild(foodDom);
            ++this.idCnt;
        },
        remove: function (foodID) {
            for (var f in this.foodArray) {
                if (this.foodArray[f].id === foodID) {
                    delete this.foodArray[f];
                    var delFood = document.getElementById(foodID);
                    this.listEl.removeChild(delFood);
                }
            }
        }
    };
};

//Actual app
window.myFoodList = new FoodList('foods');

document.getElementById('eventBinder').addEventListener('click', function (e) {
    if (e.target.id === 'addFoodBtn') {
        var food = document.getElementById('addFood').value;
        window.myFoodList.add(food);
    } else if (e.target.className === 'aFood') {
        window.myFoodList.remove(e.target.id);
    }
}, false);
于 2013-02-11T16:38:35.857 に答える