Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 扩展DIV元素时如何生成多个元素?_Javascript_Oop - Fatal编程技术网

Javascript 扩展DIV元素时如何生成多个元素?

Javascript 扩展DIV元素时如何生成多个元素?,javascript,oop,Javascript,Oop,我试图通过使用新创建的DIV作为对象的原型,通过Javascript“扩展”DIV 根据我对Javascript的理解,在通过“new”创建我的对象的新实例时,原型对象被复制,分配给“this”,然后函数被执行(作为构造函数) 一切似乎都正常,除了每当我创建另一个对象并将其添加到DOM中时,它就会“替换”原始div。更确切地说:构造函数总是更改相同的div 使用MyTest.prototype=document.createElement(“div”)给出了所描述的行为,在我的代码示例中,这之后

我试图通过使用新创建的DIV作为对象的原型,通过Javascript“扩展”DIV

根据我对Javascript的理解,在通过“new”创建我的对象的新实例时,原型对象被复制,分配给“this”,然后函数被执行(作为构造函数)

一切似乎都正常,除了每当我创建另一个对象并将其添加到DOM中时,它就会“替换”原始div。更确切地说:构造函数总是更改相同的div

使用
MyTest.prototype=document.createElement(“div”)
给出了所描述的行为,在我的代码示例中,这之后的两行注释行也是我尝试过的,但都没有用

我知道尝试扩展DOM是不受欢迎的,但我想了解这种行为,因为我认为我知道原型是如何工作的,这根本不符合我的想法

以下是我尝试做的一个简单示例:

<!DOCTYPE html>
<html>
<head>
<title>Div-Prototype-Test</title>
<script type="text/javascript">

var height = 20;
var top = 0;

function MyTest() {
    var r = Math.floor(Math.random() * 256);
    var g = Math.floor(Math.random() * 256);
    var b = Math.floor(Math.random() * 256);

    this.style.backgroundColor = "rgb("+ r +","+ g +","+ b +")";
    this.style.position        = "absolute";
    this.style.width           = "500px";
    this.style.height          = height + "px";
    this.style.top             = top + "px";

    top += height;

    document.getElementsByTagName("body")[0].appendChild(this);
}

MyTest.prototype = document.createElement("div");
// MyTest.prototype = document.createElement("div").cloneNode(true);
// MyTest.prototype = new Element();

window.addEventListener(
    "load", 
    function() {
        var a = new MyTest();
        var b = new MyTest();
        var c = new MyTest();
        var d = new MyTest();
    }
);

</script>
</head>
<body>
</body>
</html>
警报接着说:

A1 : 4
A1 : 15
A2 : 4
然而,我的第一个示例中的Div似乎没有被复制,它的行为类似于单态或单态。不应该这样吗

  • 将Protype对象复制到新对象中
  • 新对象被指定给“this”
  • 这是给构造函数的
  • 这是由构造函数返回的(如果未指定return语句)
  • 这一行只执行一次。它创建一个
    MyTest.prototype
    对象,它也是一个DOM元素
    。每个
    MyTest
    对象都将收到相同的原型。因此,您创建的每个
    MyTest
    对象将仅与您创建的单个
    关联一次。您必须为每个
    MyTest
    创建一个新的

    尝试以下模式:

    MyTest = function() {
        var myDiv = document.createElement("div");
    
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
    
        myDiv.style.backgroundColor = "rgb("+ r +","+ g +","+ b +")";
        myDiv.style.position        = "absolute";
        myDiv.style.width           = "500px";
        myDiv.style.height          = height + "px";
        myDiv.style.top             = top + "px";
    
        top += height;
    
        document.getElementsByTagName("body")[0].appendChild(myDiv);
    
        return myDiv;
    }
    
    此函数使用
    createElement()
    调用创建一个新的
    。然后,它将设置新的
    上所需的所有属性。最后,它返回新的
    。因此,你可以称之为

    var myNewDiv = MyTest();
    var myNewDiv = new MyTest();
    

    两种选择都可行。在第二种情况下,通过
    new
    关键字创建一个虚拟的新对象,但这并不重要,因为在函数中创建的新
    实际上是返回的。

    您在混合各种东西。首先,检查我的答案。其次,可以扩展
    元素
    对象,但并非所有浏览器都支持它。检查

    在我看来,您正计划以某种标准化的方式向
    文档添加元素。您的代码可以重写为(我稍微修改了一下):

    现在,您可以使用`appendElement将任何元素追加到
    文档中,如下所示:

    appendElement.call(document.createElement('div'),'empty div');
    appendElement.call(document.createElement('span'),'new empty span','span1');
    

    这是您的目标吗?

    我找到了一个解决方法,它基本上是反过来工作的-原型是一个空白对象,我将新对象数据复制到构造函数中的一个div中:

    var height = 20;
    var top = 0;
    
    function deepCopy(fromObject, toObject, depth) {
        if(typeof(fromObject) != "object" || typeof(toObject) != "object") {
            // throw "deepCopy only copies objects"
            return;
        }
    
        if (typeof(depth) == "undefined") {
            depth = 0;
        } else if (depth > 100) {
            // Recursion depth too high. Abort.
            // throw "deepCopy recursion depth cap hit"
            return;
        }
    
        for (var key in fromObject) {
            if (typeof(fromObject[key]) == "object" && fromObject[key] != null) {
                if (typeof(fromObject[key].nodeType) != "undefined") {
                    toObject[key] = fromObject[key].cloneNode(true);
                } else {
                    if (typeof(toObject[key]) != "object") {
                        toObject[key] = {};
                    }
                    deepCopy(fromObject[key], toObject[key], depth + 1);
                }           
    
            }
            toObject[key] = fromObject[key];
        }
    }    
    
    function MyTest() {
        // This is ugly...
        var self = document.createElement("div");
        deepCopy(MyTest.prototype, self);
    
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
    
        self.style.backgroundColor = "rgb("+ r +","+ g +","+ b +")";
        self.style.position        = "absolute";
        self.style.width           = "500px";
        self.style.height          = height + "px";
        self.style.top             = top + "px";
    
        top += height;
    
        document.getElementsByTagName("body")[0].appendChild(self);
    
        return self;
    }
    
    MyTest.prototype = {};
    // MyTest.prototype = document.createElement("div").cloneNode(true);
    // MyTest.prototype = new Element();
    
    window.addEventListener(
        "load", 
        function() {
            var a = new MyTest();
            var b = new MyTest();
            var c = new MyTest();
            var d = new MyTest();
        }
    );
    
    虽然我觉得我的deepCopy函数是执行任务的一种相当不雅观(可能是非常有缺陷)的方法,但使用cloneNode()的另一种方法却不起作用

    我最初的问题是:复制原型时,所有标量值都被复制,而所有对象都被简单引用(就像复制指针一样,指针值被复制,但它指向的数据不被复制)。


    希望这对其他人有所帮助。

    这就是我不理解的:当我使用不同的对象作为原型时,它及其属性会被复制。当我更改其中一个属性时,它不会更改原始原型的属性,对吗?它们不是复制的。如果在
    MyTest.prototype
    中有一个属性,例如,
    x
    ,并且您有
    var test=new MyTest();测试x='abc'
    然后您实际上向
    test
    对象添加一个新的
    x
    属性,并在原型中隐藏
    x
    属性。但是,在代码中,并没有向每个对象添加新属性。所有实例都引用
    style
    属性,该属性仍在原型中,属于您创建的一个div。但是为什么这一原则不适用于我的第二个示例?(这是我在你写下答案后加上的)我在问答中加了1-原型有时非常混乱…@sirion,因为当你调用
    x1.set(15)
    ,它执行
    set()函数中的代码:
    this.property=num
    使用
    x1
    作为
    this
    15
    作为
    num
    ,因此它使用
    x1.property=15。这在对象
    x1
    内创建了一个名为
    property
    的新属性。因此发生的情况是:
    x1。属性
    在对象
    x1
    中找到,值为
    15
    x2。在对象
    x2
    中找不到属性
    ,因此查找将继续到原型中。在那里,它的值是
    4
    。实际上,我最初的想法是向DOM中添加具有附加功能的元素(我现在只想了解它为什么不起作用)。像
    xxx.appendChild(新的FadeDiv(urlList)),URL列表是图像URL的数组。然后将图像加载到背景中,并从一个图像淡入另一个图像。这个想法是,它应该像任何其他div一样可用。
    
    function appendElement(content,id) {
        var rgb = 'rgb('+ [Math.floor(Math.random() * 256),
                   Math.floor(Math.random() * 256),
                   Math.floor(Math.random() * 256)].join(',') +')';
        var top  = Math.floor( Math.random() * 300 + 20 );
        var left = Math.floor( Math.random() * 100 + 10 );
    
        this.style.backgroundColor = rgb;
        this.style.position        = "absolute";
        this.style.width           = "500px";
        this.style.height          = "200px";
        this.style.left            = left+"px";
        this.style.top             = top+"px";
        this.innerHTML             = content || '';
        this.id                    = id || Math.Random*10000+1
        document.getElementsByTagName("body")[0].appendChild(this);
    }
    
    appendElement.call(document.createElement('div'),'empty div');
    appendElement.call(document.createElement('span'),'new empty span','span1');
    
    var height = 20;
    var top = 0;
    
    function deepCopy(fromObject, toObject, depth) {
        if(typeof(fromObject) != "object" || typeof(toObject) != "object") {
            // throw "deepCopy only copies objects"
            return;
        }
    
        if (typeof(depth) == "undefined") {
            depth = 0;
        } else if (depth > 100) {
            // Recursion depth too high. Abort.
            // throw "deepCopy recursion depth cap hit"
            return;
        }
    
        for (var key in fromObject) {
            if (typeof(fromObject[key]) == "object" && fromObject[key] != null) {
                if (typeof(fromObject[key].nodeType) != "undefined") {
                    toObject[key] = fromObject[key].cloneNode(true);
                } else {
                    if (typeof(toObject[key]) != "object") {
                        toObject[key] = {};
                    }
                    deepCopy(fromObject[key], toObject[key], depth + 1);
                }           
    
            }
            toObject[key] = fromObject[key];
        }
    }    
    
    function MyTest() {
        // This is ugly...
        var self = document.createElement("div");
        deepCopy(MyTest.prototype, self);
    
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
    
        self.style.backgroundColor = "rgb("+ r +","+ g +","+ b +")";
        self.style.position        = "absolute";
        self.style.width           = "500px";
        self.style.height          = height + "px";
        self.style.top             = top + "px";
    
        top += height;
    
        document.getElementsByTagName("body")[0].appendChild(self);
    
        return self;
    }
    
    MyTest.prototype = {};
    // MyTest.prototype = document.createElement("div").cloneNode(true);
    // MyTest.prototype = new Element();
    
    window.addEventListener(
        "load", 
        function() {
            var a = new MyTest();
            var b = new MyTest();
            var c = new MyTest();
            var d = new MyTest();
        }
    );