2013-08-02 177 views
1

我有一個對象,X和一些創建div並分配id = X.ID的代碼。創建HTML之後,我的對象分配到div,像這樣:Javascript將新屬性添加到元素

document.getElementById(X.ID).XValue = X; 

如果我設置語句後休息一下,我可以evaulate document.getElementById(X.ID).XValue看到X.

雖然所有屬性我創建了HTML,我加onmouseup="MOUSE_UP(event)".

var aProp = {}; 
aProp.ThisValue = "This"; 
aProp.ThatValue = "That"; 
aProp.Id = 5; 
var html = '<div id="' + aProp.Id + '"'; 
var func = 'MOUSE_UP'; 
html += ' onmouseup="' + func + '(event) ">'; 
html += '</div>'; 
document.getElementById("test").innerHTML += html; 
document.getElementById(aProp.Id).XVALUE = aProp; 

function MOUSE_UP(event) { 
    alert(event.currentTarget.XValue.ThisValue); 
} 

現在,當我設置爲MOUSE_UP休息,event.currentTarget是我的div(event.currentTarget.id == X.ID),但event.currentTarget.XValue是不確定的。

爲什麼XValue在此之前定義時未定義?

+0

你的意思是'onmouseup =「MOUSE_UP(event)」'?額外的單引號可能會丟掉東西... –

+0

你可能會覺得這很有用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty –

+3

這是粗略的你在做什麼?因爲它似乎工作。 http://jsfiddle.net/jeffman/6whJ3/ – 2013-08-02 22:29:13

回答

1

貌似設置innerHTML#test會從它的孩子們消滅所有自定義屬性。您可以在jsFiddle中查看。當你運行小提琴,因爲它是,你會發現增加更多的內容與test.innerHTML += ...後的#1NewProp將成爲undefined如果您登錄tabIndex而不是NewProp,你會得到正確的值。

發生這種情況是因爲+=運算符只是a = a + b等語句的快捷方式,它也可以寫成a += b

Basicly您創建的#test內HTML字符串,然後另一個字符串添加到它,最後用這個新的字符串替換的#test原來innerHTML#test中的所有以前的元素都被替換爲沒有設置自定義屬性的新元素。

當設置id屬性的元素,也id屬性被添加到HTML,因此它們的#testinnerHTML的一部分,並且被添加到新創建的HTML太。

如果你使用正確的DOM操作,而不是設置innerHTML,你會得到你想要的結果。下面的代碼使用createElement()appendChild()方法,而不是設置innerHTML

function myMouseUp(e) { 
    alert("at MouseUp " + e.currentTarget.NewProp.ThisValue); 
} 

function buildOneDiv(aProp) { 
    var html = document.createElement('div'); 
    aProp.ThisValue = 'This is ' + aProp.id; 
    aProp.ThatValue = 'That is ' + aProp.id; 
    html.id = aProp.id; 
    html.addEventListener('mouseup', myMouseUp, false); 
    html.innerHTML = 'Test ' + aProp.id; 
    return html; 
} 

function buildDivs(x) { 
    var html = buildOneDiv(x); 
    document.getElementById("test").appendChild(html); 
    document.getElementById(x.id).NewProp = x; 
} 

window.onload = function() { 
    var aProp, i; 
    for (i = 1; i < 4; i++) { 
     aProp = {}; 
     aProp.id = i; 
     buildDivs(aProp); 
    } 
}; 

A live demo at jsFiddle

+1

@KellyCline設置'innerHTML'真的會清除元素的自定義屬性,你可以用這個簡單的[fiddle](http://jsfiddle.net/uSWPG/1/)來檢查它。如果註釋掉添加第4段的行,可以看到每個「p」的自定義屬性。您的解決方法有效,因爲它使用全局對象myDivs而不是元素的自定義屬性。 – Teemu

+0

@KellyCline有何評論? – Teemu

+0

加上一個用於定義問題的真正含義並證明createElement/appendChild解決問題。 –

0

這不是一個答案,因爲它是一個澄清和解決方法。

鑑於這個網站

<div id="test"></div> 

和驗證碼

function myMouseUp(e) { 
    alert("at MouseUp " + e.currentTarget.NewProp.ThisValue); 
} 

function buildOneDiv(aProp) { 
    aProp.ThisValue = "This"; 
    aProp.ThatValue = "That"; 
    var html = '<div id="' + aProp.id + '"'; 
    var func = 'myMouseUp'; 
    html += ' onmouseup="' + func + '(event) ">'; 
    html += 'Test ' + aProp.id + '</div>'; 
    return html; 
} 

function buildDivs(x) { 
    var html = buildOneDiv(x); 
    document.getElementById("test").innerHTML += html; 
    document.getElementById(x.id).NewProp = x; 
} 

window.onload = function() { 
    for (var i = 1; i < 4; i++) { 
     var aProp = {}; 
     aProp.id = i; 
     buildDivs(aProp); 
    } 
}; 

最終的結果是,只有最後一個div其onmouseup定義將在myMouseUp爲NewProp一個合法的值。對於每個其他div,該屬性是未定義的。這就是爲什麼我有一些評論表明「它確實有效」。它適用於ONE,這就是我的例子。 (這是澄清。)

我的解決方法是增加一個全局對象是一個關聯數組,並更改兩種說法:

var myDivs = {}; // global 

更換

document.getElementById(x.id).NewProp = x;

在buildDivs

myDivs[x.id] = x;

a ND與

alert(myDivs[e.currentTarget.id].ThisValue);取代

alert("at MouseUp " + e.currentTarget.NewProp.ThisValue);

在myMouseUp

我仍然想知道爲什麼原始方法不起作用。