自定义元素 v1 从 Typescript 转换为 ECMAScript 5 在 IE11 下失败 [英] Custom Elements v1 in transpiling from Typescript to ECMAScript 5 failing under IE11

查看:19
本文介绍了自定义元素 v1 从 Typescript 转换为 ECMAScript 5 在 IE11 下失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将简单的 Web 组件转换为 ES5 时遇到了问题.它似乎在 chrome、Edge 和 Firefox 下运行良好,但 IE11 在组件的构造函数中失败,并显示自定义元素构造函数未生成正在升级的元素."

I'm running into trouble getting a simple web component to work when transpiled to ES5. It appears to function perfectly fine under chrome, Edge, and Firefox, but IE11 is failing in the component's constructor with "The custom element constructor did not produce the element being upgraded."

下面 Oliver Krull 的出色工作清楚地将问题归结为 Typescript 的编译器输出.有没有可能让它发挥作用?

The excellent work of Oliver Krull below has clearly pinned down the problem to Typescript's compiler output. Is it possible to make it work?

原始来源(在 TypeScript 中):

The original source (in TypeScript):

import "./AppDrawer.less"

class AppDrawer extends HTMLElement {
    get open() {
        return this.hasAttribute("open");
    }

    set open(val: boolean) {
        val ? this.setAttribute("open", '') : this.removeAttribute('open');
    }

    get disabled() {
        return this.hasAttribute("disabled");
    }

    set disabled(val: boolean) {
        val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled');
    }

    static get observedAttributes() { return ["open"] };

    constructor() {
        super();
    }

    connectedCallback() {
        this.addEventListener("click", () => {
            this.open = !this.open;
        })
        this.textContent = this.open ? "OPEN": "CLOSED";
    }

    attributeChangedCallback(attr, oldVal, newVal) {
        this.textContent = this.open ? "OPEN": "CLOSED";
    }
}


customElements.define("app-drawer", AppDrawer)

输出(bundle.js):

(function () {
'use strict';

function __$styleInject(css) {
    if (!css) return;

    if (typeof window == 'undefined') return;
    var style = document.createElement('style');
    style.setAttribute('media', 'screen');

    style.innerHTML = css;
    document.head.appendChild(style);
    return css;
}

__$styleInject("app-drawer {\n  color: red;\n}\n");

function __extends(d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

var AppDrawer = (function (_super) {
    __extends(AppDrawer, _super);
    function AppDrawer() {
        _super.call(this);
    }
    Object.defineProperty(AppDrawer.prototype, "open", {
        get: function () {
            return this.hasAttribute("open");
        },
        set: function (val) {
            val ? this.setAttribute("open", '') : this.removeAttribute('open');
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AppDrawer.prototype, "disabled", {
        get: function () {
            return this.hasAttribute("disabled");
        },
        set: function (val) {
            val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled');
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AppDrawer, "observedAttributes", {
        get: function () { return ["open"]; },
        enumerable: true,
        configurable: true
    });

    AppDrawer.prototype.connectedCallback = function () {
        var _this = this;
        this.addEventListener("click", function () {
            _this.open = !_this.open;
        });
        this.textContent = this.open ? "OPEN" : "CLOSED";
    };
    AppDrawer.prototype.attributeChangedCallback = function (attr, oldVal, newVal) {
        this.textContent = this.open ? "OPEN" : "CLOSED";
    };
    return AppDrawer;
}(HTMLElement));
customElements.define("app-drawer", AppDrawer);

}());

还有我的 HTML:

<!doctype html>
<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/webcomponents-lite.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/custom-elements-es5-adapter.js"></script>
        <script src="bundle.js"></script>
    </head>
    <body>
        <app-drawer open disabled></app-drawer>
    </body>
</html>

推荐答案

为了获得 自定义元素 v1 跨浏览器工作,我们需要添加 这个 原生垫片(这里 有关它的更多信息).

In order to get custom elements v1 working cross browser we need to add this native-shim (here more infos about it).

这适用于所有主要浏览器(edge、safari、firefox 等),但不适用于 ie11!

This works well in all major browsers (edge, safari, firefox etc..) but doesn't in ie11!

当我们尝试在 ie11 中导入它时,我们会收到一堆语法错误,因为 shim 是用一些 es6 编写的.

When we try to import it in ie11 we get a bunch of syntax errors because the shim is written with some es6.

一个简单的解决方法是将 shim 编译为 es5,并在 es6 版本之外添加它(首先是 es6,然后是 es5 以忽略错误).

A simple workaround is to compile the shim to es5 and add it in addition of the es6 version (first es6, then es5 to omit errors).

这不是最干净的解决方案,但至少它有效.

This isn't the cleanest solution, but at least it works.

我用一个工作示例创建了一个 repo(您的应用程序抽屉(已删除)disabled 属性,因为冲突)).

I created a repo with a working example (your app-drawer (removed the disabled attribute because of conflicts)).

再说一次,它不是很干净,但它有效;-)

Again, it's not verry clean but it works ;-)

这篇关于自定义元素 v1 从 Typescript 转换为 ECMAScript 5 在 IE11 下失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆