【问题标题】:Calling a function defined in a TypeScript file from an HTML input onchange attribute从 HTML 输入 onchange 属性调用 TypeScript 文件中定义的函数
【发布时间】:2020-06-02 13:06:55
【问题描述】:

如果我有一个像这样的 JavaScript index.js 文件:

function foo(val) {
  console.log(val);
}

还有一个 index.html 像这样的 HTML 文件:

...
<script src="./index.js"></script>
<div id="container">
  <label>bar
    <input type="radio" name="radio" value="bar" onchange="foo(value);"/>
  </label>
  <label>baz
    <input type="radio" name="radio" value="baz" onchange="foo(value);"/>
  </label>
...

当我检查单选按钮时,这将记录 barbaz

我想调用在 index.ts TypeScript 文件中定义的foo(value),如下所示:

let foo = (value: string): void => {
  console.log(value);
};

index.html中我把&lt;script src="./index.js"&gt;&lt;/script&gt;改成&lt;script src="./src/index.ts"&gt;&lt;/script&gt;,然后我用parcel构建app,但是构建出来的文件不能调用函数,记录referenceError: setLayer is not defined .

我知道理论上浏览器对 TypeScript 一无所知,只知道 JavaScript,但是在我的 dist 目录中使用 parcel 编译后,我看到一堆 *js 文件,我认为其中一个可能包含编译后的文件foo()函数。

所以问题是:如何像处理 JS 文件一样从 HTML 输入 onchange 属性调用 TS 文件内的函数?

最后但同样重要的是:为了构建我的应用程序,我调用了parcel start(甚至是parcel run build),而我的package.json 看起来像这样:

{
  "name": "app_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start:build": "tsc -w",
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.4",
    "typescript": "^3.7.5"
  }
}

【问题讨论】:

  • 您不能直接从 .ts 文件执行函数。它只是程序的“源代码”,必须先“编译”成 JavaScript(并保存为 .js 文件)才能使用。

标签: javascript html typescript


【解决方案1】:

问题:

像 Parcel 和 Webpack 这样捆绑你的 js 的工具将你的所有模块包装在 IIFE 中,因此,在 Parcel 处理之后,你的 index.ts 函数 foo 不是全局的,你不能再从你的 html 文件中简单地访问它。未经处理(如本例中:&lt;script src="./index.js"&gt;&lt;/script&gt;foo 是全局的。

解决方案:

foo 设为全局。

// index.ts
function foo(val: string) {
  console.log(val);
}

window.foo = foo;

Codesandbox

【讨论】:

  • 太好了,成功了!非常有趣,我想了解更多。非常感谢!
  • 不客气。我参加了有关 webpack 的 FrontendMasters 课程,但他们都做同样的事情。
【解决方案2】:

不要直接从index.html 文件中引用index.ts,而是尝试像这样指向/dist 中的已编译文件:

<script src="dist/index.js"></script>

正如您所说的,TypeScript 只是 JavaScript 的超集,您的浏览器无法解释 - 只有在将其编译为 JavaScript 之后。

【讨论】:

  • 按照您的建议更改 HTML,当我尝试执行 parcel start 时,我遇到了构建错误 my_path/dist/index.js: ENOENT: no such file or directory, open 'my_path/dist/index.js'(当然 my_path 是真实路径)。它试图寻找一个确实不存在的js。即使我使用 tsc ./src/index.ts 创建它并将 HTML 更改为 &lt;script src="./src/index.js"&gt;&lt;/script&gt; 我也会收到我在回答中描述的错误。
猜你喜欢
  • 2016-10-24
  • 1970-01-01
  • 2015-01-30
  • 2011-09-04
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
相关资源
最近更新 更多