2

I have a button that when clicked it changes the color of text to red.

Some basic JS below:

function colorChange() {
 document.getElementById('text').style.color = "red";
}

and HTML:

<p id="text">some text</p>
<button type="button" onclick="colorChange()">red</button>

Does not work on either JSfiddle or Codepen. However - when I make an identical local HTML file it works as expected.

What would be a/the reason as to why this vanilla Javascript doesn't work in Codepen/JSfiddle? There are no libraries (jQuery, React etc) involved. My first immediate thought was in JSFiddle, there is a property that you can set in settings for the load type. I set this to onLoad and still did not work. Codepen doesn't look like it offers control over this.

JSFiddle: https://jsfiddle.net/mo5pro4a/1/

Codepen: https://codepen.io/anon/pen/YVYZXj

UPDATE: Codepen actually looks to be OK - the issue is primarily now with jsfiddle.

kawnah
  • 3,204
  • 8
  • 53
  • 103

4 Answers4

1

Because you use onclick attr in html, but js is inserted after this tag.

It'll work fine if you add <script> in html area.

<script>
function colorChange() {
    document.getElementById('text').style.color = "red";
}
</script>
<p id="text">some text</p>
<button type="button" onclick="colorChange()">red</button>

Thanks imtheman. Another way is to click on the JavaScript gear and change the load type to "head" or "body" in fiddle.

Stanislav Mayorov
  • 4,298
  • 5
  • 21
  • 44
  • 3
    Also, if you click on the JavaScript gear, you can change the load type to "head" or "body". – imtheman May 08 '17 at 20:10
  • This is not actually a good approach because it implies that you can scan the DOM for elements prior to the entire DOM being parsed. If you were to place the script prior to the HTML, the contents of the script (that utilizes DOM elements) should be inside of a `DOMContentLoaded` event handler. Better yet, don't use inline event attributes. – Scott Marcus May 08 '17 at 20:10
  • @ScottMarcus of course. It's just a simple example. – Stanislav Mayorov May 08 '17 at 20:13
  • 1
    But, simple examples should not be examples of how not to do it. – Scott Marcus May 08 '17 at 20:13
  • 1
    I see. I guess JSFiddle builds out differently than Codepen. – kawnah May 08 '17 at 20:14
  • @ScottMarcus the question was about differences in jsfiddle. if he used addEventListener he coundn't see this difference at all. – Stanislav Mayorov May 08 '17 at 20:16
  • 1
    Stack Overflow answers should always strive to follow standards and best practices. You could have just stated what the problem was with JSFiddle, but then gone on to explain why that form of coding should be avoided. Remember, Stack Overflow is a knowledge base for future users as well. – Scott Marcus May 08 '17 at 20:18
  • 1
    @ScottMarcus I totally understand the whole seperation of concerns concept - I was just curious as to why this wasn't working as expected in JSFiddle. I thought it ran the script before the HTML. Setting up event listeners in the JSFiddle wouldn't have worked anyways as now I know that scripts load after HTML in that platform. – kawnah May 08 '17 at 20:22
  • @kawnah I understand and I think all the answers here have answered your question. But, (FYI) actually, setting up event listeners in JS Fiddle works just fine. You can control when the scripts load or you can actually put all of your code (HTML and JavaScript) into the HTML section and it will work. – Scott Marcus May 08 '17 at 20:23
  • @ScottMarcus yes I know this now! :) – kawnah May 08 '17 at 20:29
1

It's because of when your JavaScript is loaded. If you change the load type in your fiddle to No wrap - in <head> (see this example) it will work.

It also works in a snippet here, on StackOverflow:

function colorChange() {
 document.getElementById('text').style.color = "red";
}
<p id="text">some text</p>
<button type="button" onclick="colorChange();">red</button>

To avoid this problem, be sure to add your <script> tag before running any JavaScript or specifying any code, such as the onclick attribute.

freginold
  • 3,946
  • 3
  • 13
  • 28
  • 1
    I think this is really the best answer. – imtheman May 08 '17 at 20:14
  • @imtheman Advocating the use of inline HTML event attributes (which is the cause for this issue) is never the best answer. – Scott Marcus May 08 '17 at 20:15
  • 1
    @ScottMarcus I'm not advocating for inline HTML event attributes; just using what the OP provided and showing him why it didn't work. – freginold May 08 '17 at 20:18
  • 1
    I'm just trying to explain that using what the OP used is not what makes a good answer on Stack Overflow. Answers that answer the question and then provide corrections to code that is deficient in one way or another are. – Scott Marcus May 08 '17 at 20:20
1

This is happening because the onclick is being read before the script is and the colorChange function can't be found at that time.

This is yet another reason not to use inline HTML event attributes (see here for a slew of others). Change the code to follow standards and keep the JavaScript separate from the HTML.

Place all of this code inside a window event handler that runs after the DOM content is loaded, such as:

// When the document has been fully parsed...
window.addEventListener("DOMContentLoaded", function(){

    // Register the event handler via the DOM standard:
    document.querySelector("button").addEventListener("click", colorChange);

    function colorChange() {
     document.getElementById('text').style.color = "red";
    }

});
    <p id="text">some text</p>
    <button type="button">red</button>

Or, place this code into a <script> element that is placed just before the closing <body> tag (</body>) or

<body>
<p id="text">some text</p>
<button type="button">red</button>

<script>
// Register the event handler via the DOM standard:
document.querySelector("button").addEventListener("click", colorChange);

function colorChange() {
 document.getElementById('text').style.color = "red";
}
</script>
</body>

Either way, inline HTML event attributes should not be used.

Community
  • 1
  • 1
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
0

That's because you need to define the script before you define html or just put the js code you want to run inside the onClick() method.

Option 1 : https://jsfiddle.net/mo5pro4a/5/ Option 2 : https://jsfiddle.net/mo5pro4a/9/

Ümit Aparı
  • 540
  • 2
  • 6
  • 23