Create custom elements v1 in ES5, not ES6

2020-06-23 07:36发布

问题:

Right now, if you follow the exact specifications of v1 of the custom elements spec, it's not possible to use custom elements in browsers that don't support classes.

Is there a way to create v1 custom elements without using the class syntax so that they are fully functional in Chrome, FireFox and IE11. Also, since IE11 doesn't have native support for custom elements, I'm assuming we will probably need to use some pollyfills, so what polyfills or libraries do we need in order to make this work in IE11?

I've messed around with Polymer 2, Polymer 3, and Stencil, but they are all a bit heavy-duty for some of the things we want to create.

This question seems to be on the right track, but I had some trouble getting it to work in IE11, so also how can I use Reflect.construct in IE11 for the purposes of custom elements?

回答1:

Here's a full example of writing ES5-compatible custom elements using the v1 spec (credit to this comment on github)

<html>

<head>
  <!--pollyfill Reflect for "older" browsers-->
  <script src="https://cdn.rawgit.com/paulmillr/es6-shim/master/es6-shim.min.js"></script>
  <!--pollyfill custom elements for "older" browsers-->
  <script src="https://cdn.rawgit.com/webcomponents/custom-elements/master/custom-elements.min.js"></script>
  <script type="text/javascript">
    function MyEl() {
      return Reflect.construct(HTMLElement, [], this.constructor);
    }

    MyEl.prototype = Object.create(HTMLElement.prototype);
    MyEl.prototype.constructor = MyEl;
    Object.setPrototypeOf(MyEl, HTMLElement);

    MyEl.prototype.connectedCallback = function() {
      this.innerHTML = 'Hello world';
    };
    customElements.define('my-el', MyEl);
  </script>
</head>

<body>
  <my-el></my-el>
</body>

</html>

Also, for the typescript lovers, here's a way to write custom elements using typescript that will still work when compiled to ES5.

<html>
<head>
    <!--pollyfill Reflect for "older" browsers-->
    <script src="https://cdn.rawgit.com/paulmillr/es6-shim/master/es6-shim.min.js"></script>
    <!--pollyfill custom elements for "older" browsers-->
    <script src="https://cdn.rawgit.com/webcomponents/custom-elements/master/custom-elements.min.js"></script>
    <script type="text/typescript">
        class MyEl extends HTMLElement{
          constructor(){
              return Reflect.construct(HTMLElement, [], this.constructor);
            }  
            
            connectedCallback () {
              this.innerHTML = 'Hello world';
          }
        }

        customElements.define('my-el', MyEl);
    </script>

</head>

<body>
    <my-el></my-el>
    <!-- include an in-browser typescript compiler just for this example -->
    <script src="https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js"></script>
    <script src="https://rawgit.com/basarat/typescript-script/master/transpiler.js"></script>
</body>

</html>