0

Doing some basic practice/testing for a project I'm working on and can't get my html file to access the functions written in the attached javascript file. I feel like there's something super basic that I'm missing but I can't put my finger on it.

I pulled the basic button from here: Creating an ON/OFF button with javascript And I tried the solutions here: HTML file not pulling information from javascript file

My html:

<!DOCTYPE html>
<head>
  <script type="text/javascript" src="app.js"></script>
  <link rel="stylesheet" href="style.css">
</head> 
<body>
    <input type="button" value="X" id="turn" onclick="turn();">
</body>
</html>

My js:

function turn(){
    currentvalue = document.getElementById('turn').value;
    if(currentvalue == "X"){
        document.getElementById("turn").value="O";
    }
    else{
        document.getElementById("turn").value="X";
    }
}

The function itself works when embedded in a script tag within <body> but not when pulled from the attached javascript file. What am I missing?

rioV8
  • 24,506
  • 3
  • 32
  • 49
Cameron Crane
  • 113
  • 1
  • 12
  • Your code is running before the DOM loads. Either put the call to the script before the `

    ` [or use defer](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script), or `window.addEventListener('DOMContentLoaded', fn);`.

    – Andy Mar 20 '22 at 01:07
  • @Andy but the function likely doesn't run until after the document is loaded, since it is triggered by user click, so `document` should have been ready by then. – code Mar 20 '22 at 01:13
  • @Andy Tried all three of these and sadly did not work. Tried putting the script right above ``````, at the top inside it, and at the bottom inside it. Then tried using defer in the script tag, and also added ```window.addEventListener... etc``` in the javascript and still nothing. – Cameron Crane Mar 20 '22 at 01:17
  • Not an answer to your question by why hit the DOM 3 times? it can just be `function turn() { let myTurn = document.getElementById('turn'); myTurn.value = myTurn.value == "X" ? "O" : "X"; }` – Mark Schultheiss Mar 20 '22 at 01:45

2 Answers2

1

You should use <script> tag in body.

<!DOCTYPE html>
<html lang="en">
  <head> </head>
  <body>
    <input type="button" value="X" id="turn" onclick="turn();" />
    <script src="app.js"></script>
  </body>
</html>

For summary: Modern approach to old approach

  • You can use module which are defered by default <script type="module" src="/app.js"></script>
  • You can use defer to make sure your js is executed after page has load i.e <script src=app.js" defer></script>
  • You can put your <script> tag before </body> body tag closing

For more details, you can look at this excellent answer.

Umut Gerçek
  • 630
  • 6
  • 9
  • Unfortunately tried this as well, and still nothing :( – Cameron Crane Mar 20 '22 at 01:18
  • 1
    Above works on my machine. – Umut Gerçek Mar 20 '22 at 01:26
  • After edit: Tried module originally and sadly that didn't work either. Neither did defer, nor changing the position of my ` – Cameron Crane Mar 20 '22 at 01:26
  • 1
    You can use [this link](https://jsfiddle.net/eugercek/mbowvtn6) to continue studying. I edited the answer again it seemed like you didn't have `` tag open maybe it's the reason of bug. – Umut Gerçek Mar 20 '22 at 01:35
  • Looks like the issue was that I accidentally left the ```window.addEventListener('DOMContentLoaded', fn);``` line in my javascript while also trying this method, and that was causing an issue. Removing it and adding ```defer``` into my ``` – Cameron Crane Mar 20 '22 at 01:36
1

function turn(){
    currentvalue = document.getElementById('turn').value;
    if(currentvalue == "X"){
        document.getElementById("turn").value="O";
    }
    else{
        document.getElementById("turn").value="X";
    }
}
<!DOCTYPE html>
<head>
  <script type="text/javascript" src="app.js" defer></script>
  <link rel="stylesheet" href="style.css">
</head> 
<body>
    <input type="button" value="X" id="turn" onclick="turn();">
</body>
</html>

You need to add defer atrribute.

webCatDev
  • 86
  • 5
  • This fixed it! I tried this before but accidentally left ```window.addEventListener('DOMContentLoaded', fn);``` in my javascript at the same time and that was somehow causing an issue. Copied/pasted yours exactly (without that extra addition) and it somehow worked. Thanks for the help :) – Cameron Crane Mar 20 '22 at 01:35
  • 1
    Your welcome. Defer makes it download js but wait to HTML parsing complete. Then parse js file. – webCatDev Mar 20 '22 at 01:45