7

I want to add only one css style in JS. I don't want to include jQuery for only one thing.

My code:

document.addEventListener('DOMContentLoaded', function() {
    if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
        var productAttr = document.getElementsByClassName('product-attributes');
        productAttr.style.top = "-90px";
    }
});

The error from console is:

TypeError: 'undefined' is not an object (evaluating 'productAttr.style.top = "-90px"')

If I want change other styles f.e. opacity or color, I get the same problem.

How can I fix this ?

Thanks in advance for help.

Roberto Pegoraro
  • 1,313
  • 2
  • 16
  • 31
Robson
  • 1,207
  • 3
  • 21
  • 43
  • Possible duplicate of [How to change css property using javascript](http://stackoverflow.com/questions/15241915/how-to-change-css-property-using-javascript) – 8eecf0d2 Feb 16 '16 at 13:14
  • 1
    getElementsByClassName returns a collection of matching elements, not a single object – DanielS Feb 16 '16 at 13:15

4 Answers4

4

You need to loop through your results because getElementsByClassName() returns a collection of elements:

for(var i = 0; i < productAttr.length; i++)
{
    productAttr[i].style.top = "-90px";
}
brso05
  • 13,142
  • 2
  • 21
  • 40
0

Maybe it's because you can not give negative values in CSS

top:"-90px" === bottom "90px"

Maybe now it would work

document.addEventListener('DOMContentLoaded', function() {
    if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
        var productAttr = document.getElementsByClassName('product-attributes');
        productAttr.style.bottom = "90px";
    }
});
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
-1

It's preferred to have an id assigned to the targeted element then target using getElementById() as there cannot be elements with the same id, hence getElementByClassName() will return an array if there are multiple elements with the same className. If you need to target multiple elements, you should for-loop through them while applying the change to the nth item being looped:

for(x = 0; x < array.length; x++){
    array[x].style.top = '-90px';
}

Gentle reminder: also remember to have position: relative|absolute|fixed to ensure 'top' attribute works

edited with thanks to Sebastien Daniel

zehata
  • 3,354
  • 2
  • 14
  • 23
  • 1
    when using `getElementsByClassName()` you're obtianing a COLLECTION (i.e. an array-like structure). Your above code will generate an error because an HTML collection does NOT have the style property. In addition, setting style via the style property is discouraged and you should use `element.setAttribute("style", "value");` – Sebastien Daniel Feb 16 '16 at 13:55
  • So its better to change the element to have an id, then target the element by id? – zehata Feb 16 '16 at 13:59
  • Not necessarily, it all depends on your use-case. If your target is UNIQUE, then using #id and `getElementById()` is preferrable. However, if you have multiple elements that need to be adjusted (*That share a className, for example*), then using `getElementsByClassName()` will allow you to grab them all and iterate over them with whichever process those elements need to go through. – Sebastien Daniel Feb 16 '16 at 14:01
  • Ok, thanks, I added id instead class, and it works. Thanks – Robson Feb 16 '16 at 16:57
-1

When selecting a class you have to indicate what number is as an Tag, it is not like the id that there is only one.

It would be something like this code depending on which of the classes you want to apply it:

document.addEventListener('DOMContentLoaded', function() {
    if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
        var productAttr = document.getElementsByClassName('product-attributes');
        productAttr[0].style.top = "-90px";
        productAttr[1].style.top = "-90px";
        productAttr[2].style.top = "-90px";
    }
});
PedroZGZ
  • 1
  • 2