Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stackblitz: onClick doesn't find my function

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

like image 665
RRachel Avatar asked Sep 08 '18 10:09

RRachel


1 Answers

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.

like image 112
connexo Avatar answered Sep 20 '22 16:09

connexo