0

I have several classes named .tag on a click/mousedown action I want to either change clear:both to clear:none on all .tag items. Or add the class .clearNone { clear:none; } to all the tags.

What I've tried so far without luck:

function mouseDown(e) {
    window.addEventListener('mousemove', sizePanel, true);

    // Using ID works
    var tagsCol = document.getElementById("tags-col");
    tagsCol.classList.add("width100");

    // Using class does not
    var tag = document.getElementsByClassName("tag");
    tag.classList.add("clearNone");
};

CSS

.tag {
    overflow: hidden;
    float: left;
    position: relative;
    margin: 0 10px 10px 0;
    padding: 5px 10px;
    width: auto;
    cursor: pointer;
    clear: both;
    @include rounded(4px);
}

.clearNone  { clear: none; }

How would you accomplish this? Note there are hundreds of .tag's

Leon Gaban
  • 36,509
  • 115
  • 332
  • 529

3 Answers3

5

Don't do that.

Instead, add a marker classname to a common ancestor element, then use a CSS rule:

.SomeClassName .tag {
    clear: both;
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • What's the JavaScript part? I tried to do that in my code above – Leon Gaban Apr 14 '15 at 16:03
  • 1
    @LeonGaban: Just add that classname to any common ancestor element. – SLaks Apr 14 '15 at 16:03
  • I don't understand, again this is what I just added now: `.clearNone .tag { clear: none; }` now again the javascript I tried is this `tag.classList.add("clearNone");` which does not work. :( – Leon Gaban Apr 14 '15 at 16:06
  • Do you understand what that selector means? You need to add that class to an element that contains all of the `.tag`s. – SLaks Apr 14 '15 at 16:16
3

To fix your issue directly, you need to loop over the returned elements:

var tags = document.getElementsByClassName("tag");
for (var x = 0; x < tags.length; x++)
    tags[x].classList.add("clearNone");

But as with Slaks' answer, there is a better way of accomplishing this.

Community
  • 1
  • 1
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
  • thx, getting this error btw `Uncaught TypeError: Cannot read property 'add' of undefinedapp.min.js:18 d` on the classList.add part, not sure why as I didn't get that on the `id` code. – Leon Gaban Apr 14 '15 at 16:01
  • @Leon Not sure why - [it should work fine](http://jsfiddle.net/JamesThorpe/nxe00kmu/) – James Thorpe Apr 14 '15 at 16:04
  • @JamesThorpe the `.classList` property isn't supported on older browsers. – Pointy Apr 14 '15 at 16:04
  • @Pointy The OP said it worked for him with `getElementById`, so I was working with that. The issue isn't so much about `classList`, but rather the fact it was being applied to a collection rather than individual elements. – James Thorpe Apr 14 '15 at 16:05
  • Ah yes I got this working now thanks! I have no idea how to implement @SLaks answer :( it's just the CSS part and I already have that, it's the JavaScript part I was missing... also I needed to add !important `.clearNone { clear: none !important; }` – Leon Gaban Apr 14 '15 at 16:09
  • 1
    @LeonGaban just `document.body.classList.add("someClassName")` - it'll be much faster if you have lots of `.tag` elements. – Pointy Apr 14 '15 at 16:15
1

you can try the following code (edit thanks @Bergi)

var tags = document.getElementsByClassName("tag");
for(var i=0; i<tags.length; ++i){ 
  if(typeof tags[i] === "object" && "classList" in tags[i]){
    tags[i].classList.add("clearNone");
  }
}
Jose Ricardo Bustos M.
  • 8,016
  • 6
  • 40
  • 62
  • 2
    [Don't use `for in` enumerations on array-like objects!](http://stackoverflow.com/q/500504/1048572) – Bergi Apr 14 '15 at 16:13
  • thanks @Bergi [link](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea) ..... i did not know, is considered a bad practice – Jose Ricardo Bustos M. Apr 14 '15 at 16:38