Wednesday, May 30, 2012

Change an element"s CSS class with JavaScript


How can I change a CSS class of an HTML element in response to an onClick event using JavaScript?



Source: Tips4all

14 comments:

  1. To add a class to an element:

    document.getElementById("MyElement").className += " MyClass";


    To remove a class from an element:

    document.getElementById("MyElement").className =
    document.getElementById("MyElement").className.replace
    ( /(?:^|\s)MyClass(?!\S)/ , '' )
    /* code wrapped for readability - above is all one statement */


    To do that in an onclick event:

    <script type="text/javascript">
    function changeClass()
    {
    // code examples from above
    }
    </script>
    ...
    <button onclick="changeClass()">My Button</button>




    Better yet, use a framework (in this example jQuery) which allows you to do the following:

    $j('#MyElement').addClass('MyClass');

    $j('#MyElement').removeClass('MyClass');

    $j('#MyElement').toggleClass('MyClass');


    And also:

    <script type="text/javascript">
    function changeClass()
    {
    // code examples from above
    }

    $j(':button:contains(My Button)').click(changeClass);
    </script>
    ...
    <button>My Button</button>


    This is separating HTML markup from your JS interaction logic, which is something that - especially on large/complex applications - can make maintenance significantly easier.

    ReplyDelete
  2. You could also just do:


    document.getElementById('id').classList.add('class');
    document.getElementById('id').classList.remove('class');

    ReplyDelete
  3. You can use node.className like so:


    document.getElementById("blah").className = "cssclass";

    ReplyDelete
  4. In one of my old projects that did not use jQuery, I built the following functions for adding, removing, and checking if element has class:

    function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
    }
    function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
    }
    function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
    }
    }


    So, for example, if I want onclick to add some class the the button I can use this:

    <script type="text/javascript">
    function changeClass(btn, cls)
    {
    if(!hasClass(btn, cls))
    {
    addClass(btn, cls);
    }
    }
    </script>
    ...
    <button onclick="changeClass(this, "someClass")">My Button</button>


    By now for sure it would just better to use jQuery.

    ReplyDelete
  5. Pure JS:

    function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
    }
    function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
    }
    function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
    }
    }
    function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
    removeClass(ele, oldClass);
    addClass(ele, newClass);
    }
    return;
    }

    function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
    replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
    replaceClass(ele, cls2, cls1);
    }else{
    addClass(ele, cls1);
    }
    }

    ReplyDelete
  6. Wow, surprised there are so many overkill answers here...

    <div class="firstClass" onclick="this.className='secondClass'">

    ReplyDelete
  7. it's working for me. So i am sharing my answer.

    function setCSS(eleID) {

    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
    }


    Thanx.

    ReplyDelete
  8. Just to add on information from another popular framework, Google Closures, see their dom/classes class:

    goog.dom.classes.add(element, var_args)

    goog.dom.classes.addRemove(element, classesToRemove, classesToAdd)

    goog.dom.classes.remove(element, var_args)


    One option for selecting the element is using goog.dom.query with a CSS3 selector:

    var myElement = goog.dom.query("#MyElement")[0];

    ReplyDelete
  9. Couple of minor notes and tweaks on the regex from above:

    You'll want to do it globally in case the class list has the class name more than once. And, you'll probably want to strip spaces from the ends of the class list and convert multiple spaces to one space to keep from getting runs of spaces. None of these things should be a problem if the only code dinking with the class names uses the regex below and removes a name before adding it. But. Well, who knows who might be dinking with the class name list.

    This regex is case insensitive so that bugs in class names may show up before the code is used on a browser that doesn't care about case in class names.

    var s = "testing one four one two";
    var cls = "one";
    var rg = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
    alert("[" + s.replace(rg, ' ') + "]");
    var cls = "test";
    var rg = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
    alert("[" + s.replace(rg, ' ') + "]");
    var cls = "testing";
    var rg = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
    alert("[" + s.replace(rg, ' ') + "]");
    var cls = "tWo";
    var rg = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
    alert("[" + s.replace(rg, ' ') + "]");

    ReplyDelete
  10. The line

    document.getElementById("MyElement").className = document.getElementById("MyElement").className.replace(/\bMyClass\b/','')


    should be:

    document.getElementById("MyElement").className = document.getElementById("MyElement").className.replace('/\bMyClass\b/','');

    ReplyDelete
  11. Change an element's CSS class with JavaScript in ASP.Net

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
    lbSave.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
    lbSave.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
    lbCancel.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
    lbCancel.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
    End If
    End Sub

    ReplyDelete
  12. I would use jQuery and write something like this:

    jQuery(function() {
    jQuery("#some-element").click(function() {
    jQuery(this).toggleClass("clicked");
    });
    });


    This code adds a function to be called when an element of the id some-element is clicked. The function appends clicked to the element's class attribute if it's not already part of it, and removes it if it's there.

    Yes you do need to add a reference to the jQuery library in your page to use this code, but at least you can feel confident the most functions in the library would work on pretty much all the modern browsers, and it will save you time implementing your own code to do the same.

    Thanks

    ReplyDelete
  13. This is easiest with a library like jQuery:

    <input type="button" onClick="javascript:test_byid();" value="id='second'" />

    <script>
    function test_byid()
    {
    $("#second").toggleClass("highlight");
    }
    </script>

    ReplyDelete
  14. No offense, but it's unclever to change class on-the-fly as it forces the CSS interpreter to recalculate the visual presentation of the entire web page.

    The reason is that it is nearly impossible for the CSS interpreter to know if any inheritance or cascading could be changed, so the short answer is:

    Never ever change className on-the-fly !-)

    But usually you'll only need to change a property or two, and that is easily implemented:

    function highlight(elm){
    elm.style.backgroundColor ="#345";
    elm.style.color = "#fff";
    }

    ReplyDelete