为什么我的HTML构造函数对象返回[object Object]而不是[HTMLElementElement]?

时间:2014-03-26 01:29:57

标签: javascript html object constructor return-type

背景

我试图创建一个完全纯粹的JavaScript GUI来创建用于学习目的的HTML内容。文件中唯一真正的html是一个<script></script>元素。我想,我差不多完成了。

我制作了一个自定义HTML元素构造函数,但是当我创建一个对象时,[object Object]显示[object HTMLWhateverElement]而不是alert(whatever);(参见下面的示例)。我认为,当两者都是由构造函数构成时,我阻止我将子元素附加到父元素。

主要问题

如果我可以将HTML实例附加到HTML标记element实例,那么我会非常高兴。

构造

function element(tagName) {
    var element = document.createElement(tagName);

    this.setText = function(elementText) {
        if(element.childNodes.length < 1) {
            var text = document.createTextNode(elementText);
            element.appendChild(text);
        } else {
            element.childNodes[0].nodeValue = elementText;
        }
    }

    this.removeText = function() {
        element.removeChild(element.childNodes[0]);
    }

    this.setAttribute = function(attribute,value) {
        element.setAttribute(attribute,value);
    }

    this.removeAttribute = function(attribute) {
        element.removeAttribute(attribute);
    }

    this.appendTo = function(parent) { // Works but not on element instances of the constructor
        parent.appendChild(element);
    }

    this.details = function(){
        alert(
            "Type: " + element + 
            "\n\"typeof\": " + typeof(element) // Shouldn't need this right?
        );
    }
}

实施例

ul = new element("ul");
ul.appendTo(body); // works fine if BODY is actually an HTML tag

alert(body); // gives me [object HTMLBodyElement] :)
alert(ul); // gives me [object Object] >(

li = new element("li"); // works :)
li.setText("list item text"); // works :)
li.appendTo(ul); // doesn't work >(

如果我能弄清楚如何将JavaScript创建的(子)element附加到其他JavaScript创建的(父)element,我就是金色的。我认为它与构造函数生成的实例化元素的返回值有关。

修改

1)可能的答案

@ carter-sand谢谢。 添加新的this.appendChild方法可以工作但重新发明轮子 HTML对象的内置在appendChild方法中。

2)可能的答案

@ s4mok感谢提示。 将var element更改为this.elem有效,但会创建一个 时髦的界面:

li.appendTo(ul.elem); 

VS。

li.appendTo(ul);

我试图模仿私人会员。

两个答案都有效,但都没有返回值[对象 HTMLWhateverElement]当我这样做时:

alert(li);

有没有办法获得上述所有好处?

3 个答案:

答案 0 :(得分:3)

ul = new element("ul");

上面一行是实例化函数element(),分配给ul的实例是对象而不是HTMLWhateverElement

ul.appendTo(body); // works fine if BODY is actually an HTML tag

上述方法有效,因为您的代码是:

this.appendTo = function(parent) { // Works but not on element instances of the constructor
    parent.appendChild(element);
}

而父级是 body 和HMTL元素,并且有一个方法appendChild,而你要追加的元素是这一行的元素:

var element = document.createElement(tagName);

为什么以下代码不起作用?

li = new element("li"); // works :)
li.setText("list item text"); // works :)
li.appendTo(li); // doesn't work >(

答案就是首先 li 不是HTML元素代码

this.appendTo = function(parent) { // Works but not on element instances of the constructor
    parent.appendChild(element);
}

将失败,因为实例 li 不是html元素,而是函数元素的对象实例()

此代码中的另一个错误是你有一个循环li.appendTo(li);如果你检查你的代码,那么你就像孩子一样追求自己。像悖论或循环依赖的东西。

修改

我的建议:

  • 首先,可能会更改函数元素中“元素”的名称以避免混淆。 :d
  • 公开 var element = document.createElement(tagName); ,以便您可以从方法 appendTo 的参数 parent 访问它这将允许您使用parent.getTheExposedElement()。appendChild()

答案 1 :(得分:2)

当使用“new”关键字创建时,您的函数返回自身[object Object]的实例。您可以通过专门返回元素来覆盖它。但是,您需要将“this”更改为您的元素,因为“this”指的是函数新实例。同样如果你将“元素”更改为“newElement”等其他内容,可能会减少混淆。

function element(tagName) {
    var element = document.createElement(tagName);

    element.setText = function(elementText) {
        if(element.childNodes.length < 1) {
            var text = document.createTextNode(elementText);
            element.appendChild(text);
        } else {
            element.childNodes[0].nodeValue = elementText;
        }
    }

    element.removeText = function() {
        element.removeChild(element.childNodes[0]);
    }

    element.setAttribute = function(attribute,value) {
        element.setAttribute(attribute,value);
    }

    element.removeAttribute = function(attribute) {
        element.removeAttribute(attribute);
    }

    element.appendTo = function(parent) { // Works but not on element instances of the constructor
        parent.appendChild(element);
    }

    element.details = function(){
        alert(
            "Type: " + element + 
            "\n\"typeof\": " + typeof(element) // Shouldn't need this right?
        );
    }
    return element;
}


ul = new element("ul");
ul.appendTo(document.body); // works fine if BODY is actually an HTML tag

alert(document.body); 
alert(ul); 

li = new element("li");
li.setText("list item text"); 
li.appendTo(ul); 

答案 2 :(得分:1)

如果我运行您的示例,我会在控制台中注意到以下错误消息:

Uncaught TypeError: Object #<element> has no method 'appendChild'

这是因为您的自定义element实例没有您在appendChild中使用的appendTo方法。您需要在构造函数中添加一个,如下所示:

this.appendChild = function(child) {
    element.appendChild(child);
}