1

我有一个对象 X 和一些创建 div 并分配 id = X.ID 的代码。创建 html 后,我将对象分配给 div,如下所示:

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

如果我在该语句之后设置一个中断,我可以评估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 在这里没有定义?

4

2 回答 2

1

看起来设置会清除其子级的所有innerHTML定义属性。您可以在jsFiddle中检查这一点。当您按原样运行小提琴时,您会注意到在添加更多内容后将变为 If you log而不是,您将获得正确的值。#testNewProp#1undefinedtest.innerHTML += ...tabIndexNewProp

发生这种情况是因为+=operator 只是类似语句的快捷方式a = a + b,也可以编写a += b

基本上,您从 的内部 HTML 创建一个字符串#test,然后向其中添加另一个字符串,最后用这个新字符串替换原始innerHTML的。#test中的所有先前元素#test都被替换为没有设置自定义属性的新元素。

id为一个元素设置属性时,id属性也被添加到 HTML 中,因此它们是 的一部分innerHTML#test并且也被添加到新创建的 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);
    }
};

jsFiddle 的现场演示

于 2013-08-02T23:14:34.720 回答
0

This is not so much an answer as it is a clarification and a work-around.

Given this html

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

and this code

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);
    }
};

The end result is that only the LAST div whose onmouseup is defined will have a legitimate value for NewProp at myMouseUp. For each other div, this property is undefined. This is why I got some comments indicating that "It does work." It works for ONE, which is all I had in my example. (This is the clarification.)

My workaround is to add a global object to be an associative array and change two statements:

var myDivs = {};    // global

Replace

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

in buildDivs with

myDivs[x.id] = x;

and replace

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

in myMouseUp with

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

I'd still like to know why the original approach doesn't work.

于 2013-08-05T19:25:32.540 回答