在转换为ES5时,我遇到了一个简单的Web组件工作的麻烦 . 它看起来在chrome,Edge和Firefox下运行得非常好,但IE11在组件的构造函数中失败了“自定义元素构造函数没有生成要升级的元素 . ”
更新
下面的Oliver Krull的出色工作明确地将问题归结为Typescript的编译器输出 . 它可以使它工作吗?
原始源(在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>
2 回答
为了让custom elements v1工作跨浏览器,我们需要添加this native-shim(here关于它的更多信息) .
这适用于所有主流浏览器(边缘,Safari,Firefox等)但不在ie11中!
当我们尝试在ie11中导入它时,我们得到了一堆语法错误,因为shim是用一些es6编写的 .
一个简单的解决方法是将填充程序编译为es5并添加es6版本(首先是es6,然后是es5以省略错误) .
这不是最干净的解决方案,但至少它可行 .
我创建了一个带有工作示例的repo(您的app-drawer(由于冲突而删除了
disabled
属性)) .再次,它不是干净但它的工作;-)
问题是Typescript的ES5类实现与
custom-elements-v1
垫片不兼容 . 那么,显而易见的解决方案是配置TypeScript以生成ES6并将其传递给Babel以进行转换 .然而,看到接受的答案 - 似乎通过将es5转换后的填充添加到打字稿生成的代码修复,TypeScript 's ES5, while having no effect on babel compiled code. I' ve接受了它,因为它对于这个问题是一个相当简单的插入修复,并且我实际上并不理解的警告它为何有效