ON THE STYLE SHEETS OBJECT(s)
|
|
What style sheets are?
What the new DOM and JavaScript objects do, and how it all can help you
|
[ NOTE: another very interesting style sheet manipulation function is located here: it finds the prevailing class properties for a layer knowing only the id of the layer, and that function takes into consideration also the notation - see that referred file for implementation and for the details. ]
Tis is serious stuff, bud.
Probably you already know what style sheets are. Since before using these scripts you should have steadfast understanding about what style sheets are meant to accomplish, here's the deal.
Whereas the traditional html affects only single elements on a page, style sheets are a way to affect all of the html tags in a page (by affecting we mean that once pinpointed the tag groupings you want to alter, all which is inside them, from colors to sizes to page dispatchment, can be changed on the fly!) either as
- ALL: A whole
- SPECIFIC (ID): Pinpointing only some specific elements (tag) to which it has been assigned an id property (<table ... id="aUniqueName">) - I guess that the id keyword just stands for IDentificative.
- GROUPS (CLASS): Affecting only some sectors of the page, namely only those tags which share the same property called class: <table class="aNameHere">.
In other words the tag attribute named ID is used to localize one element and single it out from all the rest, whereas the tag attribute named class is meant to let you identify the tag as belonging to a whole set of elements (other tags, that is) that share the same value name assigned as their class attribute.
INHERITANCE THE STYLE SHEETS WAY |
 |
 |
 |
 |
 |
 |
If you have some scripting experience, maybe it is enlightening if I stress for you that you should consider those tags that - carry the class attribute defined in within the tag
- and such class value is set to a name as its value
like instances of that class whose name is matching that name.
If you have no programming experience, this may sound not that much terrific piece of a statement to you; but if you do, and you've been tackling style sheet only recently, this may sound interesting to you.
The original template, or prototype, of such class is the rule definition in the css file whose name (technically called selector, just to be sure things can be confusing enough for us...) matches with the value of the class property expressed in the tag.
So in a style sheet you have:
- Classes, also called rules. These classes can affect:
- ALL instances of SOME TAG TYPE namely all those tags in a document that match the tag name provided in the rule. Example of such a rule:
- ONLY specific tags carrying a class pointer namely those tags that have a class attribute specified (<table class="aClass"...>).
In such case the definition of such aClass like it appears in the style sheet must have the same aClass name but also with a pre pended a dot (in fact if you omit the dot, the style sheet would assume you're not going to mean to pinpoint only those tags that carry a class attribute matching with such definition, but all tags that, even without a class attribute whatsoever, match the name: in other words without the dot the script would look for tags like: <aClass> !).
- Inside the classes you have:
- The class name (selector: actually it is slightly different than a name, so perhaps thence this new technical term: in fact a selector is more than a mere name: it can be a collection of names, like: , which would mean: address -pick, sift out,... select!- all the tags that are either div or table or images, and apply to them the specifications that follows this "selector name" )
- What follows the selector, is called the (associative collection of the) declarations (they can be either none -an empty shell- or just one or, in all likelihood, many each separated from the next one by a semi colon), and of course declarations go in pairs:
- Property (such as color): there is a list of available properties, so far if I am not mistaken about 50.
- Value (such as #000000 for black): a property can accept only some type of data (that is: a property fit to express a measurement, cannot hold as its value "Hi man!")
- The whole of the two above (selector plus its declarations) are also called the definition of the class, or just the class itself (and the class can also be called rule...).
So such original template (any class in a style sheet) contains all the declarations of property/value pairs meant to affect and characterize the page objects (tags, in our case, reflecting themselves in immediate layout effects) that partake with such class (rule).
Therefore style sheet classes are a way to propagate an hereditary liaison (like every class does) but this time not by creating independent new instances from a template like in Java and OOP, but by providing them with a label (an ID or the tag name) which is as a pointer to the prototype (rule) of the class.
Therefore this type of inheritance cannot relinquish real copies of the prototype that inherit from the template and then walk their lives, but conversely is an inheritance where the instances must reflect whatever change the prototype may undergo (and must reflect it immediately, indeed like a pointer does), and they never gain independence from it: it is not a copy that as such can live its own life in the aftermath of its generation and for instance change the nature of the properties it had bequeathed from the template, but it is nearly the same thing than the template itself; it has never really be "drawn" from it, and cannot produce such evident emancipations as Java template copies do, or like my ULMA template copies do insofar they can even add methods on the fly that never belonged to the class definition they originated from.
I'd call style sheets inheritance a form of rigid inheritance. |
 |
 |
 |
 |
 |
 |
- SOME tags: Selecting only some types of tags, such as say all tags like <table>
The difference between addressing a group by tag names or by class definitions is merely an overloaded chance: if you have a class you'd preferably address the elements as a class, but if by chance you've not defined classes, you can also affect them by locating the tag types to involve.
The good thing is that by having at your disposal groups that you can address both through the class and the tag names, you could even device your own scripting ways to traverse and criss-cross those groupings with changes of the formattings: in fact a tag can even have both style sheets definitions affecting it as a tag, and a class attribute specification pointing to another style sheet rule meant for it.
In case they address the same tag properties, the latter prevails (the class pointed by the class attribute prevails on the class pointed by the tag type...).
Therefore style sheets are a way to dynamically alter the format of a page:
- On the fly, by instructions that upon some events (like, for instance, onClick of some link or button or onMouseOver of the contents included in between a open/close tag pair, and the alike) can trigger scripts (by JavaScript or ECMAScript, which are nearly the same thing for they're both standard compliant: ECMA is the standard itself, and JavaScript is fully compliant! something you cannot say in regard of, for instance, VBScript), and these scripts can instruct the style sheets (the collections of the definitions meant to address the elements in a page as outlined above) to change some properties, changes whose nature would be instantaneously reflected in the page and in each concerned element (tag).
- You can do this without refreshing/reloading the page.
This is certainly and by far the greatest feature, because originally html was meant to be completely static so the only way to have a different page was... to call in a new page and wait for it being downloaded from the server it got freshly and anew requested from.
 |
 |
 |
 |
 |
 |
ASP.NET vs ASP vs STYLE SHEETS |
Let me highlight one thing at this stage.
There is a newly developed server side language called ASP.NET
This language (although I am myself a great supporter of its lesser version, called just ASP) has been introduced, with a full fledged new syntax full of quirks and complex enough to make you wonder what was the point of inventing thousands of new keywords for a purpose that is not fulfilled: in fact the presumption was it would have let you turn a web page into an application (if you change something in a program, you don't have to... restart the program in order to see the newly generated status/layout).
Let me say this allegation by ASP.NET (that is, that ASP.NET transforms web pages in applications) is entirely untrue.
By ASP.NET whenever you have a script, you include the attribute runat="server" and thus the script commands are not parsed on your page but on the server; but guess what: to let this happen you have to submit the page to the server, and the server in order to make your changes appear on your screen has to... send to you a brand new page as usual: now, wouldn't you agree with me if I'd say: where's the claimed advantage, man? You're just reproducing the usual, traditional server/client paradigm with the only difference that some scripts are run on the server: so what?
Not a big deal, particularly when compared with the requested effort to cut it: learning books already as thick as 1,600 pages, each and all introducing new syntaxes to do precisely the same old things, and at least in one instance simply to jumble out a neat table grid you could already do by traditional means: but ASP.NET does it... using 10 lines of code less! wow, that's a deal...- plus this runat server thing which, honestly, does nothing so terrific worth telling home, despite the drumbeat.
In fact the real advantage would have been there if in order to deliver the command to the server, I would have been able to do this just by sending through only the command itself funneling it on an independent socket inside my connection, and therefore without refreshing my page with a mainstream page submission; and the server could have responded through the same tunnel and could have sent back to me the server side script outputs and, delivering the latter ones to the originally meant and pointed page elements, by this it would have rearranged the page layout accordingly to my original command without forcing a new page being generated by the server and being pushed through.
This real advantage is, precisely, what ASP.NET does not while it hints it would have liked doing.
So ASP.NET is no real advantage, and in respect to the traditional ASP it is a completely irrational super-foetation.
Moreover, it handles the thing not by keeping a session track but by hiding in your web page a form with a hidden form field carrying -listen to this- a specific name with several underscores signs both leading and trailing such name in order to be sure not to come across form name conflicts (!), and in such hidden element is stored a value to identify you: I call such a move a bit too cheap, especially when you arrange a whole array of technology only to end up there... I am undecided on whether it is more annoying or just more disappointing!
So the real deal is to stick to ASP, not to ASP.NET (no matter what they adjunctively say on the ASP.NET compiled features: if you disappoint me at inception with the very same foremost intention you were taking aim at, you cast a shadow that hinders all the rest. Moreover if it is the server side, why should I have to learn a new language? You build a new server side complier instead, and do the job in the background without meddling with my way!); and as far as the real dynamic changes in a page are necessary, the real deal is to stick to the W3C recommendations, which are styleSheets and not ASP.NET, whereas style sheets do affect and change the whole of the page without any need whatsoever of reloading from the server.
|
 |
 |
 |
 |
 |
 |
You can insert style sheets in a page by:
INCLUDING STYLE SHEETS IN A PAGE |
 |  |
 |  |
 |  |
 |  |
 |  |
 |  |
<LINK> tag |
By a tag like <link rel="stylesheet" type="text/css" href="myStyleFile.css">
In this way you import in the page an external file which carries all the definitions of the file sheet: such definitions are what are called classes when you think of them in regard to the html tags that are connected to them by the class property; conversely when you consider them with regard to the style sheet, they can switch name and be called, at times, rules. It's still the same lot of stuff.
Each rule can affect either a whole class of htm tags or only specific a id, and they normally look like:
- .aClassName {color:red; border-size:5px; background-color:black;}
this is a syntax where the class name is set with a dot before it to flag it affects all the elements carrying such class name (aClassName)
Here and below the property/values pairs are just examples among many that were possible, and each class could include dozens and dozens of such pairs.
- #aIDstyle {color:red; border-size:5px; background-color:black;}
this syntax with the # sign normally affects only one id.
- table {color:red; border-size:5px; background-color:black;}
this time with neither a dot or a #sign preceding, the selector (what precedes the curly brackets set) is going to address not classes neither id labeled items, but all the html tags in the document that match (table tags, in the example).
|
<STYLE> </STYLE> tags pair |
you can set
the same definitions as above but this time without resorting to external files, but by including all your style sheets rules/definitions in within such pair of opening and closing STYLE tags. Each set constitutes an independent style sheet node regarded by the scripting engines as a new style sheet object available in the page (that is: each pair of STYLE tags delimits independent units: the scripting engines do not consider them all in the same park, but each an independent style node). |
@import url(myStyleFile.css) |
this is an instruction that you can nest in within a pair of STYLE tags as above, and is meant to import from within there an external css file (without using the LINK tag, that is). There is no difference under a practical point of view (and even Netscape 4 accepts such syntax), but I urge you not to import your css this way: in fact we're to see that every imported style sheet is an independent object that can be addressed through scripting language and thus consequently affected; but if you import a file by the fore mentioned syntax, such file is to be loaded correctly but won't (not) be recognized any longer as a node in the hierarchy of the available imported style sheets nodes: it is going to be invisible to many scripting engines (Netscape 6.0) and therefore its rules/definitions won't be available to be changed via scripting languages (Actually IE has a way to inspect them as well, but to date NN6 has or implements none: so we're stuck). |
INLINE the tags |
inside an html normal tag you can add a property named style (example: <table style="color:red; etc...">) and this would affect only that tag: it is the standard way to override a class definitions and let in a few specific exceptions, you see.
Such style declarations inserted inline, are not an independent node (that is: the scripting engine apply the style, but consider them just like an attribute, not like an object node to count in the collection of the style nodes present in the page. Ask Santa why. I assume attributes are necessarily something different than the tag which hosts them, and so only the tag has the dignity of Object: so it is for style as nodes and as attributes, methinks.)
|
ALL of the above |
multiple external files can coexist as well with multiple combinations of the above in the same page
If some declarations include by chance the same class names, the last one with the identical name that got introduced in the queue, is going to be the one which prevails on all the others ( behaviour which is exactly why css are called css: Cascading Style Sheets). |
 |  |
 |  |
 |  |
 |  |
 |  |
 |  |
It is important to understand and repeat that each of these style definitions is, from a document scripting perspective, an object itself and therefore it can be addressed by scripting languages (scripting languages can do nothing on something they do not consider an Object: and what a script considers an Object exclusively depends on how the scripting engine works, which may amount to whisper into your ear it is just somewhat arbitrary; therefore knowing what is considered an Object and gets bestowed such dignity by an engine, and what is not, is so deeply relevant a matter) and its properties can be changed on the fly, at least in all the new browsers (from generation 5 onward, that is: that is from Internet Explorer 5 and above and Mozilla and Netscape 6 and above. And by and large style sheets are a valid Object on all browsers that have/recognize as valid a basic object/collection that is the array of present style sheet nodes: document.styleSheets).
As outlined, in such collections only style sheets included via the LINK or via the STYLE tags are counted in. Possible tag inline style statements, for instance, certainly do not belong to a global collection of Objects (a collection is a family of Objects that have something in common: like all elephants do not belong to the group of monkeys Objects), for they are just exceptions to the rule.
The syntaxes by which you can address these objects are, in their basic paths:
- Address tag sheets:
document.styleSheets[NumericalIndex]
whereas the numerical indexes start with zero included onward.
- Each so pinpointed styleSheet holds then a further collection named either rules or cssRules, accordingly to the browsers, which addresses each class included in the file (or in the style tag pairs):
document.styleSheets[index].rules[index].style or
document.styleSheets[index].cssRules[index].style
Once you're inside one of these latest branches, to address for instance the color:
document.styleSheets[index].cssRules[index].style.color to read it, or:
document.styleSheets[index].cssRules[index].style.color="yellow" to... change it!
Last but not least, a css declaration like background-color which includes the dash, should be changed, when addressing it from a scripting process, removing the dash and Capitalizing the letter soon after it:
document.styleSheets[index].cssRules[index].style.backgroundColor
- Address :
document.getElementById("theIdHere").style
and then after style the same color or backgroundColor or whatever as outlined above.
If this file doesn't get too long, odds are that at bottom you're to find a nearly comprehensive list of all the main available properties and the values they can accept, with small snippets to see what they do to a fake element when you change their values.
AFFECTING THE CASCADE |
 |
 |
 |
 |
 |
 |
Given the observation I have made above on the prevalence of the last style sheet over the previous ones in case of multiple style sheets (either external files or STYLE tags or both, no matter) all or some carrying by chance matching class names, I have to stress one more thing.
Consider inline style statements, such as those made by setting a style attribute to a tag (please do note the difference between style as a tag and style as an attribute inside a tag).
Let's imagine a widely common chance indeed: the tag has both a class and an inline attribute:
If both of them affect the same property(s), say to keep it simple just background-color, and namely both the inline style attribute and the definition inside the myClassName fight to set the background-color, perhaps you already know that in this case the inline style statement (attribute) prevails on the class, and the background is set accordingly to the style attribute and not accordingly to the class.
This is the end of the branch of the cascading behaviour:
- Style Sheets rules affecting the TAG TYPE
- Style Sheets rules affecting the CLASS ATTRIBUTES (prevails on the previous in case of conflicts)
- Inline style defined by STYLE ATTRIBUTES (prevails on all of the previous in case of conflicts)
- Also, if you are so unmindful to include more classes with the same name or more inline style declarations, what prevails is always the last found in the whole path line: style Sheets are therefore LIFO Stacks: Last In, First Out (first considered, that is).
Now we have here a twofold issue (if the tag has both class and style attributes, ok?):
- Foremost, I want you to understand this:
- if you alter (or add, or delete) a class inside a style sheet (style sheets are the files that include collections of css classes, remember?) via scripts, the alteration of the class is immediately reflected on all (I insist: ALL) the tags belonging to such class.
- If you alter a style attribute declaration via scripts by pinpointing a specific tag (typically knowing its ID if any, by ), this alteration and the alike affect only (I insist: ONLY) the specific tag that carries such inline declaration.
- If, like my scripts would allow you, you alter one declaration inside a style sheet (like changing a property inside a class) but the tag has an inline style attribute involving the same property too, well this class alteration is not going to be reflected on the tag (although it may be reflected on all the other tags belonging to such class but that do not have overriding inline style attributes), because a tag with an inline style attribute is ultimately affected by the latter, that somewhat "dislodges" the former.
Therefore in order to be sure that a class alteration is reflected also in the tags carrying both inline statements and a class attribute pointer, assuming you want this well you have to alter both the class and the inline style!
Some of my scripts like writeClass held an helping hand for this too!
- It is nearly impossible to read the style of a tag if such style is given by a class and not by an inline style attribute. Why? because some browsers, most notably Netscape 6, don't let you read it via scripting but only let you read the inline style attributes (crazy, I agree 100%).
My scripts (oneClass) let you address this problem effectively!
|
 |
 |
 |
 |
 |
 |
One thing I want you to understand before we proceed to the actual scripts is that as you may have noticed by the use of numerical indexes in the examples above, (which is just a reproduction of the order the tags have been typed in the document!).
Needless to observe that if you don't know beforehand, for instance, in which styleSheet a class definition is included and then you don't also know what such style sheet index is (and moreover you also have to know what is the index of the class/rule itself within the amount of classes present in the style sheet!), you'd regret you cannot change absolutely anything of that class to affect on the fly the whole set of depending tags: in fact you don't know how to find out those indexes (unless you have hard coded yourself the whole page and you never altered the order of your style sheets invocations, and you're never to alter them in the future... an optimistic illation that my scripts question, and are here to defy).
You guessed it: among many things, the first odd these scripts will help you solve is exactly finding the appropriate indexes of styleSheets and even of the rules (classes) definitions included in it by merely knowing, for instance, the class name of a tag, which by the way can be retrieved via scripting from the TAG with the following syntax:
document.getElementById("anId").className
the above if the tag has an ID attribute. Or, if it hasn't:
document.getElementsByTagName("table")[index].className
Note that to address one single element from such latter collection you have to append an index; to read the length of the collection as a whole, instead, no index must be included: the whole collection and each single instance arrayed in it are different things/objects!
This last expression, getElementsByTagName, grabs all the elements that match with the tag name passed in between the quotes, therefore it returns either an empty array (no such tags in the page...) or an array whose each entry is a document element tag with that name, pointing to the tag, and from which you can read via scripting all the properties (the class, if such attribute is included, by className, or other things like the length of the whole array and so on).
[Netscape 4 won't show correctly the following snippet]
Try it: get the length of some collections present in this document
(note: there are many tiny hidden -transparent- images to fix some layout formats):
document.getElementsByTagName("
").length
Therefore you have to scan such yielded array by a loop to address all its gathered elements and check their possibly different class names; or, alternatively, you have to stuck an index right after it in order to pick one specific element from the returned collection (this provided you're sure about the index: you know beforehand how many tables are there - if you don't the document.getElementsByTagName("table").length property is arguably going to let you know this at least!).
A note: there is a third syntax alike the previous ones at least, that I add just to be complete:
document.getElementsByName()
This should address all the tags that have an attribute name specified:
<table name="aName"...>
Do not use getElementsByName(), if you want to spare yourselves the headaches I got looking after it.
On Internet Explorer, moreover, it only picks the IMG and FORM (form elements as well) tags, regardless of other different tag types that could have a name specified (say table or div tags or any other). And this without any official documentation ever mentioning the annoying setback, but conversely providing small snippet drawing the getElementsByName exactly from... FORM tags thus spreading the false and deceptive impression such last syntax would have grabbed the tags by their name independently of the tag type.
THE SCRIPTS, CODES AND WHAT THEY DO
|
|
Here are the several powerful scripts I have devised by which you can manipulate the styleSheets object at your will, with the codes, the description on what they do, how to use them, how to arrange the arguments to get different outcomes, and the test forms to see each of them in action.
|
All these functions work only with browsers capable of recognizing the
document.getElementById
syntaxes, which tantamount to saying Internet Explorer 5 and above, and Netscape 6 and above, and Mozilla. Netscape 4 and Explorer 4 cannot use them (the scripts would just return false if attempted to run on those platforms, thus no errors would be yielded anyway, but no useful data as well: in fact these syntaxes for styleSheets have been released by the World Wide Web Consortium only lately).
Remember that the browser named Opera although in its version 6 recognizes such syntax, is none the less still unable to process loops for associative arrays (an appalling shortcoming, openly acknowledged as an issue by the Opera staff itself: click for more on it at a Opera.com file): therefore Opera is not able to scan Objects properties, for object properties are indeed associative arrays! Useless to say this is an issue indeed if you are dealing with... styleSheets objects.
Also, keep in mind that to let you test these forms, in this file I have included:
2 external css by LINK tags, both carrying a lot of rules (classes).
1 style sheet by the STYLE tag holding one mere foo-foo class.
So, on the whole, this page has 3 styleSheets nodes: indexes: [0,1,2]
 |
 |
 |
 |
 |
 |
findSheet function |
WHAT IT DOES, HOW IT DOES IT |
findSheet( characteristic, characteristicIsHREF ) |
Given some known data on a css node (either external css files or nodes represented by pairs of <style></style> tags) such as (please note that the possibilities below are exactly the possibilities you have to feed the function with its first and only mandatory argument named characteristic):
- Number representing the index of the style sheet.
- String representing the file name of the style sheet regardless of its location (es: "mycss.css" or you can also omit the extension if you prefer).
- String representing the path of the style sheet location as it appears in the document (such as: "myfolder/mycss.css" or more complex paths, or just, if the style sheet is a file in the same directory, "mycss.css").
If you pass the first argument as a location path, you do have to pass also a second argument as number 1 to flag such a string is meant to be handled like a path indeed and not like a file name without path.
I assume you know also the path shorthands like the double dots to mean up of one folder.
- Object for in case you have some variable which holds a reference to the actual object (in scripting it may well happen!) rest assured the script can yield its data also in this case.
The function returns an Array of 5 entries holding the following data on the style sheet (or it returns false if no styleSheet corresponding to the passed criteria has been located in the current document):
- entry [0]: the style sheet Object (a scripting reference to it, that is)
- entry [1]: the style sheet numerical index
- entry [2]: the style sheet file name stripped of the location path.
If there was no external file, but say a STYLE tag, this property would carry an empty string.
- entry [4]: the style sheet location path (very good in case you knew only the file name but not the path!)
If there was no external file, but say a STYLE tag, this property would carry an empty string.
Running this function with Internet Explorer 5 and above you can scan even the style sheets included by @import.
Netscape 6 cannot do that at all. This is why I anyway suggest to you never to include style sheet by the @import syntax.
|
TEST IT |
(suggestion: start with an index (Number) like 0 to find the names of the files here)
|
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
allClasses function (plus bonus: findClass) |
WHAT IT DOES, HOW IT DOES IT |
allClasses( indexOrObject )
|
This script reads and reports all the classes inside a css node (an external file or a STYLE tag set, that is).
It unfolds all the properties and value for each rule and finds all the indexes for each rule and returns also the selectors of the rules: in other words given an external css, you can roll it flat!
It returns a complex output (matrix: array of arrays, namely that in two entries -index 2 and index 3- can get further complicated assuming the shape and in the case of entries 4 and 5 the shape ).
The details of this complex output are as follows:
- Array: each entry is a class (rule) found in the css node (file or STYLE tags), and if no class (rule) is by chance found, it returns an empty array.
If classes are found, each entry (whose array index is by the way also the index of the class position within the css) of the output is an Array itself, composed of 6 entries carrying for the rule the following data:
- [?][0], namely you're on main Array at [index ?] index [0]:
Object: the class object itself.
[TECHNICAL NOTE]: A syntax that would address directly allClasses(index)[index] could use immediately such entry as an active reference to the rule. But if you assign that to a variable, you should test first if the variable is able to keep the pointer.
- [?][1], namely you're on main Array at [index ?] index [1]:
String: the text of the selector, inclusive of dots and # signs if any.
- [?][2], namely you're on main Array at [index ?] index [2]:
Another Array: [?][3][?]. Therefore at level [2] you can find elements as follows:
Each of these entries is... the name of a property found in the class! This is a refined feature, for you can find entries whose value is, for instance:
- [?][3], namely you're on main Array at [index ?] index [3]:
Another Array: [?][3][?]: conceptual integration of point above (read it if you didn't):
In the same order of the array of properties, it carries the corresponding values!
Instance:
//#ff0000 is hexadecimal for color red. Remember that Netscape 6 returns colors as rgb not as hexadecimals: "rgb(255,0,0)" - yeah like that, only the numbers may change!
- [?][4], namely you're on main Array at [index ?] index [4]:
Object
This is the style Object.
A powerful feature: if you keep in mind that the script equivalent of style sheets properties are those very same names but without the dash signs (if any) and the letter soon after the dash goes capitalized (instance: background-color turns into
backgroundColor), well you can store in a global variable the output of this function and later address and change and read all the class properties on the fly by saying:
variableName"#ffffff"; //or whatever other hexadecimal
Remember to include the last index as a LITERAL, namely in between quotes: ["color"], ["borderSize"]...
You can use this powerful entry for setting and reading a property value both:
- :
invoke and set to equal:
[?][4][STRING]=a value
- :
just invoke:
[?][4][STRING]
- [?][5], namely you're on main Array at [index ?] index [5]:
Number: again, this is the index position of the class inside the style sheet.
It is repeated here and stored autonomously because if you slice some entries out of the main array to dispatch them somewhere else (like assigning an array lot to another independent variable), by such move you would have lost the index position of the class in the style sheet as it was reflected in the returned mother array index position (each entry was a class, so the indexes where also the indexes of the classes within the style sheet. But if you remove them from the mother array, the only way to retrieve again the index position is that it is saved within the structure too).
- [?][6], namely you're on main Array at [index ?] index [6]:
Number: this is the same parameter you passed to the function (in case it was a style sheet index -for it could even be a style sheet object namely a script reference-, maybe you like to have it associated to these class collections of properties. Most of the times it is the index of the style sheet, unless you passed to the function as its argument an object instead of the index number!).
This function wants only one argument: either a Number that must be the index position of the style sheet among the available ones in the current page, or a style sheet object itself; the latter would be if you use this function passing to it as an argument another function seen earlier ( findSheet, that can return exactly a style sheet object), or a full fledged reference to the styleSheet like document.styleSheets[2]; example:
That's a way to extract all the classes from a style sheet by simply knowing its name!! (perhaps you remember that findSheet returned an array of 4 entries whose entry [0] is the styleSheet Object itself!)
Last but not least, if you pass an object as a reference, the script cannot find the index of the style sheet any longer so the 6th entry is going to be unreliable: but after all this should not worry you too much, for in some cases it means you already know such index number (like in document.styleSheets[INDEX]) or you can anyway find it by simply scanning all the returned classes for each styleSheet in the document.
Now a minor script: whereas the allClasses script finds all the classes in a style sheet, the following snippet is meant to locate one single class and not to return them all indistinctly. Namely it assumes you do not know where such class may precisley be located in a style sheet (althouhg you mya know either its name or its selector) and you want to find it and get all the indexes and adjunctive possible data on it.
This script is called findClass, but the bigger script called oneClass that you will find furhter on basically includes all its functionalities so you can consider findClass sort of a depleted, more agile version of oneClass. It requires allClasses being included in the same script.
The script above [by the way: a bug went undetected for 2 months: something rare at UnitedScripters: it was a stable index (a zero) inside a loop which was assigned to a returned element instead than assigning to it the looping updated index: a typical bug of the tired scripter gazing at the screen at 5am!- a bug fixed on january 2003] wants either one argument or two: the first must always be a String carrying either the className (with or without the leading dot doesn't matter) or the unlikely full selector if you know it. For instance if a tag belongs to the class "fooclass", you can use that snippet like:
findClass("fooclass")
And it will return either an empty array or an array whose each entry is carrying a 4 entry array (structure: [?][0-3]); in each main entry, the subarray first entry [0] is the styleSheet index where the class has been found (if more classes bear the same class definition, it returns the last one, for only the last one in a cascading setting affects the tags), and as second [1] is the index of the class within such sheet; third [2] entry is the style sheet Object itself, and last [3] entry is the class Object itself.
The second argument named beyondMatch is optional: if you do pass it, the function will go on checking for class instances matching the given class in all the style sheets, and would return them all: [?][0-3].
if you do not pass it, the script will start scanning the style sheets from the last one in the line, and as soon as it finds a class matching the first argument criteria, returns only that one and exits (a bit faster, that is): [0][0-3].
To know how many style sheets are in a page:
document.styleSheets.length
|
TEST allClasses
The document has only 3 style sheets: indexes: 0,1,2
|
|
|
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
oneClass function |
WHAT IT DOES, HOW IT DOES IT |
oneClass( object, cssIndex, setProperty, withThisValue, objIsSelector )
|
Unlike the allClasses function, this oneClass function gathers all the data but relative to one class and not, like the previous script did, relative to a whole style sheet.
The output it generates is absolutely identical to the 6 entries described above, thus I hope you agree with me if we save yours and my bandwidth by omitting repetitions: whenever using this find class, as far as you need to check what the standard shape the output is, just glance at the description of the output in the previous script.
The only difference is that since this latter script deals only with one rule (class), therefore the main backbone of the array consists normally of just one entry; so in the setting:
[?][2]
and the alike, you can normally change that ? index with a zero:
[0][2] or [0][3] etc...
If you wonder why I have kept this shape instead of carrying out a mere array of 6 entries, and if you deem unnecessary a complication that leading [0] entry which never varies and none the less you still have to keep sticking at the beginning, well keep in mind that I did so very intentionally: firstly for I wanted to keep consistency with the two outputs in case you were using these scripts along with other scripts of yours, meant to scan these objects: if such were your case, it is better if you can rely always on the same type of data structure, don't you think so?
However, and secondly, for there are two cases when this script too returns a first index which can actually be progressive (from zero onward, that is): in case you passed only the first argument either as a Number or as a String, the script assumes you want to return an array of all the classes with that index number or that name on all the available style sheets; therefore the indexing and the data structure perfectly match with the data structure released by allClasses.
So the foremost difference is that this script deals with only one rule and, even most significantly, can locate a class (rule) without necessarily knowing its index in a style sheet.
Here are the possible invocations showing how this script can locate a class without knowing its index:
- oneClass(object):
Pass as argument a full reference to the class (unlikely you have it, but it is good to know the script can do this too)
stuff.
For the null and what the subsequent Strings may be in the second provided version for this lot, see further on.
- oneClass(index, index):
You must pass as the second index the index of the styleSheet.
The first index is the index of the class in within the stylesheet.
They must be numbers, not literal numbers: that is: 5, not "5".
stuff.
For what the subsequent Strings may be in the second provided version for this lot, see further on.
- oneClass(index):
You know only the index of the class in the styleSheet but you have no clue which style sheet index (for instance you're not sure how the style sheets have been loaded in the page, although within your given style sheet you're positive about its index location): the script will work out all the rest, namely it will locate the class and report all its data.
Warning: if you have more style sheets, the returned output will include the classes with such index found on all the style sheets: instance, you search for a class whose index is 10 and you have 2 style sheets with more than 10 classes: the output would report:
namely both of them.
The order is decreasing: output[0] is the class with index 10 met in the last included style sheet (and therefore it refers to the active one!), output[0] is the class with index 10 met in the first included (and therefore the nonactive one, and so on in case there were even more style sheets).
For the null and what the subsequent Strings may be in the second provided version for this lot, see further on.
- oneClass(className):
Powerful.
You pass a String which is the className: the script works out all the rest without being disturbed by the dots: if you include them or you omit them in the argument, the script is going to work as well. Trust me: this is powerful stuff.
Warning: if you have more style sheets and they include classes with the same name (selector), the returned output will include the classes with such name found on all the style sheets: instance, you search for a class whose name is fooand you have 2 style sheets with a foo class: the output would report:
namely both of them.
The order is decreasing: output[0] is the class with name foo met in the last included style sheet (and therefore it refers to the active one!), output[0] is the class with name foo met in the first included (and therefore the nonactive one, and so on in case there were even more style sheets).
For the null and what the subsequent Strings may be in the second provided version for this lot, see further on.
- oneClass(className, index):
Same as above, String which is a className; but by knowing also the index of the style sheet, passing it as the second argument would save the script the effort to parse the style sheets (at least until it finds the requested object, upon which the script stops and returns the output).
- oneClass(selectorText,null, 0, 0, 1);
you pass a full selector (such as, say, "A DIV TABLE") like the only thing you know. Pass the subsequent argument exactly as above (most notably with the use of the javaScript keyword null as the second argument) and the script is going to find such class defined by such selector, if any in the document.
Warning: if you have more style sheets and they include classes with the same selector, the returned output will include the classes with such selector found on all the style sheets: instance, you search for a class whose selector is TABLEand you have 2 style sheets with a TABLE class: the output would report:
namely both of them.
The order is decreasing: output[0] is the class with selector TABLE met in the last included style sheet (and therefore it refers to the active one!), output[0] is the class with selector TABLE met in the first included (and therefore the nonactive one, and so on in case there were even more style sheets).
- oneClass(selectorText, index, 0, 0, 1):
Same as above, but you know also the style sheet index.
If you're wondering why you have to add those 0,0,1 this is the reason: the last 1 flags that the first argument is a selector and not just a class name: it is unlikely in my opinion that you may puss as first argument a selector, but it is none the less a chance (for instance you know your class but you want to build one of this script objects out of it: therefore you could pass the selector who knows...).
The zeros are something you're going to see next what they're meant for.
Additionally, this script can be used also to locate a class, and then change one of its properties with some value as soon as it finds it.
You can take avail of this feature anyway only if you know also the index of the style sheet (zero if only one) node.
Conversely, you can use as the first argument either the index of the rule in the style sheet or the name of the class (a String, still regardless of dots: if you include them or not, the script would work correctly as well!) or the whole class selector.
If you want to do such a thing, pass the property to change as a String (in between quotes, that is, and remembering that the scripting version of the names of the style sheet properties require you to delete the possible dash and capitalize the letter that was before the dash: thus backgroundcolor would become backgroundolor) and then the value:
If successful in this, the function will not produce the output array, but would simply change the property and then it would return true.
I devised this simply because it was easy to add in this script just very few lines for a neat thing.
Whenever unsuccessful the script returns either an empty array or false.
|
TEST IT
Refer to the previous Test Form please
|
The output is very much the same as the test form above, whereas the only differences are:
- The first index is almost always zero, namely except if you passed only one argument and is either a Number or a String; so no longer
[?][0] or [?][1] or [?][2][?] or [?][3][?] or [?][4][STRING] or [?][5]
but:
[0][0] or [0][1] or [0][2][?] or [0][3][?] or [0][4][STRING] or [0][5]
- There is a 6th entry which is a Number and it is but the index of the Style Sheet (its numerical indexes in the collection of the possible several style sheets present in the document, that is) the class was found in: so:
[0][5] is the index of the class
[0][6] is the index of the style sheet
- If you pass the first argument as a class object, the 5th and 6th indexes of the output cannot be the real index of the class/sheet (it is no longer a Number. Consider this an exception, will you?).
- I suggest to you to always check whether the output is not false; and if not check whether it has a length. If it has, the first [0] element is the first style sheet in the line: if you want to affect the last one, be sure to see whether the output has more than just the first [0] entry (output.length>1) and consequently pick the last entry: that is the entry referring to the last style sheet in the line where it has been found one instance at the index or with the name of the class you were searching for: and, being the last index, it is also the one referring to the stylesheet whose definition affects the tags (the last in the line prevails. All this matters only as long as you may have included the same class definition in more style sheets!).
If you understood how to handle the output of the allClasses function you can handle this output too. Therefore the only thing that significantly changes is not the output, but it is the input arguments: they can be a lot of different types depending on what partial thing (name, index...) you knew about the class you want to gather all the data about.
|
|
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
addClass, deleteClass, switchSheet
[ switchClass snippet too ] |
WHAT THEY DO, HOW THEY DO IT |
addClass( sheetIndex, definition, optionalIndex )
deleteClass(sheetIndex, whichIndex)
switchSheet(indexOrObject, on)
|
Knowing the index of a styleSheet loaded/present in the page/document, the functions respectively do:
- Add a class to that style sheet
- Delete a class from that style sheet
- Disable/Enable a whole style sheet (style sheets can be enabled and disabled each as a whole and on the fly - which gets reflected in the appearances of the page!)
Arguments:
- addClass:
sheetIndex is the index of the fileSheet where you want to add a class.
definition is the definition of the whole class, inclusive of possible leading dots or # sign, of selector (class name, that is) and curly brackets (mandatory or the function exits and returns false), and then the statements inside the curly brackets.
optionalIndex if none, the rule is appended at bottom of the style sheet, if passed as 1 the rule is posed at position 1. it is an optional parameter.
Returns false if something went wrong.
- deleteClass:
sheetIndex is the index of the fileSheet where you want to add a class.
whichIndex is the index of the class inside that style sheet and that you want to delete (as for finding the indexes of the classes included inside a style sheet see further on).
Returns false if something went wrong.
- switchSheet:
indexOrObject is the index of the fileSheet where you want to add a class (accepts an object too, given the way some browsers work).
on: if 1 or true disables the style sheets, otherwise if 0 or false enables it.
Returns false if something went wrong.
By the way if you need a snippet function that switches the class (namely the rule and not the whole style sheet) an element belongs to (that is: a tag belongs to a class "foo" and you want to make it switch to a class "foo2") this is a triflesome task and I provide you with a snippet just for sake of completeness. You pass to it two arguments, the first a String (in between quotes as usual, obviously) with the ID of the element, the second a String again with the name of the new class you want it assigned to.
|
TEST IT |
|
|
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
readClass, writeClass functions |
WHAT THEY DO, HOW THEY DO IT |
readClass(cssIndex, ruleIndex, property, optionalID)
writeClass(cssIndex, ruleIndex, property, value, optionalID, onlyID)
|
What they do is obvious by their names: the only thing you keep in mind is that you do have to know the numerical indexes of the style sheet and of the class in within the class is, in order to address your class and either read or write it; obviously, this is one of the main thing the features offered by the scripts above were busy providing you with (findClass is a nice method to find at once both the numerical indexes of a class and of the styleSheet containing it).
Also the arguments are obvious except the optionalId.
If you pass the optionalId argument, it means that the style has to be read (or written) not inside a class but from/inside the inline style definitions of a tag element grabbed by its ID.
Since when you read you cannot read but once, if you pass such argument optionalID the script searches in the inline declarations of the ID, whereas it would be impossible to search within a class definition: an id and a class are (remember?) two different attributes in a tag.
If you pass the optionalID argument to the writeClass the situation is more powerful: the function can either:
- Change only the inline style (if you want to do this, pass also the last argument onlyID)
- Change the given property only in the indexed class (completely omit optionalID and onlyID)
- Change the property both in the class and in the pinpointed optionalID (pass all except onlyID).
This last thing is pretty useful when you change a class, and all the elements (tags) in a page reflect the new situation, but alas! you also have a few elements that although belonging to the given class index, host some inline style declarations that override the class ones: and as you may remember these latest ones not only are overriding in respect of a class, but have to be set in a different scripting way too.
The script can therefore force at once also tags that make exception and compel them into respect of the change induced on the class they belonged to but that they excepted from via a style inline attribute carrying expression overriding the equivalent ones in the class.
Eventually, you can even pass an Array as optionalID, and include in each entry of this array an ID: the script would force the change in the class and in all the arrayed IDs!
Wow.
|
TEST IT
Refer to the previous Test Form please
|
|
|
|
 |
 |
 |
 |
 |
 |
|