-2

I try to write a simple javascript function, which contains default options. These should be customizable while calling the function.

My code does not work. Whats the problem in here?

var options = [{
  selector: '.test',
  color: '#c3c3c3'
}]

document.querySelectorAll(options.selector).style.backgroundColor = options.color

JSBIN DEMO

Marian Rick
  • 3,350
  • 4
  • 31
  • 67

3 Answers3

1

options is an array of objects. You should access it like this options[index].property:

var options = [{
  selector: '.test',
  color: '#c3c3c3'
}];

document.querySelectorAll(options[0].selector)[0].style.backgroundColor = options[0].color;

If you only care to have one set of default options, you could have a single object instead:

var options = {
  selector: '.test',
  color: '#c3c3c3'
};

Finally, querySelectorAll(...) returns an array, so you must also access it with brackets (querySelectorAll(...)[index]):

document.addEventListener("DOMContentLoaded", function(event) { 
  
  var options = [{
    selector: '#test'
  }];

  document.querySelectorAll(options[0].selector)[0].style.display = 'none';

});
<div id="test">
  This should be hidden
</div>
JCOC611
  • 19,111
  • 14
  • 69
  • 90
  • [`querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) also returns an `Array`. So you are trying to change an `Array`'s `style` property. – zero298 Nov 08 '17 at 20:30
  • This will throw a `TypeError` because `.style` is undefined since `querySelectorAll` will return an array. – Chin Leung Nov 08 '17 at 20:30
  • This line: `document.querySelectorAll(options[0].selector).style.backgroundColor = options[0].color;` in your answer is still wrong. – zero298 Nov 08 '17 at 20:36
1

A couple of problems:

"options" in your code is an array, which doesn't make a lot of sense. I've changed it to a single object, without the array.

Also, document.querySelectorAll returns a list of elements. A list doesn't have a "style" attribute, but the elements within the list do. Therefore you have to loop through them in order to make the change to each one:

document.addEventListener("DOMContentLoaded", function(event) {

  var options = {
    selector: '.test',
    color: '#c3c3c3'
  };

  document.querySelectorAll(options.selector).forEach(function(element) {
    element.style.backgroundColor = options.color;
  });

});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <title>JS Bin</title>
</head>

<body>
  <div class="test">
    This should be #c3c3c3
  </div>
  <div class="test">
    This should be #c3c3c3
  </div>
  <div class="test">
    This should be #c3c3c3
  </div>
  <div class="test">
    This should be #c3c3c3
  </div>
</body>

</html>

As noted in the comments, not all browser support forEach on a nodeList (as returned by querySelectorAll). In that case you could easily substitute it with a standard for loop, like this:

var elements = document.querySelectorAll(options.selector);
for (var i = 0; i < elements.length; ++i) {
  elements[i].style.backgroundColor = options.color;
}
ADyson
  • 57,178
  • 14
  • 51
  • 63
  • I am sorry, while the stack thread code was correct, the jsbin snapshot was the wrong one. I have fixed that. For the quality of stack it would be great, if you either could update or remove your answer based on the wrong code. Again sorry for any troubles. – Marian Rick Nov 08 '17 at 20:31
  • @MarianRick I was literally doing it as you wrote your comment - see the update now – ADyson Nov 08 '17 at 20:32
  • Don't use `forEach` directly on a NodeList: https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/ – zero298 Nov 08 '17 at 20:32
  • @zero298 fair point. Have added an alternative using a `for` loop if browser support is an issue. – ADyson Nov 08 '17 at 20:36
  • As you are using a `es6` selector (at least I think it is), it may be a good solution to use `Array.from(querySelectorAll()).forEach()` as clean and simple solution. – Marian Rick Nov 08 '17 at 20:39
  • @MarianRick Array.from support is still patchy, especially in IE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from – ADyson Nov 08 '17 at 20:56
0

You probably want to change the color for one option at a time. And querySelectorAll return an array. So you also want to loop through the results of that function.

var options = [{
  selector: '.test',
  color: '#c3c3c3'
}];

options.forEach(o => {
  var domElements = document.querySelectorAll(o.selector);
  domElements.forEach(d => d.style.backgroundColor = o.color);
});
Steven Wexler
  • 16,589
  • 8
  • 53
  • 80