扩展 DIV 元素时如何制作多个元素
How can I make several Elements when extending a DIV-Element?
我正在尝试通过使用新创建的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>
PS:由于某个Javascript框架,我在Javascript中搜索任何更改原型的内容总是导致数百个与我的问题无关的结果 - 如果我错过了一个已经讨论过这个问题的问题,请告诉我。
编辑:
为了使我的问题更清楚:
下面是一个我使用对象作为原型的示例 - 它的属性被复制。
function A() {
}
A.prototype = { property: 4 };
A.prototype.set = function(num) {
this.property = num;
}
window.addEventListener(
"load",
function() {
var message = "";
var x1 = new A();
message += "A1 : "+ x1.property +"'n";
x1.set(15);
message += "A1 : "+ x1.property +"'n";
var x2 = new A();
message += "A2 : "+ x2.property +"'n";
alert(message);
}
);
警报接着说:
A1 : 4
A1 : 15
A2 : 4
然而,我的第一个示例中的 Div 似乎没有被复制,它的行为类似于单例或单状态。不应该是这样的吗?
- 将 Protype 对象复制到新对象中
- 新对象被分配给"this"
- 这是提供给构造函数的
- 这由构造函数返回(如果未指定 return 语句)
MyTest.prototype = document.createElement("div");
此行仅执行一次。它创建一个MyTest.prototype
对象,该对象也是 DOM 元素<div>
。每 MyTest
对象将收到相同的原型。因此,您创建的每个MyTest
对象都将与您仅创建一次的单个<div>
相关联。您必须为每个MyTest
创建一个新<div>
。
试试这个模式:
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()
调用创建一个新的<div>
。然后,它会在该新<div>
上设置所需的所有属性。最后,它返回您的新<div>
。因此,您可以将其称为
var myNewDiv = MyTest();
var myNewDiv = new MyTest();
这两种选择都有效。在第二种情况下,new
关键字会创建一个虚拟的新对象,但这并不重要,因为在函数中创建的新<div>
实际上是返回的。
你正在混合各种东西。首先,检查我对这个SO问题的回答。其次,可以扩展Element
对象,但并非所有浏览器都支持。检查这个SO问题。
在我看来,您正计划以某种标准化的方式向document
添加元素。您的代码可以重写为(我对其进行了一点修改):
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将任何元素附加到document
,如下所示:
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()的方式不起作用。
我最初的问题来自这个:当复制原型时,所有标量值都被复制,而所有对象都被简单地引用(就像复制指针一样,指针值是重复的,但不是它指向的数据)。
希望这对某人有所帮助。
- 将列表元素动画制作到顶部
- 动画制作/减缓元素填充移除元素留下的空间
- 如何制作链接到网页特定元素的桌面快捷方式
- 制作一个chrome扩展,替换css和js元素
- 制作 JavaScript 代码适用于任何元素
- 制作没有子元素的D3气泡图
- RaphaelJS:如何制作一个又一个元素的动画
- 什么'这是ES6中制作重复元素列表的等效方法
- 为滚动元素制作动画
- 如何为动画持续时间较短的元素制作连续动画's[GASP]
- Android默认浏览器:谷歌地图制作“;位置:相对;元素在页面顶部滚动
- 制作AngularJS路线之间的英雄元素动画
- 如何在CSS中制作ghost元素
- 如何使用javascript从网页中删除HTML元素?(试图制作镀铬扩展)
- 制作元素移动的动画
- 如何制作此元素的数组
- 如何在使用 fancybox 时从这个 span 元素制作一个 javascript 变量
- Javascript以可变的角度和速度为元素移动制作动画
- 使用Jquery将元素动画制作到窗口的右边缘
- 如何使用jQuery在容器中的元素之间制作动画