使用属性仅仅为了标记HTML元素是一种好的做法吗?

6

我对使用Javascript编写HTML的良好实践有疑问。

我想到了一个想法(可能不是第一个,但找不到明确的参考),将某些元素标记为候选项,在数据可用时(经过某些用户交互)加载一些数据。让我举个例子:

假设我有一个请求,返回以下内容:

GET    /animals/dog

{
  name: "Gutemberg",
  race: "doberman",
  age: "2y"
}

我编写的代码将响应中的字段绑定到可能加载此值的元素上。 例如:使用上述请求,我可以使用以下标记:
<input name="dog-name-field" data-load-dog-name type="text"/>
<input name="dog-age-hid" data-load-dog-age type="hidden"/>

每个标签都会接收属性值,因为它被标记为可以这样做的候选者 - 当所有内容执行时,`dog-name-field` 的值将为 "Gutemberg"。每次重新加载请求时都会发生这种情况。目前,我只是获得了我搜索的数据类型(“狗”),将其与属性“名称/年龄”连接起来形成属性`data-load-type-property`并为具有此类属性的每个人设置一个值。
我有一种感觉,属性不应该仅仅像这样使用,但我不知道任何真正的缺点。由于我找不到这种方法的明确名称,所以我想要一些指导。
这种技术有名称吗? 是否是一种不好的做法? 如果是,为什么?
附言: 为了遵守 SO 的良好实践,如果可能的话,我希望答案是基于参考文献而不仅仅是基于意见。如果没有提供参考,请让我们有一个坚实、描述清楚的例子。

通常,如果是针对单个元素,则使用id属性,如果是针对多个元素,则使用class属性。 - Tonlage
相关:https://dev59.com/62Qm5IYBdhLWcg3w-jBL - Andrea Casaccia
我认为你的方法没有问题,假设你需要保持身份验证方法的动态性。 - Rory McCrossan
使用id或类。属性是其中最慢的。 Id比3快得多。如果您想保持这种方式,请设置一个类似于myval="xxx"的属性。 - cpugourou
2个回答

1
这被称为“绑定”。有时是数据绑定,有时是模板绑定。
各种框架都提供了机制来实现这一点,尽管语法有所不同。 AngularJS 示例:
<input ng-model="dog.name" />

Knockout示例:

<input data-bind="textInput: dog.name" />

React示例:

<input value={this.state.dog.name} />

这些都是相当流行的框架/库,因此我认为可以肯定地说这不被视为不良实践。与您的方法主要区别在于它们使用属性值来指定对模型的引用(即您属性中的“dog.name”部分),而您将引用放在属性名称中。实际上,这主要是风格问题。将引用与“标记”(即“data-load”)分开可能更易读一些。

在HTML中使用属性本身不会创建任何绑定,因此说“这被称为绑定”是不正确的。 - charlietfl
如果您使用我提到的框架或编写代码来查找和处理属性,就会有用,就像D. Melo所做的那样。 - Supr

1
我有一种感觉,属性并不是用来随便使用的。 让我们看看自定义数据属性的用途: 自定义数据属性旨在存储页面或应用程序私有的自定义数据,这些数据没有更合适的属性或元素可用。这些属性不适用于独立于使用属性的站点的软件。 (来自w3.org) 因此,在您的情况下,使用数据属性是否“合适”取决于您的需求:如果DOM API没有提供更好的属性来执行此操作,则合适。 如果您只需要选择某些元素以更改textContent,则有两个更合适/更简单的选项: 1)如果您的元素在文档中是唯一的,则使用id属性

id 全局属性定义了一个唯一的标识符(ID),在整个文档中必须是唯一的。它的目的是在链接(使用片段标识符)、脚本或样式(使用CSS)时标识元素。

(来自MDN上的id)

2) 如果您的元素将在文档中的多个实例中使用,请使用 class 属性

class 全局属性是元素类的一个以空格分隔的列表。类允许CSS和Javascript通过类选择器或像DOM方法document.getElementsByClassName这样的函数选择和访问特定的元素。

(来自MDN上的class)

正如@Supr在他的回答中所说,你正在进行的是一个非常简单的数据绑定实现。 数据绑定可能涉及比你目前做的更复杂的内容;例如,你可能想要:
  • 将UI与代表业务模型的Javascript对象保持同步,而不是直接注入来自Ajax调用的数据,

  • 更新其他属性(值、样式),而不仅仅是innerHTML或textContent,

  • 在UI发生变化时更新你的业务模型(双向数据绑定

为了实现所有这些功能,简单的idclass选择器是不够的,这就是为什么实现数据绑定的框架,如KnockoutJS或AngularJS,使用更灵活的data-*属性的原因(AngularJS实际上使用自己的ng-*属性,但允许使用替代的data-ng-*语法以使用HTML验证工具)。

数据属性允许描述更复杂的绑定关系:
<input data-bind="visible: editing, value: name, hasFocus: editing" />

请查看KnockoutJS文档以了解上述代码的含义,虽然与本示例无关,但请想象使用classid来描述它将不太方便。

简而言之

如果您不打算实现更复杂的功能,可能希望改用classid


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接