Javascript 模块导入失败

Javascript modules import fails

我正在尝试在此处输入代码以执行从 HTML 页面导入的模块。我看到它正在部分执行。我需要帮助。我的代码文件是 test.html、main.js 和 say.js。这些文件按相同的顺序在下面生成。

test.html:

<html>
 <head>
     <script type="module" src="./main.js"></script>
 </head>
 <body onload="sayHi('Manish')">
 </body>
</html>

main.js:

import { sayHi } from './say.js';
sayHi('MK');

say.js:

export function sayHi(user) {
alert('Hello, { $user }');}

This code partially executes

然后这部分执行后,报错

Uncaught ReferenceError: sayHi is not defined

at onload (test.html:7)

报错图片如下:

This is the error that says sayHi function is not recognized. Why?

我做错了什么?

String插值经典案例

使用

export function sayHi(user) { alert(`Hello, ${user}`);}

注意 ` 代替 ' 或 "

引用https://campushippo.com/lessons/how-to-do-string-interpolation-with-javascript-7854ef9d

对于错误,将window绑定到加载

window.addEventListener("load", () => {
    sayHi('testing');
});

模块的一大优点是其中的顶级声明等不会创建全局变量。 onxyz-attribute-style 事件处理程序的缺点之一是您使用它们调用的函数必须是全局函数。您的 sayHi 不是全局的,因此 onload="sayHi('Manish')" 失败,因为它无权访问 sayHi.

这是一件好事。

相反,只需从 main.js:

调用函数
import { sayHi } from './say.js';
sayHi('MK');
sayHi('Manish');

因为模块脚本会自动延迟到 HTML 处理结束,所以您知道在加载所有 HTML 之前不会发生这种情况。 this section of the spec 中的精美图片涵盖了这一点,复制于此:

如果您想等待更长时间,直到 load 事件(在加载所有图像等之前不会触发),请使用现代事件处理程序来执行此操作:

import { sayHi } from './say.js';
sayHi('MK');
window.addEventListener("load", () => {
    sayHi('Manish');
});

如果您需要挂钩事件的元素的信息,请使用传统函数并以 this 访问元素,或者接受 event 参数并使用 event.currentTarget (您还可以将 event.target 用于事件所针对的元素,它可以在您挂钩事件的元素内)。例如,假设您有:

<button type="button" data-name="Manish" id="btn-say-hi">

你可以:

import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
    sayHi(this.getAttribute("data-name"));
});

另请注意,正如 Vikas Saini 所指出的那样,您的 say.js 使用的是字符串文字而不是模板文字(尽管 he/she 没有提及,但也有错误的语法替代),因此您实际上会看到文本 Hello { $user } 而不是 Hello MKHello Manish。使用具有正确替换形式的模板文字(${user},而不是 { $user }):

export function sayHi(user) {
    alert(`Hello, ${user}`);
}

或简单的字符串连接:

export function sayHi(user) {
    alert("Hello, " + user);
}

基本上我的 objective 是将一些参数从 HTML 脚本传递到 main.js 文件。在你们两个都给我提示之后,我已经得到了要求,尤其是 Vikas Saini。在 main.js 文件中添加事件侦听器的建议很有帮助。非常感谢。为了像我这样的 ES6 初学者的利益,我发布了更正后的最新代码文件。

test.html 文件内容

<html>
<head>
    <script type="module" src="./main.js"></script>
</head>
<body>
    <input type="text" id="btn-say-hi"label="fill here" placeholder="Fill in here and click"/>
</body>
</html>

main.js 文件内容

import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
    sayHi(this.value);
});

say.js 文件内容

export function sayHi(user) { alert(`Hello, ${user}`); }

请注意:所有这些文件都在同一个 directory/folder 中。我可以更改文本项值,并可以根据我的输入获得所需的执行。

非常感谢T.J。 Crowder 和 特别感谢 Vikas Saini 提供与添加事件侦听器相关的代码片段。这是一个黄金建议。

非常感谢大家。 问候 马尼什