扩展HTMLElement原型

时间:2018-08-03 20:44:25

标签: javascript angular typescript

我正在尝试在main.ts中扩展HTMLElement对象的原型,以便可以在整个Angular 6项目中使用它。

但是我得到了Property 'fadeOut' does not exist on type 'HTMLElement'

HTMLElement.prototype.fadeOut = function(duration: number = 300): Promise<void> {
  const keyframes: AnimationKeyFrame[] = [{ opacity: 1 }, { opacity: 0 }];
  return new Promise(resolve => {
    const animation: Animation = this.animate(keyframes, duration);
    animation.onfinish = () => resolve();
  });
};

const circle = document.getElementById('circle');

HTMLElement.prototype.fadeOut = function(duration = 300) {
  const keyframes = [{ opacity: 1 }, { opacity: 0 }];
  return this.animate(keyframes, duration).finished
};

circle.fadeOut(2000);
#circle {
  height: 100px;
  width: 100px;
  margin: 50px;
  border-radius: 50%;
  background-color: #0f477f;
 }
 
<div id="circle"></>

我在做什么错了?

我需要在哪里放置这段代码,以便可以在任何地方使用此方法?

您还看到使此代码更简洁的可能性吗?

1 个答案:

答案 0 :(得分:3)

您需要在原始接口中添加一个定义为merged,在其中定义要添加到HTMLElement的额外功能

interface HTMLElement {
    fadeOut(duration: number): Promise<void>
}

// Will now work 
HTMLElement.prototype.fadeOut = function (duration: number = 300): Promise<void> {
    const keyframes: AnimationKeyFrame[] = [{ opacity: 1 }, { opacity: 0 }];
    return new Promise(resolve => {
        const animation: Animation = this.animate(keyframes, duration);
        animation.onfinish = () => resolve();
    });
};

如果代码在模块中,则需要在全局名称空间中声明接口

declare global {
    interface HTMLElement {
        fadeOut(duration: number): Promise<void>
    }

}
HTMLElement.prototype.fadeOut = function (duration: number = 300): Promise<void> {
    const keyframes: AnimationKeyFrame[] = [{ opacity: 1 }, { opacity: 0 }];
    return new Promise(resolve => {
        const animation: Animation = this.animate(keyframes, duration);
        animation.onfinish = () => resolve();
    });
};


export var x;