扩展 DOM 元素添加自定义变量(如在输入节点中)
Extending DOM elements adding custom variables (like in input nodes)
我有:
基本由主要数据点组成的组列表:link、名称和封面图像。每个组的代码如下所示:
<a href="/group/ololo" class="group-item">
<h1>Group Name</h1>
<img src="path/to/the/image.png" />
</a>
因此a.href是link,h1是名字,img.src是图片。
我需要的:
我需要为每个组创建一个模型表示,以便我可以简单地使用 group.link、group.name 和 group.image 访问它。
我考虑用构造函数创建一个 class 并手动设置所有字段,它实际上可以工作。我想要做的是扩展节点 class 以将这些字段添加到对象,如果我正在尝试访问 a.group-item。我想要的一个示例是特殊节点,例如具有 .value 变量的 input[type=text] 或具有 .checked 变量的 input[type=checkbox]。
如何以这种方式扩展节点 class?另外,我不想为此使用任何框架,只使用纯 js。谢谢!
您想延长 DOM 有什么具体原因吗?如果没有,您可以只定义一个函数,该函数 returns 您想要的嵌套属性:
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
否则,这里有一个 post 可以回答您关于扩展 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 插件可以定义/操作相同的属性,所以你引入了与其他代码冲突的可能性。
我有:
基本由主要数据点组成的组列表:link、名称和封面图像。每个组的代码如下所示:
<a href="/group/ololo" class="group-item">
<h1>Group Name</h1>
<img src="path/to/the/image.png" />
</a>
因此a.href是link,h1是名字,img.src是图片。
我需要的:
我需要为每个组创建一个模型表示,以便我可以简单地使用 group.link、group.name 和 group.image 访问它。
我考虑用构造函数创建一个 class 并手动设置所有字段,它实际上可以工作。我想要做的是扩展节点 class 以将这些字段添加到对象,如果我正在尝试访问 a.group-item。我想要的一个示例是特殊节点,例如具有 .value 变量的 input[type=text] 或具有 .checked 变量的 input[type=checkbox]。
如何以这种方式扩展节点 class?另外,我不想为此使用任何框架,只使用纯 js。谢谢!
您想延长 DOM 有什么具体原因吗?如果没有,您可以只定义一个函数,该函数 returns 您想要的嵌套属性:
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
否则,这里有一个 post 可以回答您关于扩展 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 插件可以定义/操作相同的属性,所以你引入了与其他代码冲突的可能性。