changing class properties

Discussion in 'Javascript' started by Wim Roffil, Nov 22, 2005.

  1. Wim Roffil

    Wim Roffil Guest

    I have a simple webpage (without stylesheet) where I want to be able to
    switch some parts of the page off. I tried to do this by giving all the
    elements that should be switched off the class "dname" and then to call the
    javascript:
    document.classes.dname.style.display = "none";

    This does not work.

    Can someone suggest me how I could get this to work?

    Thanks, Wim
     
    Wim Roffil, Nov 22, 2005
    #1
    1. Advertisements

  2. Wim Roffil

    VK Guest

    Surprisingly enough DOM still doesn't have
    document.getElementsByClassName() method. It is one of misteries of
    academical thinking I guess. :)

    prototype.js library has an emulation of this method. It is totally
    free to use and destribute and it contains nothing really proprietary
    in it. But as I'm not the first one who wrote this particular piece of
    code, I feel obligated to place the MIT licence notice (so don't get
    scared ;-)

    (c) 2005 Sam Stephenson
    http://prototype.conio.net/
    http://www.opensource.org/licenses/mit-license.php

    document.getElementsByClassName = function(className) {
    var children = document.getElementsByTagName('*') || document.all;
    var elements = new Array();

    for (var i = 0; i < children.length; i++) {
    var child = children;
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
    if (classNames[j] == className) {
    elements.push(child);
    break;
    }
    }
    }
    return elements;
    }
     
    VK, Nov 22, 2005
    #2
    1. Advertisements


  3. There are two ways you could look at this:-

    1. Amend the style sheet through script:-

    I.e. identify your class in a styleSheet thus:-

    <style>
    .myClass {
    }
    </style>

    And access the style sheet thus:-

    function ChangeClassProperty(sClassName,sProperty,sValue)
    {
    sClassName="."+sClassName;
    var sheets = document.styleSheets;
    var rules;
    var styleObj;

    for (var i=sheets.length-1; i >= 0; i--)
    {
    rules=sheets.cssRules || sheets[1].rules;

    for (var j=0; j<ruleList.length; j++)
    {
    if (rules[j].selectorText &&
    rules[j].selectorText==sClassName)
    {
    styleObj=rules[j].style;
    break;
    }
    }
    }

    styleObj[sProperty]=sValue;
    }


    Or alternatively create two style sheets, one with display on and one
    with display off, and switch them using

    styleSheet.disabled

    Regards

    Julian
     
    Julian Turner, Nov 22, 2005
    #3
  4. Wim Roffil

    RobG Guest



    I seems to me if you are going to that much trouble, it should create an
    object that has all the class names as properties and the value of each
    should be an array of references to the elements that have that class.
    It's not dynamic, so any elements added to the document would have to be
    added to the appropriate properties array (or a new one added).

    It would be a kind of classes collection.

    e.g.:

    // Initiallise with a property for elements with no class
    var ClassObj = { noClass:[] };

    function loadClassObj(obj)
    {
    var el, els=obj.childNodes, i=els.length;
    var eClass, eClasses, j;
    while (i--){
    el = els;
    if (el.className){
    eClasses = el.className.split(' ');
    j=eClasses.length;
    while (j--){
    eClass = eClasses[j];
    if (ClassObj[eClass]){
    ClassObj[eClass][ClassObj[eClass].length] = el;
    } else {
    ClassObj[eClass] = [el];
    }
    }
    } else {
    ClassObj.noClass[ClassObj.noClass.length] = el;
    }
    if (el.childNodes){
    loadClassObj(el)
    }
    }
    }

    window.onload = function (){
    var docBody = document.body || document.documentElement;
    loadClassObj(docBody);
    }


    Lightly tested in Firefox & IE, it should work in nearly all browsers,
    but care needs to be taken with class attribute values - only single
    spaces between class names and none before and after (that could be
    fixed with a regExp, but speed may suffer even more). The loadClassObj
    function could be made a method of the ClassObj.

    But I think it would be slow for a big document, a much faster way is to
    modify the class rule directly, but support in various browsers may not
    be sufficient for the OP's purpose. There is a post here:

    <URL:http://groups.google.com/group/comp...nt.styleSheets&rnum=13&hl=en#eeb33edb6af79855>


    A modified version here:

    <URL:http://groups.google.com/group/comp...dify+class+rule+style&rnum=1#f800fd5529ed50b0>


    Some compatibility information is here:

    <URL:http://www.quirksmode.org/dom/w3c_css.html>
     
    RobG, Nov 22, 2005
    #4
  5. This can evaluate to undefined, so you might want to check the result
    before proceeding.
     
    Stephen Chalmers, Nov 22, 2005
    #5
  6. Wim Roffil

    VK Guest

    Sam Stephenson may - I am not Sam Stephenson and I have no relations
    with prototype.js (besides that I used this library occasionally).

    My personal opinion:
    It may evaluate to undefined only if the current browser doesn't
    support neither [getElementsByTagName] method nor [all] collection.
    Let's find one such browser and name it. If it also appears no more
    than 4 years old then we should add it to the Browser Hall of Shame :)
     
    VK, Nov 22, 2005
    #6
  7. Do consider testing support for this before proceeding; your next big
    client could be an Opera fan.
     
    Stephen Chalmers, Nov 22, 2005
    #7
  8. Fair point. Opera 8 does not support the document.styleSheets
    collection so this will not work. It has been on wishlists for at
    least 2 years.

    There is some dirty hack I have seen suggested, involving something
    like:-

    document.getElementsByTagName("style")[0].appendChild(
    document.createTextNode("style sheet contents") );

    which can give access to the stylesheet text node at least.

    But I have not tried it, and goodness knows if it works.

    Regards

    Julian
     
    Julian Turner, Nov 22, 2005
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.