【问题标题】:How to Instantiate new HTMLElement?如何实例化新的 HTMLElement?
【发布时间】:2014-10-06 16:05:17
【问题描述】:

我正在尝试在 TypeScript 中实例化新的 HTMLDivElement

var elem = new HTMLDivElement();

但是浏览器会抛出

Uncaught TypeError: Illegal constructor.

解决方法似乎是使用

var elem = document.createElement('div');

但由于各种原因,我发现这不是最理想的。

lib.d.ts中有new关键字,为什么我不能直接实例化DOM元素?

declare var HTMLDivElement: {
    prototype: HTMLDivElement;
    new (): HTMLDivElement;
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    请注意,您在这里得到的错误是“非法构造函数”。这与您在编写 new {}() 时会得到的错误“对象不是函数”不同。

    所以,从技术上讲,HTMLDivElement确实有一个构造函数。只是这个特定的构造函数抛出了一个异常而不是创建一个对象。

    通常lib.d.ts 只会排除这些无用的签名,但 TypeScript 要求 instanceof 运算符的右侧有一个构造函数。也就是说foo instanceof HTMLElement可以写,foo instanceof []不行,区别在于HTMLElement有构造函数。

    这里基本上有三个选择:

    1. 从 DOM 元素中移除构造签名并移除对 instanceof 右操作数的限制。这是不可取的,因为您真的更愿意在有人意外编写代码时捕获错误,例如 x instanceof foo 而不是 x instanceof Foo(其中 fooFoo 的一个实例)。
    2. 从 DOM 元素中删除构造签名,但保留 instanceof 检查。这很糟糕,因为foo instanceof HTMLElement 是一个非常合理的写法。
    3. 当前情况,构造函数存在,但您必须知道不要调用它们。

    你不能使用普通的构造函数来构造 DOM 元素,因为你应该通过document.createElement。这基本上是出于与浏览器如何实现这些对象有关的技术原因。

    【讨论】:

    • 惊人的解释。是否可以在 lib.d.ts 中发表评论来解释这一点?或者你不想用 cmets 污染 lib.d.ts?
    • 为调用Element子类的构造函数的代码添加来自tsc的警告或错误是否有意义?
    • 如果您扩展 HTMLElement,例如 class Thing extends HTMLElement,那么您可以使用 new 来创建带有 let t = new Thing() 的实例。然后你就可以把它添加到 DOM 中了!
    • 看来不是这样,Kokodoko:class Thing extends HTMLElement {} ; let t = new Thing() 导致 TypeError: Illegal constructor.
    • customElements.define( 'custom-tag', Thing ); 然后调用new Thing() - 返回<custom-tag></custom-tag>
    【解决方案2】:

    您将 typescript 语法与 c# 语法错误。

    只需替换

    var elem = new HTMLDivElement();
    

    使用以下之一

    var elem = document.createElement('div');
    

    var elem = <HTMLDivElement>(document.createElement('div'));
    

    let elem = document.createElement('div') as HTMLDivElement
    

    (如果需要使用 HTMLDivElement 属性)

    【讨论】:

      【解决方案3】:

      如果您扩展 HTMLElement 或任何子类,如 HTMLDivElement

      你还需要注册自定义元素

      
      class SampleDiv extends HTMLDivElement{
          constructor(){
             super();
          }
      }
      customElements.define('sample-div', SampleDiv, { extends: 'div' });
      

      在此处查看更多信息: https://javascript.info/custom-elements

      【讨论】:

      • 如果我没记错的话,需要将{extends:'div'}作为第三个参数添加到define函数中:如:customElements.define('sample-div', SampleDiv, { extends: 'div' });
      猜你喜欢
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2019-09-19
      相关资源
      最近更新 更多