0

I am trying to add styles via Javascript. For some reason unknown to me, I am getting an error that says my query selector is not a valid selector, even though my ids look correct. Can someone please help me to understand what is going wrong with my code?

var currentRow;
var rowCol;
for(let i = 0; i < 3; i++)
{
    var x = i.toString();
    currentRow = document.querySelector("#0");
    for(let j = 0; j < 3; j++)
    {
        y = j.toString();
        rowCol = currentRow.querySelector("#" + x + y);
        if(i == 1)
        {
            rowCol.style.border = "5px 'solid black'";
            rowCol.style.border = "5px 'solid black'";
        } 
        if(j == 0 || j == 1)
        {
          rowCol.style.border = "5px 'solid black'";
        }
    }

}
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="./tictactoe.css">
</head>
<body>
   <script src="tictactoe.js"></script>
    <div class= "header">
    </div>

    <div class= "main">
        <div id = '0'>
            <div id = "00">x</div>
            <div id = "01">x</div>
            <div id = "02">x</div>
        </div>
        <div id = "1">
            <div id = "10">x</div>
            <div id = "11">x</div>
            <div id = "12">x</div>
        </div>
        <div class = "2">
            <div id = "20">x</div>
            <div id = "21">x</div>
            <div id = "22">x</div>
        </div>
    </div>

</body>
</html>
ElliotSchmelliot
  • 7,322
  • 4
  • 41
  • 64
je1013
  • 21
  • 5
  • 1
    Your script is included in the `head` and executed before the body of the HTML document is parsed, so the elements don't exist yet. Move the script to just before the closing `body` tag. – Scott Marcus Feb 01 '21 at 22:58
  • 1
    @CertainPerformance You've closed the question for the wrong reason. `id`s are allowed to start with numbers in HTML5 (you've posted a link to the HTML4 rules). That's not the problem here. – Scott Marcus Feb 01 '21 at 22:58
  • I did that and am still getting the same error – je1013 Feb 01 '21 at 23:03
  • @ScottMarcus Oh, thanks, my bad. Interesting. Maybe it's a `querySelector`-specific limitation? – CertainPerformance Feb 01 '21 at 23:06
  • @CertainPerformance It is. See my answer below. – Scott Marcus Feb 01 '21 at 23:07
  • @ScottMarcus CSS selectors still follow CSS2 rules where it was forbidden. It is the problem here, OP should escape the leading numbers. – Kaiido Feb 01 '21 at 23:07
  • @Kaiido It's simpler (and faster usually) to use `.getElementById` because most browsers optimize access to elements with `id`s, so searching with `.getElementById` leverages that capability. – Scott Marcus Feb 01 '21 at 23:08
  • @ScottMarcus they also all use the looking-table for `#`, Chrome even using it for [id=foo]. Not a point against querySelector which offers more modularity than gEBId – Kaiido Feb 01 '21 at 23:10
  • @ScottMarcus i tried the code below and am now getting an error currentRow.getElementById is not a function – je1013 Feb 01 '21 at 23:12
  • nevermid! fixed the problem, thank you! – je1013 Feb 01 '21 at 23:13
  • @je1013 As you can see when you run my code below, no error is thrown. You are using `currentRow.getElementById()` and my code uses `document.getElementById()`. – Scott Marcus Feb 01 '21 at 23:13
  • @Kaiido It's still simpler than escaping the first char of the `id`. – Scott Marcus Feb 01 '21 at 23:14

1 Answers1

1

Your script is included in the head and executed before the body of the HTML document is parsed, so the elements don't exist yet. Move the script to just before the closing body tag.

Then, use .getElementById() to access your elements that have numbers as the first character in their id. .querySelector() won't work on those ids.

Also, your CSS is incorrect. Instead of:

"5px 'solid black'"

It should be:

"5px solid black"

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="./tictactoe.css">
  </head>
  <body>
    <div class= "header"></div>
    <div class= "main">
      <div id = '0'>
         <div id = "00">r1c1</div>
         <div id = "01">r1c2</div>
         <div id = "02">r1c3</div>
      </div>
      <div id = "1">
         <div id = "10">r2c1</div>
         <div id = "11">r2c2</div>
         <div id = "12">r3c3</div>
      </div>
      <div class = "2">
         <div id = "20">r3c1</div>
         <div id = "21">r3c2</div>
         <div id = "22">r3c3</div>
      </div>
    </div>
        
    <!-- With the script here, all the HTML above will be parsed
         and in memory so you can access the elements. -->
    <script src="tictactoe.js"></script>
    <script>
      var currentRow;
      var rowCol;
      for(let i = 0; i < 3; i++){
          var x = i.toString();
          currentRow = document.getElementById("0");
          for(let j = 0; j < 3; j++){
              y = j.toString();
              rowCol = document.getElementById(x + y);
              if(i == 1){
                rowCol.style.border = "5px solid black";
                rowCol.style.border = "5px solid black";
              } 
              if(j == 0 || j == 1){rowCol.style.border = "5px solid black";}
          }        
      }
    </script>
    </body>
    </html>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71