【问题标题】:Add JavaScript objects into the DOM将 JavaScript 对象添加到 DOM
【发布时间】:2012-08-11 12:08:53
【问题描述】:

我正在寻找一种在不重新定义对象的情况下将 javascript 对象添加到 DOM 的方法。

我创建了一个函数,它将所有对象方法放入一个新对象中,将该对象重新定义为一个新的 DOM 元素,并将所有对象放回它上面,但这并不是我想要的。我需要在不使用任何返回语句的情况下更新对象。

我这里有一个例子:http://jsfiddle.net/y56wS/

function addToDOM(obj) {
    temp = {};
    for (p in obj) {
        temp[p] = obj[p];
    }
    obj = document.createElement('prop');
    document.body.appendChild(obj);
    for (p in temp) {
        obj[p] = temp[p];
    }
    return obj;
}

var obj = {var1:123};
obj = addToDOM(obj);

生成的代码模板应该是这样的:

function addToDOM(obj) {
    //Code for method
    //No return statement
}

var obj = {var1:123};
//No obj=
addToDOM(obj);

要做到这一点,addToDOM 函数中必须没有 obj =,这样它就不会被重新定义,也不需要 return 语句。有没有办法简单地将 javascript 对象扩展到 DOM 上?

【问题讨论】:

  • “我正在寻找一种将 javascript 对象添加到 DOM 的方法” - 让我停下来告诉你 嗯?为什么?显然我完全没有抓住重点,因为将 JS 对象添加到 DOM 的想法对我来说毫无意义。浏览器将如何显示它?如果它不显示它,你为什么要这样做?
  • 很抱歉没有详细说明。我正在尝试创建一个 defineObject getter/setter polyfill(ish) 的东西,这样我的代码就可以在 IE6+ 以及所有其他主要浏览器中运行。许多人都知道,如果对象是 DOM 的一部分,这仅在 IE8 中是可能的,如果它也在 DOM 中,我有一个针对 IE6/7 的解决方法。只要我在定义obj = {} 后调用obj = addToDOM(obj),Object.defineProperty 就可以完美运行。我只是想做它,这样我就可以将addToDOM(obj) 包含在polyfill 中,为此我必须将它添加到DOM 元素而不重新定义它。是不是更清楚了?

标签: javascript javascript-objects dom


【解决方案1】:

不,JavaScript 对象不能像那样添加到文档中 - appendChild() 方法需要特定类型的对象,通常使用 document.createElement() 方法创建。

所以你必须每次都创建新的 DOM 元素,或者克隆现有的元素。

假设你想要某种“模板”元素,我建议使用全局变量来保存该元素,创建一次,然后每次克隆它并放置新属性。

代码如下:

var _globalDOMobj = 0;
function addToDOM(obj) {
    temp = {};
    for (p in obj) {
        temp[p] = obj[p];
    }
    if (!_globalDOMobj) {
        _globalDOMobj = document.createElement('prop');
        _globalDOMobj.className = "myprop";
    }
    obj = _globalDOMobj.cloneNode(true);
    obj.innerHTML = "I am dynamic element";
    document.body.appendChild(obj);
    for (p in temp) {
        obj.setAttribute(p, temp[p]);
    }
    return obj;
}

addToDOM({"var1": "123", "style": "color: red;"});
addToDOM({"var2": "789", "style": "color: blue;"});

如您所见,您可以将对象直接传递给函数,而无需先将其分配给变量。

此外,要在 DOM 元素中应用对象属性,您必须使用 setAttribute() 否则这些属性不会成为 DOM 的一部分。

在上面的代码中,模板对所有实例都有相同的类,所以你可以应用一些 CSS 来影响它们,例如

.myprop { font-weight: bold; }​

​Live test case.

【讨论】:

  • 这段代码并不是我所需要的,但它让我想到了完成这项任务的新方法,这是我以前没有想到的。如果我确实想出办法做到这一点,我会发布它。
  • 干杯,不知道你需要什么,所以如果你想出更好的方法,请更新我。 :)
【解决方案2】:

“将 JS 对象添加到 DOM”的概念确实没有任何意义,实际上您的代码没有这样做,它正在创建一个新的 <prop> 元素和从您的对象中为其分配属性。我不明白这一点:您希望浏览器对 <prop> 元素做什么?

无论如何,继续讨论如何不必从函数返回对象并将其分配回变量的问题,你不能。 JavaScript 按值传递参数 - 在这种情况下,“值”是对对象的引用。您可以更改对象的属性,但不能使传入的变量指向其他对象。 (显然你可以使声明的参数obj 指向其他对象,就像你正在做的那样。)

但这会导致一种可能的解决方法,可能会对您有所帮助:您只需向现有对象添加一个属性,新属性引用 DOM 对象 -

function addToDOM(obj) {
    var temp = document.createElement('prop');
    document.body.appendChild(temp);
    for (var p in obj) {
        temp[p] = obj[p];
    }
    obj.myDOMElement = temp;
}

var obj = {var1:123};
//No obj=
addToDOM(obj);
// obj now has a property myDOMElement that references the DOM element

请注意,我已经稍微简化了您的功能:您不需要将所有 obj 属性复制到 temp 中,然后在将 obj 重新分配给新的 obj 后将所有属性复制回 obj DOM 元素。 (即使您决定保留当前代码返回新对象的想法,您也可以使用我的简化形式,只需 return temp。)

请注意,您应该使用var 声明您的变量,否则它们将是全局的。

【讨论】:

  • 非常好的和深思熟虑的答案。我正在尝试开发适用于 IE6+ 的 getter/setter 方法。只要我在定义 obj 是什么之后包含obj = addToDOM(obj),它们就可以在所有浏览器中使用我的polyfill。由于它们是 getter 和 setter 方法,我必须能够检测对象何时被访问,并且在 IE 6/7/8 中,这只能在对象位于 DOM 中时完成。我想对脚本中的所有事件自动执行此操作,这样就不必在每次应用 getter 或 setter 时都写出来。
猜你喜欢
  • 2010-12-17
  • 2017-04-28
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
相关资源
最近更新 更多