Javascript 扩展DIV元素时如何生成多个元素?
我试图通过使用新创建的DIV作为对象的原型,通过Javascript“扩展”DIV 根据我对Javascript的理解,在通过“new”创建我的对象的新实例时,原型对象被复制,分配给“this”,然后函数被执行(作为构造函数) 一切似乎都正常,除了每当我创建另一个对象并将其添加到DOM中时,它就会“替换”原始div。更确切地说:构造函数总是更改相同的div 使用Javascript 扩展DIV元素时如何生成多个元素?,javascript,oop,Javascript,Oop,我试图通过使用新创建的DIV作为对象的原型,通过Javascript“扩展”DIV 根据我对Javascript的理解,在通过“new”创建我的对象的新实例时,原型对象被复制,分配给“this”,然后函数被执行(作为构造函数) 一切似乎都正常,除了每当我创建另一个对象并将其添加到DOM中时,它就会“替换”原始div。更确切地说:构造函数总是更改相同的div 使用MyTest.prototype=document.createElement(“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似乎没有被复制,它的行为类似于单态或单态。不应该这样吗
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();
}
);