在WebComponents中的HTML自定义元素中澄清自定义属性的状态

voase2hg  于 2023-03-27  发布在  其他
关注(0)|答案(1)|浏览(159)

直到最近,每当我在HTML中需要自定义属性时,我总是使用HTML data-* custom attribute
最近开始尝试WebComponents,特别是Custom Elements,我已经开始考虑自定义属性,而不是 * HTML5数据-* 自定义属性。
在无意中采用任何不推荐的做法之前,我想澄清以下几点...
在下面的列表中,我们有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)**自定义属性可以在标准元素和自定义元素中通用。

  • 结论:* 元素iiiiiiiv均有效 *
    ***B)**自定义属性只能在自定义元素中使用,其他地方无效。
  • 结论:* 元素iiiiiv有效,ii无效 *
    ***C)*Data- 属性用于标准元素,自定义属性用于自定义元素。
  • 结论:* 元素i&iv有效,ii&iii无效 *
    ***D)**自定义属性根本不是一个东西,你从哪里得到这个想法的?
  • 结论:* 元素i&iii有效,ii&iv无效 *

添加:

为了说明我上面的问题,我想给予一个例子,说明自定义属性在哪里无效:
1.请访问:https://validator.w3.org/nu/#textarea
1.选择文字输入
1.输入:

<!DOCTYPE html>
<html lang="">
<head>
<title>Test</title>
</head>
<body>

<div data-inverted="false">i</div>

<div inverted="false">ii</div>

</body>
</html>

1.检查标记
验证器返回错误:

错误:div元素此时不允许有inverted属性。

第10行第1栏;第10行第22列
i</div>↩↩<div inverted="false">ii</di
虽然......我不确定https://validator.w3.org/nu/上的工具是否已经过时和/或废弃,并且返回的Error在2020年不应再被视为错误(?)

uinbv5nw

uinbv5nw1#

4个用法都有效,为什么它们无效?
data-前缀提供了***额外的***奖励,它们在element.dataset中可用。
--属性就是属性--,在自定义元素API中没有什么特别的,
除了observedAttributes()。是的,你可以在那里使用data-*属性。

备注

class myCircle extends HTMLElement {
  constructor() {
    super();
    this.root = this.attachShadow({mode: "open"});
  }
  connectedCallback() {
    this.root.appendChild(document.createElement('slot'));
  }
}

可以写成:

class myCircle extends HTMLElement {
  constructor() {
    super()
      .attachShadow({mode: "open"})
      .append(document.createElement('slot'));
  }
}

因为super()返回'this'
attachShadow都可以免费设置和返回this.shadowRoot
你没有对appendChild()的返回值做任何事情,所以append()(它可以接受多个参数)就足够了。
另外,还有一个toggleAttribute方法。

相关问题