簡體   English   中英

如何將對象與DOM元素關聯

[英]How to Associate an Object with a DOM Element

我的JS設置中有一個主對象,即:

var myGarage = {
    cars: [
        {
            make: "Ford",
            model: "Escape",
            color: "Green",
            inuse: false
        },
        {
            make: "Dodge",
            model: "Viper"
            color: "Red",
            inuse: true
        },
        {
            make: "Toyota",
            model: "Camry"
            color: "Blue",
            inuse: false
        }
    ]
}

現在我把車停在我的車上並放在桌子上。 在表格中,我還有一個按鈕,可讓我將車輛切換為“使用中”和“未使用中”。

如何將每行的DOM元素與其對應的汽車相關聯,這樣如果我切換“inuse”標志,我可以更新主對象?

您實際上可以將對象直接附加到節點:

var n = document.getElementById('green-ford-escape');
n.carObject = myGarage.cars[0];
n.onclick = function() {
  doSomethingWith(this.carObject);
}

對於同消除歧義,在某些情況下,它更明確寫入上述事件處理程序指n而不是this

n.onclick = function() {
  doSomethingWith(n.carObject);
}

您還可以直接引用附加事件中的對象:

var n = document.getElementById('green-ford-escape');
n.onclick = function() {
    doSomethingWith(myGarage.cars[0]);
}

在后一種情況下, myGarage 不必是全球性的。 您可以執行此操作並期望它正常工作:

(function(){

    var myGarage = { /* ... etc ... */ };

    var n = document.getElementById('green-ford-escape');
    n.onclick = function() {
        doSomethingWith(myGarage.cars[0]);
    }

})();

節點的事件函數將正確“保持”局部變量,有效地創建私有變量。

您可以在Chrome / FF / IE控制台中測試:

var o = {a: 1};
var n = document.createElement('div');
n.innerHTML = "click me";
n.data = o;
n.onclick = function() { n.data.a++; console.log(n.data, o); }
document.body.appendChild(n);

您應該看到控制台在每次單擊時記錄兩個相同的對象,每個對象都遞增a值。

請注意 ,將n.data設置為基元將不會創建引用。 它會復制價值。

我建議考慮addEventListener ,以及一個使你的對象符合eventListener接口的構造函數。

這樣,您可以在對象,元素和處理程序之間建立良好的關聯。

為此,請創建一個特定於您的數據的構造函數。

function Car(props) {
    this.make = props.make;
    this.model = props.model;
   // and so on...

    this.element = document.createElement("div"); // or whatever

    document.body.appendChild(this.element);      // or whatever

    this.element.addEventListener("click", this, false);
}

然后實現界面:

Car.prototype.handleEvent = function(e) {
    switch (e.type) {
        case "click": this.click(e);
        // add other event types if needed
    }
}

然后在原型上實現.click()處理程序。

Car.prototype.click = function(e) {
    // do something with this.element...
    this.element.style.color = "#F00";

    // ...and the other properties
    this.inuse = !this.inuse
}

那么你就可以遍歷數組,並為每個項目創建一個新的Car對象,它將創建新元素並添加監聽器。

myGarage.cars.forEach(function(obj) {
    new Car(obj)
})

您需要在信息中使用某種ID或不同的行,否則您將不得不依賴數組索引來執行此操作。 無論哪種方式,您都希望使用數據屬性存儲數據

所以當你循環:

for (var i = 0, l = array.length; i < l; i++) {
  var div = '<tr data-car="' + JSON.stringify(array[i]) + '" data-index="' + i + '"><td></td></tr>'
}

並在您的點擊事件:

$('button').click(function() {
    var carIndex = $(this).closest('tr').attr('data-index');
    var carData = $(this).closest('tr').attr('data-car');
    if (carData) carData = JSON.parse(carData);

    myGarage.cars[carIndex].inUse = true;
})

如果將數據綁定到DOM,甚至可能不需要更新實際的JS數據。 可以遍歷表中的每一行並重新創建從中創建表的數據對象。

您可以使用HTML5 data- *屬性找出它是哪一行。 你必須做這樣的事情

var table = $('<table>'); // Let's create a new table even if we have an empty table in our DOM. Simple reason: we will achieve single DOM operation (Faster)

for (var i=0; i<myGarbage.cars.length; i++) {
    // Create a new row and append to table
    var tr = $('<tr>').appendTo(table);

    var carObject = myGarbage.cars[i];
    // Traverse the JSON object for each car
    for (var key in carObject) {
        // Create other cells. I am doing the last one
        var td = $('<td>').appendTo(tr);
        var button = $('<button>').attr('data-carId', i).addClass('toggle-inuse').appendTo(td);
    }
}
// If en ampty table awaits me in DOM
$('#tableId').html(table.html());

現在我們將在按鈕上添加事件監聽器: -

$('.toggle-inuse').click(function() {
    var i = $(this).data('carId');
    myGarbage.cars[i].inuse = !myGarbage.cars[i].inuse; //Wow done
}

試試吧!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM