skip to Main Content

My JavaScript file is not linking to my HTML document. When I copy the code directly into the HTML body, it works, but it doesn’t work when I try to link the script file. Below is the code for both the HTML and JavaScript files:

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="styles.css">
  <script src="script.js"></script>
  <title>Document</title>
</head>
<body>
  <div id="cards-container">
    <div class="card">A<div id="aceH">♥</div></div>
    <div class="card">K<div id=kingS>♠</div></div>
    <div class="card">Q<div id="queenC">♣</div></div>
    <div class="card">J<div id="jackH">♥</div></div>
  </div>
  <button onclick="shuffleCards()">Shuffle Cards</button>
  <button onclick="resetCards()">Reset Cards</button>
</body>
</html>
var initialOrder = [];
var cardsContainer = document.getElementById('cards-container');

// Store the initial order of the cards
var cards = Array.from(cardsContainer.getElementsByClassName('card'));
cards.forEach(function (card) {
  initialOrder.push(card);
});

function shuffleCards() {
  cards = Array.from(cardsContainer.getElementsByClassName('card'));
  cards.forEach(function (card) {
    var randomPos = Math.floor(Math.random() * cards.length);
    cardsContainer.appendChild(card);
    cardsContainer.insertBefore(card, cards[randomPos]);
  });
}

function resetCards() {
  cards = Array.from(cardsContainer.getElementsByClassName('card'));
  cards.forEach(function (card, index) {
    cardsContainer.appendChild(card);
    cardsContainer.insertBefore(card, initialOrder[index]);
  });
}

I am new to this, so maybe it is a simple mistake. However, the JavaScript code works fine when it is directly in the HTML body.

3

Answers


  1. Since you know the JS isn’t at fault, you’re very close. The HTML file just needs a little more understanding of how to access the script.js file.

    Assuming your file structure looks something like:

    project folder
      index.html
      script.js
      maybeSomeStyles.css
    

    As a result, you’ll want to let the HTML file know that script.js is within the same directory by adding a relative path identifier (you’ll see a lot more of this as you use JS more).

    Try replacing your script line with the following:
    <script src="./script.js"></script>

    . means this directory, while .. means the parent directory.

    Login or Signup to reply.
  2. Place your code in the body as sometimes it takes time to render the script if it is placed in head :

    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="styles.css">
      <title>Document</title>
    </head>
    <body>
      <div id="cards-container">
        <div class="card">A<div id="aceH">&#x2665;</div></div>
        <div class="card">K<div id=kingS>&#x2660;</div></div>
        <div class="card">Q<div id="queenC">&#x2663;</div></div>
        <div class="card">J<div id="jackH">&#x2665;</div></div>
      </div>
      <button onclick="shuffleCards()">Shuffle Cards</button>
      <button onclick="resetCards()">Reset Cards</button>
      <script src="script.js"></script>
    </body>
    </html>
    
    

    Your java script code is fine don’t worry about that .

    Login or Signup to reply.
  3. Your script is loading before your HTML, but it’s failing because it’s instantly trying to interact with the DOM. Wrap all your JS in a listener to wait for all the markup to load, or move your script tag to just before the closing body tag. Jatin’s answer includes an example of the latter. Here’s how you would do the former in plain JS (the changes are commented):

    // add the event listener wrapping the rest of your code
    document.addEventListener('DOMContentLoaded', function () {
      var initialOrder = [];
      var cardsContainer = document.getElementById('cards-container');
    
      var cards = Array.from(cardsContainer.getElementsByClassName('card'));
      cards.forEach(function (card) {
        initialOrder.push(card);
      });
    
      function shuffleCards() {
        cards = Array.from(cardsContainer.getElementsByClassName('card'));
        cards.forEach(function (card) {
          var randomPos = Math.floor(Math.random() * cards.length);
          cardsContainer.appendChild(card);
          cardsContainer.insertBefore(card, cards[randomPos]);
        });
      }
    
      function resetCards() {
        cards = Array.from(cardsContainer.getElementsByClassName('card'));
        cards.forEach(function (card, index) {
          cardsContainer.appendChild(card);
          cardsContainer.insertBefore(card, initialOrder[index]);
        });
      }
    
      // put the above functions on window so you can
      // access them in your html
      window.shuffleCards = shuffleCards;
      window.resetCards = resetCards;
    });
    

    Also see the comment below this answer; you could use the defer attribute and keep your script tag in the head, as in <script defer src="script.js></script>

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search