A simple HTML webpage using SystemJS 0.21 that's loading a JavaScript module compiled from TypeScript. The HTML web-page has an onclick=""
-style event-handler that calls a function declared in a module file:
{
"compilerOptions": {
"module": "system",
"moduleResolution": "node"
}
}
export function onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {
console.log( 'clicked!' );
return true;
}
I'm using SystemJS in a HTML page in a website (not an SPA) like so:
System.config( {
map: { /* ... */ },
packages: {
'/scripts/': { defaultExtension: 'js' }
}
} );
System.import( '/scripts/Page' );
<html>
<head>
<script src="/scripts/system.src.js"></script>
<script src="/scripts/system.config.js"></script>
</head>
<body>
<button onclick="onButtonClick( event, this )">Click me and check the browser console</button>
</body>
</html>
This doesn't work because the onButtonClick
function is defined in Page.js
as a function within the module, which means it is not imported as a property into the global ( Window
) object in consuming scripts. So I get this output in my console window:
Uncaught
ReferenceError
:onButtonClick
is not defined at HTMLButtonElement.onclick (Page.html:8)
So how can I get my <button onclick="onButtonClick( event, this )"
to use the function onButtonClick
in Page.ts
/ Page.js
?
I developed a workaround solution for now:
Window
object interface in the TypeScript module to add the new global functions. window
within the module's "top-level" function. This isn't the same thing as having SystemJS importing a module into the window
object (which is what I originally wanted) and this approach also requires me to modify the module I'm importing, but it works for now.
Like so:
declare global {
declare interface Window {
onButtonClick( e: Event, btn: HTMLButtonElement ): boolean;
}
}
function onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {
console.log( 'clicked!' );
return true;
}
window.onButtonClick = onButtonClick;
The onButtonClick
function no-longer needs to be exported. And this can be made even more succinct by just assigning the function directly:
declare global {
declare interface Window {
onButtonClick( e: Event, btn: HTMLButtonElement ): boolean;
}
}
window.onButtonClick = onButtonClick( e: Event, btn: HTMLButtonElement ): boolean {
console.log( 'clicked!' );
return true;
};
Because the Page.ts
/ Page.js
module is loaded asynchronously it does mean that when Page.html
loads the onclick=""
attributes won't work until the module is loaded - but assuming that happens quickly after the page loads there won't be any user-experience issues.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.