0

Okay, I had to re-word this to make better sense of what I was asking.

So I have a block filled with divs, and I want to cause them to change color if clicked. So, if I use an inline reference with this the function works properly.

<html><head><style>
body       {font-family:"BACKTO1982", System, san serif; background-color:#666; font-weight: normal; font-size: normal; padding: 0; margin: 0; height: 100%; min-height: 700px; width: 100%; min-width: 800px; overflow: hidden;} 
#theBlock  {position:relative; height: 640px; width: 800px; margin:20px auto 20px auto; padding:0; overflow:hidden;} 
.blocks    {height:12px;width:12px;border:1px solid #eee;background-color:#ffffff;margin:0;padding:0;display:inline-block;}
</style><script>
x = 0;
window.onload = function(){
  for(i=0;i<3200;i++){
    var newBlock = document.createElement('div');
    newBlock.setAttribute('class', 'blocks');
    newBlock.setAttribute('id','blockId'+x);
    newBlock.setAttribute('onclick','change(this);');
    document.getElementById('theBlock').appendChild(newBlock);
    x++;
  }
}
function change(x){
  x.style.backgroundColor = '#000000';
}
</script></head><body><div id="theBlock"></div></body></html>

However as inline Javascript is not the cleanest way to code, so I attempted to make a function using a this reference, in place of change() like so:

document.getElementsByClassName('blocks').onclick = function(){
  this.style.backgroundColor = "#000000";
}

But this function seems to not really do anything. I am not sure if this is a matter of it not properly referencing the object, or is malformed, but my console doesn't seem to find any issue with it, it just doesn't work.

Hopefully this makes more sense than my first attempt at this question.

2 Answers 2

3

EDIT: Changed event listener code, as per suggested in comment.

document.getElementsByClassName('blocks') is a array NodeList containing all the elements with the class blocks. So you can't add one even listener to all of them.

Try this:

var arr = document.getElementsByClassName('blocks');
var len = arr.length;
var toBlack = function() {this.style.backgroundColor = '#000000';}
for (var i=0; i<len; i++) {
  arr[i].onclick = toBlack;
}

This loops through the array NodeList and attaches an event listener to each element.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 But it would be better to store the event handler in a variable before the loop; otherwise, at each iteration a new duplicated function is created. And to be precise, getElementsByClassName returns a NodeList instance, which is array-like, but not an array.
@Oriol Done. Also, good to know regarding NodeList distinction. Thank you.
1
//newBlock.setAttribute('onclick','change(this);');
        newBlock.onclick = change;
...    ....
function change() {
  this.style.backgroundColor = '#000000';
}

But as i test your code, it's working on IE9 on my PC.

3 Comments

I like the idea here, but it is throwing errors on Chrome. I think it is referencing the local variable outside of the scope of the function.
@ThomasCheney—it should work fine in Chrome too. Don't use the setAttribute version, stick to assigning to properties.
I thought it didn't work on my Chrome because of the use of the variable name newBlock, which was only a temp name, but I may have made an error, because it prevented all blocks from rendering to the page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.