3

我正在为内部包含 DOM 节点并通过额外功能方法增强的表单输入字段制作自定义类包装器。

我的问题是是否有与 .toString() 类似的方法用于附加到 DOM,因为我想直接将我的对象插入 DOM 而不是调用其他方法

在其他作品中,这是我所拥有的示例:

function A () {
  this.element = documenet.createElement('input');
  // blah blah logic
  this.toString = function () {
    return '<input type="'+this.element.type+'" value="'+this.element.value+'" />';
  }
  // a similar method to this i'ld like
  this.toString = function () {
    return this.element;
  }
}

这样我就可以按如下方式使用它:

var a = new A();

// this works as it calls .toString(), but it is a hack and it is not pretty
document.body.innerHTML += a;

// this is what i'd want to be able to do:
document.body.appendChild(a);

// this is what **I AM REALLY TRYING TO AVOID:**
document.body.appendCHild(a.toElement());

您不能简单地从 DOM 节点继承,因为它不是公共类

我试过看其他问题,但似乎没有答案......任何想法都会受到高度欢迎

4

3 回答 3

3

你不能从原生 DOM 构造函数继承,但是你可以从 jQuery 继承你的包装类!

function A () {
    if (!(this instanceof A)) return new A(); // fix wrong constructor invocations
    if (this.length) { // shouldn't be set yet, so another odd invocation:
        var empty = Object.create(A.prototype); // a new, but *empty* instance
        empty.length = 0; // explicitly set length
        return empty;
    }

    this[0] = document.createElement('input');
    …
    // or you might want to call $.fn.init
    this.context = undefined; // not sure whether
    this.selector = ""; // we need those two lines
    this.length = 1; // but the length is obligatory
}
A.prototype = Object.create($.fn, {constructor:{value:A,configurable:true}});
A.prototype.toString = function () {
    return '<input type="'+this[0].type+'" value="'+this[0].value+'" />';
}

有了这个,你可以只是$(document.body).append(new A)new A().appendTo(document.body)等等。

于 2012-12-17T18:30:03.983 回答
1

您可以将其视为工厂方法,而不是将A其视为对象:http: //jsfiddle.net/fnK56/2/

// We can modify ele however we like, even overriding the toString method.
function CustomElement() {
    var ele = document.createElement("input");
    ele.type = "button";
    ele.value = "Testing";
    // do stuff to ele
    ele.CustomProperty = {one:"two", three:"four"}; // we can even add custom properties that will persist with that DOM node. 

    ele.toString = function(){
        return '<input type="'+this.type+'" value="'+this.value+'" />';
    };

    return ele;
}

var tmp = CustomElement(); // get us a new CustomElement

document.body.innerHTML += tmp; // this works because of the overridden toString
tmp.id = "Test";
document.body.appendChild(tmp);​ // this works because tmp is still a DOM input node.

console.log(tmp.CustomProperty); // Object {one: "two", three: "four"} 
console.log(document.getElementById("Test").CustomProperty); // Object {one: "two", three: "four"} 
于 2012-12-17T18:17:53.443 回答
1

这不适用于所有浏览器(请参阅http://www.meekostuff.net/blog/Overriding-DOM-Methods/)以很好地讨论选项,但是:

HTMLElement.prototype._appendChild = HTMLElement.prototype.appendChild;
HTMLElement.prototype.appendChild = function(target)
{
    if(target.toElement)
    {
        this._appendChild(target.toElement());
    }
    else
    {  
        //attempt to do it the old fashioned way
        this._appendChild(target);
    }


}

这使您的语法:

// this is what i'd want to be able to do:
document.body.appendChild(a);

并隐藏了“toElement()”在内部被调用的事实。

我要指出,当您开始达到这种复杂程度时,使用像 jQuery 这样的框架开始变得有意义。

于 2012-12-17T18:19:45.343 回答