简体   繁体   English

扩展DOM元素以添加自定义变量(例如在输入节点中)

[英]Extending DOM elements adding custom variables (like in input nodes)

What I have: 我有的:

A list of groups that basically consists of main data points: link, name and cover image. 基本上由主要数据点组成的组列表:链接,名称和封面图像。 Each group's code looks like this: 每个组的代码如下:

<a href="/group/ololo" class="group-item">
    <h1>Group Name</h1>
    <img src="path/to/the/image.png" />
</a>

Therefore a.href is the link, h1 consists the name and img.src is the image. 因此,a.href是链接,h1包含名称,img.src是图像。

What I need: 我需要的:

I need to create a model representation of each group, so that I can access it simply with group.link, group.name and group.image. 我需要为每个组创建一个模型表示,以便可以通过group.link,group.name和group.image进行简单访问。

I consider creating a class with constructor and setting all the fields manually and it, actually, works. 我考虑使用构造函数创建一个类并手动设置所有字段,并且它实际上可以工作。 What I want to do is extend the Node class for it to add those fields to the object, if I'm trying to access a.group-item. 我想做的就是扩展Node类,以便在我尝试访问a.group-item时将那些字段添加到对象中。 An example of what I want are special Nodes, like input[type=text], that has a .value variable or input[type=checkbox] that has .checked variable. 我想要的一个示例是特殊节点,例如具有[值]变量的input [type = text]或具有.checked变量的input [type = checkbox]。

How is it possible to extend the Node class that way? 以这种方式如何扩展Node类? Also, I do not want to use any frameworks for that, only pure js. 另外,我不想为此使用任何框架,仅使用纯js。 Thank you! 谢谢!

Is there a specific reason for why you want to extend the DOM? 您为什么要扩展DOM有特定原因吗? If not, you can just define a function that returns the nested attributes that you want: 如果没有,则可以只定义一个函数,该函数返回所需的嵌套属性:

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 http://jsbin.com/xidufiyara/1/edit?html,js,console

Otherwise, here is a post that answers your question about extending the DOM: In Javascript, can you extend the DOM? 否则,这是一篇帖子,回答您有关扩展DOM的问题: 在Javascript中,您可以扩展DOM吗?

Edit: Here's a solution using Object.defineProperty : 编辑:这是使用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
      }
    });
}

Here's how I applied and used the properties: 这是我应用和使用属性的方式:

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)
}

Of course, this won't be compatible with older browsers. 当然,这将与旧版浏览器不兼容。 Another reason why this should be discouraged is because other libraries / javascript plugins could define / manipulate the same properties, so you introduce the possibility of conflicts with other code. 不建议这样做的另一个原因是,其他库/ javascript插件可以定义/操作相同的属性,因此您引入了与其他代码冲突的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM