-1

My current code creates a grid with span elements that have a class name of gridsquare. I'm trying to figure out how to apply styling to all of them. I keep getting the error TypeError: size.style is undefined. I have the function set to run after the elements are created, not sure what's going on...

let n=16;
let boxSize = 720/n;

function grid(){
  for(var i = 1; i < n; i++) {
    document.getElementById('container').innerHTML+='<div class="row">'

    for(k = 0; k < n; k++) {
       document.getElementById('container').innerHTML+='<span class="gridsquare">as</span>'; 
    } 
  }
  gridSize() 
}

function gridSize(){
  let size = document.getElementsByClassName("gridsquare")
    size.style.height = boxSize;
    size.style.width = boxSize; 
}
grid()
Jacob Moore
  • 277
  • 2
  • 12
  • [*getElementsByClassName*](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) returns an [*HTMLCollection*](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection), you need to get the items one at a time (e.g. `Array.from(size).forEach(...)`). You can't set a style property value on multiple elements in one go unless they all have the same class and you modify the class rules, see [*Changing a CSS rule-set from Javascript*](https://stackoverflow.com/questions/1409225/changing-a-css-rule-set-from-javascript). – RobG Jan 10 '18 at 04:16

2 Answers2

0

this give you array try using like

function gridSize(){
  let size = document.getElementsByClassName("gridsquare")
    size[0].style.height = boxSize;
    size[0].style.width = boxSize; 
}
Hemant Rajpoot
  • 683
  • 1
  • 11
  • 29
0

You have to use index while using getElementsByClassName because getElementsByClassName returns node collections.

size[0].style.width = boxSize;
size[0].style.width = boxSize;

Working snippet: By using querySelectorAll()

let n=16;
let boxSize = 720/n;

function grid(){
  for(var i = 1; i < n; i++) {
    document.getElementById('container').innerHTML+='<div class="row">'

    for(k = 0; k < n; k++) {
       document.getElementById('container').innerHTML+='<span class="gridsquare">as</span>'; 
    } 
  }
  gridSize(); 
}

function gridSize(){
  let boxSize = '20px';
  let size = document.querySelectorAll(".gridsquare");
  size.forEach(function(spanEl){
      spanEl.style.height = boxSize;
      spanEl.style.width = boxSize;
      spanEl.style.display = 'inline-block';
  });
}
grid();
<div id="container"></div>

OR: If you want to use getElementsByClassName()

let n=16;
let boxSize = 720/n;

function grid(){
  for(var i = 1; i < n; i++) {
    document.getElementById('container').innerHTML+='<div class="row">'

    for(k = 0; k < n; k++) {
       document.getElementById('container').innerHTML+='<span class="gridsquare">as</span>'; 
    } 
  }
  gridSize(); 
}

function gridSize(){
  let boxSize = '20px';
  let size = document.getElementsByClassName("gridsquare");
  [].forEach.call(size, function(spanEl){
      spanEl.style.height = boxSize;
      spanEl.style.width = boxSize;
      spanEl.style.display = 'inline-block';
  });
}
grid();
<div id="container"></div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
  • [0] index only selects the first element. I tried the .every method but gave me my original error. I'm trying to select all of them. – Jacob Moore Jan 10 '18 at 04:13
  • @JacobMoore, I have updated my answer...please check. – Mamun Jan 10 '18 at 04:20
  • @JacobMoore, plaese note I have used `querySelectorAll()` instead of `getElementsByClassName()` to loop through all the `span`. – Mamun Jan 10 '18 at 04:25
  • Note that the *forEach* method of [*HTMLCollections*](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) is not standardised or implemented widely. It has been standardised for [*NodeList*](https://developer.mozilla.org/en-US/docs/Web/API/NodeList) but not all browsers have their HTMLCollection inherit from NodeList. – RobG Jan 10 '18 at 04:26
  • Awesome, the querySelector returns an array and you iterate through each element and apply the style. – Jacob Moore Jan 10 '18 at 04:26
  • Could you not have just looped through getElementsByClassName? – Jacob Moore Jan 10 '18 at 04:27
  • @JacobMoore, do u prefer that? let me try.. – Mamun Jan 10 '18 at 04:29
  • No i was just wondering, I assumed they both return an array and it would not make a difference. – Jacob Moore Jan 10 '18 at 04:30
  • @RobG What is the standard iteration method then? – Jacob Moore Jan 10 '18 at 04:32
  • @JacobMoore, some older browsers yet to support `querySelectorAll()`. In that case you can use the second example I have added with `getElementsByClassName()`. – Mamun Jan 10 '18 at 04:45
  • @RobG, I have added another solution with `[].forEach(...`. Did you mention that as the standard iteration method? – Mamun Jan 10 '18 at 04:52
  • 1
    @JacobMoore—the usual way was a for loop, but there is also `Array.from(list).forEach(...)` and `[].forEach.call(list, ...)` as you've done. Just remember that *getElementsByClassName* doesn't return an Array, it returns a list that which is similar to an array but doesn't have Array methods. – RobG Jan 10 '18 at 05:02
  • @RobG, thanks for helping me to improve my answer. – Mamun Jan 10 '18 at 05:04