document.registerElement 扩展了 HTMLInputElement 原型,同时使用自定义标记名称

document.registerElement extending HTMLInputElement prototype while using custom tag name to avoid implicit browser style

本文关键字:自定义 扩展 registerElement HTMLInputElement 原型 document      更新时间:2023-09-26

我的目标是双重的:

  • 显示一个 HTML 元素,该元素跟踪其"已检查"状态并触发"更改"事件,而无需自己手动实现该代码。

  • 不要与浏览器对元素的隐式样式作斗争,-webkit-appearance: none和更大惊小怪。

我只需要支持谷歌浏览器当前稳定的频道。因此,我不太关心与非现代浏览器的兼容性。

我已经通过使用document.registerElement解决了这个问题。使用此方法,我注册一个新标签 custom-checkbox ,并通知浏览器我希望此标签从输入继承。

从那里,我需要设置此输入的类型为复选框的事实。为此,我在创建 HTML 元素时运行的 createdCallback 方法中设置了其类型。

此代码存在一些问题:

  • 当我不使用自定义标签而是利用 is 属性通知浏览器输入"是"custom-checkbox时,它有效。但是,使用 <input> 标记会导致浏览器接管元素的样式。我不希望这种情况发生。

  • 使用自定义标记时,不会运行 createdCallback 方法。因此,该元素不会设置它是一个复选框的事实,并且在单击时不会触发"更改"事件。

我错过了什么?

var proto = Object.create(HTMLInputElement.prototype);
proto.createdCallback = function() {
  console.log('createdCallback has ran for: ', this);
  this.type = "checkbox";
};
document.registerElement("custom-checkbox", {
  prototype: proto,
  extends: 'input'
});
$('.custom-checkbox').change(function() {
  console.log('change event handler has ran for:', this);
});
.custom-checkbox {
  width: 100px;
  height: 100px;
  background-color: red;
  display: inline-block;
}
<custom-checkbox class="custom-checkbox"></custom-checkbox>
<input is='custom-checkbox' class="custom-checkbox">

我可以复制您的问题,即在使用HTML声明的页面上插入<custom-element>标签时,createdCallback方法不会触发。我使用的是 Chrome 版本 39.0.2171.99

我相信这是因为当我的<custom-element>被渲染时,事件侦听器createCallback没有绑定。

请记住,自定义元素还不是定义的标准(请参阅此处(

但是,使用 Polymer 为我解决了这个问题,在 HTML 中使用自定义标签确实触发了 Polymer 所说的create事件/回调。

我建议你使用聚合物,它有更好的浏览器支持。