15

カスタム要素を定義しました。カスタム要素が登録済みのタイプにアップグレードされたときにのみスクリプトを実行したいと考えています。ユース ケースは、カスタム メソッドを呼び出す必要がある場合です。

私のメインのhtmlファイルは次のようになります。

<project-list></project-list>
<script>
    var project_list = document.getElementsByTagName("project-list")[0]
    project_list.custom_method("some_data");
</script>

カスタム要素は、次のように HTML インポートに登録されます。

<script>
  "use strict";
  var currentScript = document._currentScript || document.currentScript;

  class ProjectList extends HTMLElement {

    createdCallback(){
      console.log("created");
    }

    custom_method(data) {
      console.log("custom_method() OK");
      console.log(data);

      this.innerHTML = data;
    }

  }

  document.registerElement("project-list", ProjectList);
</script>

私の質問は簡単です:カスタム要素がそのcustom_methodメソッドを取得した後にのみ、メインの html ファイルのスクリプトが呼び出されるようにする方法は?

エレガントなソリューションを探しています。仕様の作成者が考えたであろう何か。アーキテクチャをかなり変更してもかまいません (たとえば、必要に応じて JavaScript をメイン ファイルから別のカスタム要素に移動するなど)。

4

2 に答える 2

5

HTML インポートの同期

@dandavis で提案されているように、 and要素のsyncデフォルトの動作のため、タグを正しい順序で配置する必要があります: メソッド呼び出しの前に登録します。<link><script>

DOMContentLoadedまたは、以下のように、またはwindow.onloadイベントが発生したときにカスタム メソッドを呼び出すこともできます。

window.onload = function() 
{
    var project_list = document.getElementsByTagName("project-list")[0]
    project_list.custom_method("some_data")     
}
<project-list></project-list>

<script>
  "use strict";
  var currentScript = document._currentScript || document.currentScript;

  class ProjectList extends HTMLElement {

    createdCallback(){
      console.log("created");
    }

    custom_method(data) {
      console.log("custom_method() OK");
      console.log(data);

      this.innerHTML = data;
    }

  }

  document.registerElement("project-list", ProjectList);
</script>

非同期 HTML インポート

何らかの理由で HTML インポート ファイルを非同期的にロードしたい場合は、link.onloadイベントを待つことができます。この時点で | <script>インポートはすでに実行されており、カスタム要素が登録および作成されています。

<html>
<head>
  <title></title>
    <meta charset="utf-8" />
    <link rel="import" href="projectList.html" id="projectList" async>
    <script>
    projectList.onload = function ()
    {
      console.log( "import {loaded}" )
      var project_list = document.getElementsByTagName( "project-list" )[0]
      project_list.custom_method("some_data")
    } 
    </script>
</head>
<body>
    <project-list id="pl"></project-list>
    <script>
        console.warn( "custom_method is " + pl.custom_method ) //undefined
    </script>
</body>
</html>

WebComponents.js ポリフィルを使用

この状況では、ポリフィルは、インポートがロードされた直後に作成されたオブジェクトをインスタンス化しません。WebComponentsReady代わりに、イベントをリッスンする必要があります。

document.addEventListener( "WebComponentsReady", function ()
{
    console.log( "WebComponentsReady" )
    var project_list = document.getElementsByTagName( "project-list" )[0]
    project_list.custom_method( "some_data" )
} )

Firefox、IE 11、および Chrome でも動作します。

于 2016-03-05T00:09:05.443 に答える