直到最近,每当我需要 HTML 中的自定义属性时,我总是使用HTML5 data-* 自定义属性。
最近开始尝试使用WebComponents,特别是自定义元素,我开始考虑自定义属性,这些属性不是HTML5 data-* 自定义属性。
在无意中采用任何不推荐的做法之前,我想澄清以下几点......
在下面的列表中,我们有 4 个元素:
- 元素 i是具有
data-*
属性的标准元素 - 元素 ii是具有自定义属性的标准元素
- 元素 iii是具有
data-*
属性的自定义元素 - 元素 iv是具有自定义属性的自定义元素
const toggleDataAttribute = (e) => {
e.target.dataset.inverted = (e.target.dataset.inverted === 'true') ? 'false' : 'true';
}
const toggleCustomAttribute = (e) => {
if (e.target.getAttribute('inverted') === 'true') {
e.target.setAttribute('inverted', 'false');
}
else {
e.target.setAttribute('inverted', 'true');
}
}
const toggleInvert = (e) => {
if (e.target.dataset.inverted) {
toggleDataAttribute(e);
}
else {
toggleCustomAttribute(e);
}
}
// Attach click event TO <div> elements
let divs = [...document.getElementsByTagName('div')];
divs.forEach((div) => div.addEventListener('click', toggleInvert, false));
// Attach click event TO <my-circle> elements
let myCircles = [...document.getElementsByTagName('my-circle')];
myCircles.forEach((myCircle) => myCircle.addEventListener('click', toggleInvert, false));
// Define <my-circle> element
class myCircle extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.appendChild(document.createElement('slot'));
}
}
customElements.define('my-circle', myCircle);
aside {
position: absolute;
top: 0;
right: 0;
width: 280px;
line-height: 24px;
}
div {
float: left;
margin: 0 12px 12px 0;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
font-size: 36px;
border-radius: 50%;
cursor: pointer;
}
my-circle {
display: block;
float: left;
margin: 0 12px 12px 0;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
font-size: 36px;
background: radial-gradient(#fff, #000);
border-radius: 50%;
cursor: pointer;
}
my-circle:first-of-type {
clear: left;
}
div:nth-of-type(1) {
background: radial-gradient(rgb(255, 255, 0), rgb(255, 0, 0));
}
div:nth-of-type(2) {
background: radial-gradient(rgb(255, 255, 0), rgb(0, 163, 0));
}
my-circle:nth-of-type(1) {
background: radial-gradient(rgb(255, 255, 0), rgb(223, 163, 0));
}
my-circle:nth-of-type(2) {
background: radial-gradient(rgb(255, 127, 127), rgb(255, 0, 0));
}
div[data-inverted="true"],
div[inverted="true"],
my-circle[data-inverted="true"],
my-circle[inverted="true"] {
filter: hue-rotate(180deg);
}
<div data-inverted="false">i</div>
<div inverted="false">ii</div>
<my-circle data-inverted="false">iii</my-circle>
<my-circle inverted="false">iv</my-circle>
<aside>
<p><strong>Click</strong> on each of the circles on the left to invert their backgrounds.</p>
</aside>
尽管上述设置在技术上有效,但以下哪项是正确的:
A)自定义属性可以在标准元素和自定义元素中普遍使用。
- 结论:元素i , ii , iii & iv都是有效的
B)自定义属性只能用于自定义元素。它们在其他地方无效。
- 结论:元素i、iii和iv有效,而ii无效
C) Data-* 属性用于标准元素,自定义属性用于自定义元素。
- 结论:元素i和iv有效,而ii和iii无效
D)自定义属性甚至不是一回事。你是从哪里得到这个想法的?
- 结论:元素i和iii有效,而ii和iv无效
添加:
为了说明我上面的问题,我想举一个自定义属性似乎无效的示例:
选择文本输入
进入:
<!DOCTYPE html>
<html lang="">
<head>
<title>Test</title>
</head>
<body>
<div data-inverted="false">i</div>
<div inverted="false">ii</div>
</body>
</html>
- 检查标记
验证器返回错误:
错误:此时
inverted
元素上不允许使用属性。div
从第 10 行第 1 列开始;到第 10 行第 22 列
i</div>↩↩<div inverted="false">ii</di
虽然......我不确定https://validator.w3.org/nu/上的工具是否已过时和/或被放弃,返回的错误不应再被视为 2020 年的错误(?)