[英]How to associate Object with DOM element in plain Javascript?
[英]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.