我有什么:
基本上由主要数据点组成的组列表:链接,名称和封面图像。每个组的代码如下所示:
<a href="/group/ololo" class="group-item">
<h1>Group Name</h1>
<img src="path/to/the/image.png" />
</a>
因此a.href是链接,h1包含名称,img.src是图像。
我需要什么:
我需要创建每个组的模型表示,以便我可以使用group.link,group.name和group.image简单地访问它。
我考虑使用构造函数创建一个类并手动设置所有字段,实际上它可以工作。我想要做的是扩展Node类,以便在我尝试访问a.group-item时将这些字段添加到对象中。我想要的一个例子是特殊节点,例如input [type = text],它有一个.value变量或输入[type = checkbox],它有.checked变量。
如何以这种方式扩展Node类?此外,我不想使用任何框架,只有纯js。谢谢!
答案 0 :(得分:1)
是否有特定原因要求您扩展DOM?如果没有,您可以定义一个返回所需嵌套属性的函数:
var group = document.getElementsByClassName('group-item');
var items = Array.prototype.map.call(group, item);
function item(element) {
return {
link: element.href,
name: element.getElementsByTagName('h1')[0].innerText,
image: element.getElementsByTagName('img')[0].src
};
}
http://jsbin.com/xidufiyara/1/edit?html,js,console
否则,这是一篇文章,回答了有关扩展DOM的问题:In Javascript, can you extend the DOM?
编辑:以下是使用Object.defineProperty
的解决方案:
function configureGroupItem(groupItem) {
Object.defineProperty(groupItem, 'link', {
enumerable: true,
get: function() {
return groupItem.href;
}
});
Object.defineProperty(groupItem, 'name', {
enumerable: true,
get: function() {
return groupItem.getElementsByTagName('h1')[0].innerText;
},
set: function(val) {
groupItem.getElementsByTagName('h1')[0].innerText = val
}
});
Object.defineProperty(groupItem, 'image', {
enumerable: true,
get: function() {
return groupItem.getElementsByTagName('img')[0].src;
},
set: function(val) {
groupItem.getElementsByTagName('img')[0].src = val
}
});
}
以下是我应用和使用属性的方法:
var group = document.getElementsByClassName('group-item');
Array.prototype.map.call(group, configureGroupItem);
for (var i = 0; i < group.length; ++i) {
var item = group[i]
// set item name
item.name = 'Group' + i
// set item image
item.image = 'http://placehold.it/' + (i+4) + '0x' + (i+2) + '0'
// print the data
console.log(item.name + ' ' + item.image + ' ' + item.link)
}
当然,这与旧版浏览器不兼容。不鼓励这样做的另一个原因是因为其他库/ javascript插件可以定义/操作相同的属性,所以你引入了与其他代码冲突的可能性。