8

I have as basic onClick in a button that outputs an alert

function test(){
  alert('here');
}
<button onClick="test()">Press</button>

In StackBlitz this doesn't work - https://stackblitz.com/edit/js-umarwe?embed=1&file=index.js&hideNavigation=1

Is this because of ES6

How does this work in ES6

connexo
  • 53,704
  • 14
  • 91
  • 128
RRachel
  • 99
  • 6

3 Answers3

13

Why it doesn't work

The reasons it is not working is that behind Stackblitz there is an asset building system which treats your Javascript code as modules.

That means that variables defined in those modules are only available inside those modules and do not become attached to the global namespace (as you expected and seem to be used to).

Minimum required to fix it

To achieve that, you need to explicitly attach those variables to the global object, which inside a browser happens to be window.

Simply adding the following line at the end of your index.js file makes your code work:

window.test = test;

A better way

Please note that using inline event handlers directly on the element (like onclick) is considered bad practice (and does have practical disadvantages, but that would lead too far). Instead, you should use Javascripts Element.prototype.addEventlistener() function. Steps to get there:

Add an id to your button so your Javascript can find it:

<button id="testButton">Press</button>

Next, put that element in a variable:

const button = document.getElementById('testButton');

Last step: Add the event listener for the click event:

button.addEventListener('click', test)

Here's the full index.js for that refactored version:

// Import stylesheets
import './style.css';
function test(){
  alert('here');
}

const button = document.getElementById('testButton');
button.addEventListener('click', test);

How to make it even safer and better

One more note: If you place the script tag loading the Javascript in the head section of the document, you either need to add a defer attribute on the tag, or wrap the part of the code that needs to access the DOM in a DOMContentLoaded event handler:

// Import stylesheets
import './style.css';
function test(){
  alert('here');
}

document.addEventListener('DOMContentLoaded', function () {
  const button = document.getElementById('testButton');
  button.addEventListener('click', test);
}

Otherwise the HTML has not yet been parsed by the browser when your Javascript tries to find the button and attach the event listener.

connexo
  • 53,704
  • 14
  • 91
  • 128
  • Maybe because `DOMContentLoaded` will never be triggered since `document.readyState` is always `"complete"` when *"index.js"* is executed. – Serg Apr 11 '19 at 16:01
-1

Modify test function declaration in index.js file:

window.test = function(){
  alert('here');
}

It doesn't recognize test function on click event because test function you declared is not in the same scope.

-2

You can do this.

window.test = () =>{
  alert('here');
}

I don't know stackBlitz..

but, I understand loading index.js

so window.test = () => {} ...

seunggabi
  • 1,699
  • 12
  • 12
  • 1
    "I don't know stackBlitz.." — Maybe you should fix that before answering a question that is explicitly about it – Quentin Sep 08 '18 at 11:05
  • @Quentin "I don't know stackBlitz.." << this sentence is I don't have experience by stackBlitz. but, I try changing code. so I make working code. I did not do it. – seunggabi Sep 08 '18 at 11:10