2

Here's my css class:

.my-css-class-name
{
    display: block;
}

And I have one element at my webpage that uses this class. I want to modify this element's "display" property.
I would happily do this by getting a handle to that element and then modifying what I need, BUT, I don't know the element's name - it's being randomly generated (it's a third-party extension).

So I figured I'm gonna have to get a handle to ".my-css-class-name" and modify that property directly.
How do I get there, cross-browser (major ones) solution?

Edit #1:
I'm looking for compatibility with newer browsers.

user113716
  • 318,772
  • 63
  • 451
  • 440
Poni
  • 11,061
  • 25
  • 80
  • 121
  • Using any javascript framework? Jquery, Mootools etc? – DeaconDesperado Dec 14 '10 at 14:30
  • is it being randomly generated in a way that a well crafted regex could catch? – Matt Phillips Dec 14 '10 at 14:30
  • @DeaconDesperado I have no clue about js frameworks although I do know this element is being generated by jQuery. – Poni Dec 14 '10 at 14:38
  • @Matt its id is a random number which I doubt any regex can catch/predict it. Since I don't know if it's "pure" random number I don't want to take the risk and rather simply change the css rule. – Poni Dec 14 '10 at 14:39
  • @Poni: Since jQuery seems to be loaded, you should use it. Its browser compatibility is one of its most compelling features. – user113716 Dec 14 '10 at 14:56
  • @patrick I'm sure of that and that's why I'm trying to do so, as some suggested here in the answers. – Poni Dec 14 '10 at 14:57

5 Answers5

5

Well, theoretically, it's easy.

document.getElementsByClassName("my-css-class-name")[0].style.display = "something";

In case you need IE compatibility:

/*
    Developed by Robert Nyman, http://www.robertnyman.com
    Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/
var getElementsByClassName = function (className, tag/* "a","div",... */, elm/*parent*/){
    if (document.getElementsByClassName) {
        getElementsByClassName = function (className, tag, elm) {
            elm = elm || document;
            var elements = elm.getElementsByClassName(className),
                nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
                returnElements = [],
                current;
            for(var i=0, il=elements.length; i<il; i+=1){
                current = elements[i];
                if(!nodeName || nodeName.test(current.nodeName)) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        };
    }
    else if (document.evaluate) {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = "",
                xhtmlNamespace = "http://www.w3.org/1999/xhtml",
                namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
                returnElements = [],
                elements,
                node;
            for(var j=0, jl=classes.length; j<jl; j+=1){
                classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
            }
            try {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
            }
            catch (e) {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
            }
            while ((node = elements.iterateNext())) {
                returnElements.push(node);
            }
            return returnElements;
        };
    }
    else {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = [],
                elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
                current,
                returnElements = [],
                match;
            for(var k=0, kl=classes.length; k<kl; k+=1){
                classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
            }
            for(var l=0, ll=elements.length; l<ll; l+=1){
                current = elements[l];
                match = false;
                for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
                    match = classesToCheck[m].test(current.className);
                    if (!match) {
                        break;
                    }
                }
                if (match) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        };
    }
    return getElementsByClassName(className, tag, elm);
};

getElementsByClassName("my-css-class-name")[0].style.display = "something";
thejh
  • 44,854
  • 16
  • 96
  • 107
3

Following your response in the comment, if the element is being generated by Jquery, then the library is most likely installed. Here is something you can try to select it via Jquery and change the require property.

$(document).ready( function(){    
$('.my-class-name').css('display', 'block');
});

Substituting 'block' for whatever setting you require.

If Jquery is included it should do what your require on page load. You can also attach it to other events as well.

$(document).ready(function(){
$('.my-class-name').click(classClicked);
})

function classClicked(){
$(this).css('display','block')
}
DeaconDesperado
  • 9,977
  • 9
  • 47
  • 77
  • +1 Since jQuery seems to be installed, this would be the way to go, although you can't necessarily assume that `$` is associated with jQuery. To be safe, I'd use the full `jQuery` variable, or wrap the code in `(function($){ /* the jQuery code */ })(jQuery);` – user113716 Dec 14 '10 at 14:52
  • Thanks for the assist patrick, I often forget to mention the aliasing when posting JQ here since so many of the examples at the framework homepage just use it by default. – DeaconDesperado Dec 14 '10 at 15:21
  • @Deacon: Yeah, normally it could be assumed, but in this case it seemed uncertain as to who/what exactly was loading the library, so the state of `$` seemed uncertain as well. :o) – user113716 Dec 14 '10 at 15:27
  • @patrick you got me interested! By your first comment, what do you mean by saying "you can't necessarily assume that $ is associated with jQuery"? Consider the fact I don't know a lot about JS. Shall I open a whole new question or can this be answered briefly? Thanks. – Poni Dec 14 '10 at 15:58
  • 1
    Basically, the dollar sign is the default alias for jQuery. In complex applications that make use of a ton of different jQuery plugins (or just have tons of vanilla javascript for that matter) the $ alias can be used elsewhere outside the scope of the immediate file and be utilized by some other library for another purpose. It is for this reason always good practice to make your own alias for jQuery and then wrap it all up setting the $ to that reference the way Patrick described to avoid collisions. – DeaconDesperado Dec 14 '10 at 16:10
  • 2
    @Poni: What DeaconDesperado described is correct. I'd explain it like this. The `$` is just a plain old global variable, as in `window.$`. It would be the same as creating any other global variable `window.myName = "patrick_dw"`. The main global variable referencing the jQuery library is `window.jQuery`. But they use the `window.$` variable as a shortcut. So essentially, `window.$ = window.jQuery`. The problem is that this (unfortunately) is a widely used practice among javascript library developers, so if you happen to use more than one library, one may overwrite the value of `window.$`. – user113716 Dec 14 '10 at 17:48
  • 2
    ...So say you load `jQuery`, but then you load the `prototypejs` library. jQuery will first use `window.$` to reference it self, but then prototypejs will overwrite `window.$` with its own reference to itself. jQuery offers the capability to reassign itself to something other than `window.$` in order to resolve such a conflict. Since it seemed as though you may not have been the one loading jQuery, it could be that jQuery had been reassigned to a different shortcut (or none at all) without your knowledge. Hope that helps. :o) – user113716 Dec 14 '10 at 17:48
  • Actually your both answer were good - I'm glad you came two came by!! Thankss! – Poni Dec 14 '10 at 21:02
0

getElementByClassName is not possible (in older browsers) but there are work arounds including iterating through every element. See here for discussion Do we have getElementsByClassName in javascript?

Community
  • 1
  • 1
Matt Asbury
  • 5,644
  • 2
  • 21
  • 29
0

Some newer browsers support document.getElementsByClassName right out of the box. Older browsers do not and you have to use a function that loops through the elements of the page.

epascarello
  • 204,599
  • 20
  • 195
  • 236
0

A flexible getElementsByClassName function with support for browser versions that do not support the native function as thejh suggested may be what you are looking for. It would work, at least. However, for what you are doing, it may be useful to look at the document.styleSheets property. With this route, you can change the CSS rule directly, which, if it worked consistently across browsers, would be the better route here. Unfortunately, browser compatibility in this area is far from consistent, as shown here: http://www.quirksmode.org/dom/w3c_css.html

If you are still interested, have a look at this question: Changing a CSS rule-set from Javascript

Community
  • 1
  • 1
Stephen Booher
  • 6,522
  • 4
  • 34
  • 50