Javascript 当使用动态导入而不是普通的标记链接时,脚本被破坏

Javascript 当使用动态导入而不是普通的标记链接时,脚本被破坏,javascript,import,es6-modules,Javascript,Import,Es6 Modules,我有一个自制的音频播放器,当通过正则脚本标签链接到页面时,它可以在我的网站上完美运行: … 脚本本身是用纯JS编写的,没有任何库、框架等:按下三角形,播放器开始播放;这里没有什么特别的。它在一些旧浏览器中可能不起作用,但现在这不重要了 但是,如果我在支持这种导入的浏览器中将其与动态导入链接,则该播放器将被破坏。在HTML中,链接的是另一个脚本index.js而不是player.js,此index.js导入player.js: //index.js log“index.js正在运行…”; 导入“/

我有一个自制的音频播放器,当通过正则脚本标签链接到页面时,它可以在我的网站上完美运行:

… 脚本本身是用纯JS编写的,没有任何库、框架等:按下三角形,播放器开始播放;这里没有什么特别的。它在一些旧浏览器中可能不起作用,但现在这不重要了

但是,如果我在支持这种导入的浏览器中将其与动态导入链接,则该播放器将被破坏。在HTML中,链接的是另一个脚本index.js而不是player.js,此index.js导入player.js:

//index.js log“index.js正在运行…”; 导入“/static/js/player.js”; ,在Windows上的Chrome和macOS上的Safari中进行了测试,所有浏览器和操作系统都是本文发布时的最新版本

player.js似乎正在加载和执行。当我将console.logs包含到其中时,它会将它们精确地输出到我期望的位置;我也没有发现与使用Dev工具中的调试器的上一个版本有任何运行时差异

但在这种情况下,音频播放器不起作用。如果按三角形键,则不会启动播放器,而只会直接链接到MP3文件。最初,它是脚本未加载或被破坏时的预期行为;但我不知道在这种情况下到底是什么断裂


脚本player.js在这两种情况下完全相同;唯一的区别是在第二种情况下添加动态导入。请帮我找出问题所在。

由于旧版本的JS没有导入功能,但自2015年ES6以来,JS已经使用ES6模块标准在NodeJS中导入模块

我会尝试这两种不同的方法中的一种来实现它:

1-使用index.js文件中的脚本标记动态加载,如:

Index.js:

2-或者使用新的ES6模块导入,记住用mjs扩展名存储播放器文件!:

<script type="module">
  import { player } from './static/js/player.mjs';
  player();
</script>
此外,如果您需要更老的浏览器兼容性,您可以使用一些工具,如Babel或Webpack。您可以在此处找到更多信息:


希望有帮助

您将js文件放在标题上,这就是神奇之处。 如果您阅读了player.js文件,就会看到播放器在DOMContentLoaded上的回复

在第一个示例中,在加载player.js之前,您的网站基本上停止加载,因为您将其放在标题上,player.js能够将事件绑定到DOMContentLoaded。然后,在所有初始HTML文档完全加载和解析后,触发事件DOMContentLoaded,您的播放器就可以启动了

关于第二个例子。事件DOMContentLoaded将在文件player.js上的脚本之后激发,因为您通过import命令加载了文件。尽管您的脚本仍然能够绑定事件DOMContentLoaded,但它已经启动,因此没有任何效果

您可以简单地尝试在Chrome控制台上再次手动触发事件,并将看到您的播放器通过使用此脚本工作正常

window.dispatchEvent(new Event('DOMContentLoaded'))

我要求的不是一种将JS文件连接到网页的通用方法;我想我对这些方法很了解。我的问题是,为什么这个特定的脚本在通过正则脚本标记链接时工作得很好,但在通过动态导入链接时却不能按预期工作。在后一种情况下,脚本至少部分地被加载和执行,正如您在控制台中看到的那样;因此,问题似乎不在于文件链接的方法,而在于其他地方。Perharps事件处理程序根据此方法注册不同,或者其他一些东西-我无法理解。
export function player() {
   //Your code here
}
new Effect({  // container
behavior: `
  $window
    DOMContentLoaded
      _.init
`,
prop
....
window.dispatchEvent(new Event('DOMContentLoaded'))