web-dev-qa-db-ja.com

ES6モジュールで定義された関数を直接HTMLで使用する

私はかなり単純なことを達成しようとしています:javascriptモジュールファイルにコードがあり、それを別のjavascriptファイル(何もエクスポートしない)にインポートし、そのファイルで定義されている関数のいくつかを直接HTML。

私に起こっていることのいくつかの代表的で最小限の例を見てみましょう(実際にコードをテストして、実際のものと同じ問題が発生しますが、この問題ほど複雑ではありません)。

  • module.js

    const mod = () => 'Hello there!';
    export { mod };
    
  • main.js

    import { mod } from './module.js';
    
    function hello()
    {
        console.log(mod());
    }
    
  • main.html

    <!DOCTYPE html>
    <html>
        <head>
            <script type="module" src="module.js"></script>
            <script type="module" src="main.js"></script>
        </head>
    
        <body>
            <button name="next-button" onclick="hello()">Obi-Wan abandons the high ground to salute you</button>
        </body>
    </html>
    

importなし(およびすべての関数定義を単一の.js file)HTMLから直接関数を呼び出すことができます。ただし、いったんモジュールを導入すると、もうできなくなります。「hello()」関数が定義されていないというだけです。

私はES6モジュール(および実際にはフロントエンドのjavascript)をまったく使用していないので、私が今言ったのは知識(または理解)の欠如だけであることを十分に承知していますが、私が間違っていることに関するコメントや、コードを別のファイルに入れて使用できるように解決する方法。よろしくお願いします!

12

各モジュールには独自のスコープがあります。 「通常の」スクリプトのようにグローバルスコープを共有していません。つまり、hellomain.jsモジュール/ファイル自体の内部でのみアクセスできます。

グローバル変数を明示的に作成したい場合は、グローバルオブジェクトwindowにプロパティを作成することで実現できます。

function hello()
{
    console.log(mod());
}
window.hello = hello;

参照 JavaScript関数でグローバル変数を定義する


そうは言っても、グローバル変数を回避することは良い習慣です。代わりに、ボタンの作成後にモジュールをロードするようにHTMLを再構築し、JavaScriptを介してイベントハンドラーをバインドできます。

<!DOCTYPE html>
<html>
    <body>
        <button name="next-button">Obi-Wan abandons the high ground to salute you</button>
        <script type="module" src="module.js"></script>
        <script type="module" src="main.js"></script>
    </body>
</html>

そして

import { mod } from './module.js';

function hello()
{
    console.log(mod());
}
document.querySelector('button').addEventListener('click', hello);
2
Felix Kling