未捕获的 DOMException:无法在 'CustomElementRegistry' 上执行 'define':“[object HTMLElement]”不是有效的自定义元素名称

Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': "[object HTMLElement]" is not a valid custom element name

请帮助我,我不明白到底是什么导致了错误。代码:-

class button extends HTMLElement{
    constructor(){
        super();
        const shadow = this.attachShadow({mode: 'open'});
        const button = document.createElement('button');
        button.style.cssText = 'display:block';
        button.textContent = super.textContent;
        shadow.appendChild(button);
    }
}
var Ω = (function () {

 'use strict';

 /**
  * Create the constructor
  * @param {String} selector The selector to use
  */
 var Constructor = function (selector) {
  if (!selector) return;
  if (selector === 'document') {
   this.elems = [document];
  } else if (selector === 'window') {
   this.elems = [window];
  } else {
   this.elems = document.querySelectorAll(selector);
  }
 };

    /**
  * Run a callback on each item
  * @param  {Function} callback The callback function to run
  */
 Constructor.prototype.each = function (callback) {
  if (!callback || typeof callback !== 'function') return;
  for (var i = 0; i < this.elems.length; i++) {
   callback(this.elems[i], i);
  }
  return this;
 };

 /**
  * 
  * @param  {String} className 
  */
 Constructor.prototype.register = function (className) {
  this.each(function (item) {
   customElements.define(item, className);
  });
  return this;
 };
    /**
  * Instantiate a new constructor
  */
 var instantiate = function (selector) {
  return new Constructor(selector);
 };

 /**
  * Return the constructor instantiation
  */
 return instantiate;

})();
Ω('lol-foo').register(button);
<p>Expect a button down below</p>
<lol-foo>Hey</lol-foo>
原以为它会从第一个方法中获取名称(这里是 lol-foo),并将添加 class 路径并定义它,但似乎写出了错误并传递了 [object HTMLElement]。

您的帮助将有助于 custags.js 添加选择器,例如 jQuery($)。 感谢回答。

问题是因为您向 define() 的第一个参数提供了 HTMLElement 对象,而它期望自定义元素 name 作为字符串。作为参考,此名称必须包含一个连字符,并且是小写的。因此试试这个:

customElements.define(item.tagName.toLowerCase(), className);

这是一个工作示例:

class button extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({
      mode: 'open'
    });
    const button = document.createElement('button');
    button.style.cssText = 'display:block';
    button.textContent = super.textContent;
    shadow.appendChild(button);
  }
}
var Ω = (function() {
  'use strict';

  /**
   * Create the constructor
   * @param {String} selector The selector to use
   */
  var Constructor = function(selector) {
    if (!selector) return;
    if (selector === 'document') {
      this.elems = [document];
    } else if (selector === 'window') {
      this.elems = [window];
    } else {
      this.elems = document.querySelectorAll(selector);
    }
  };

  /**
   * Run a callback on each item
   * @param  {Function} callback The callback function to run
   */
  Constructor.prototype.each = function(callback) {
    if (!callback || typeof callback !== 'function') return;
    for (var i = 0; i < this.elems.length; i++) {
      callback(this.elems[i], i);
    }
    return this;
  };

  /**
   * 
   * @param  {String} className 
   */
  Constructor.prototype.register = function(className) {
    this.each(function(item) {
      customElements.define(item.tagName.toLowerCase(), className);
    });
    return this;
  };
  /**
   * Instantiate a new constructor
   */
  var instantiate = function(selector) {
    return new Constructor(selector);
  };

  /**
   * Return the constructor instantiation
   */
  return instantiate;
})();

Ω('lol-foo').register(button);
<p>Expect a button down below</p>
<lol-foo>Hey</lol-foo>

还值得注意的是,define() 的第二个参数是 class 构造函数,因此 className 的参数名称用词不当。不过,它的值在此示例中是正确的。

您可以在 CustomElementRegistry.define() at MDN

上找到更多信息