homepage Welcome to WebmasterWorld Guest from 107.20.131.154
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
How can I add a style declaration in an external .js file.
... without using document.write?
ronin




msg:4217736
 9:08 pm on Oct 16, 2010 (gmt 0)

Quick and easy one (I hope).

1) I have a series of collapsible <div>s on an .html page.

2) A local .js file referenced by the .html page, enables the <div>s to collapse / uncollapse when and if each one is clicked.

3) Collapsed <div> status is achieved by the CSS declaration - display:none;

4) Design constraint: When the page loads, all the divs must start off in collapsed status.

5) With accessibility in mind I don't want the display:none; declaration to be in the same external stylesheet as all other styles - because, then, anybody accessing the page with javascript disabled will see only the collapsed <div>s (due to the design constraints of item 4), have no way of opening them and consequently will be unable to read the page.

6) It makes most sense (to me) to have the relevant style declaration inside the same .js file as the script. That way, if the visitor has javascript enabled, the collapsed <div>s will display collapsed - and if the visitor has javascript disabled, the visitor will see all the divs open and be able to read them in a static open format.

So...

Obviously this works:

document.write('<style>.collapsed-div .article {display:none;}</style>');

but it uses document.write... which I want to avoid using if possible, since it slows everything down when the page is loading.

Instead I have been trying to get something like this to work in the .js file:

document.getElementsByClassName("collapsed-div").getElementsByClassName("article").style.display = "none";

However that piece of javascript doesn't want to play ball.

I suspect I have messed up the syntax.

Any pointers, please?

Thanks in advance to anyone who can help!

 

Fotiman




msg:4217768
 11:10 pm on Oct 16, 2010 (gmt 0)

If you have a framework like jQuery or YUI, then you could use the selector syntax for each of those languages, like:

$('.collapsed-div .article')

If not, then you could do something like this:

var i, j, k, n, articles,
collapsed-divs = document.getElementsByClassName("collapsed-div");
for (i = 0, n = collapsed-divs.length; i < n; i++) {
articles = collapsed-divs[i].getElementsByClassName("article");
for (j = 0, k = articles.length; j < k; j++) {
articles[j].style.display = "none";
}
}

Basically, JavaScript doesn't provide a way to set the style on a collection of elements using a simple syntax... you need to iterate through the list and set it on each of them. Some of the frameworks make this simpler, hiding the details from you.

Another approach you might consider would be to use JavaScript to attach a class to the body element. For example, you might attach a class "jsEnabled". Then in your CSS, you could do:
.jsEnabled .collapsed-div .article {display:none;}

This allows you to keep that presentational code entirely in the CSS.
Hope that helps.

rainborick




msg:4217771
 11:27 pm on Oct 16, 2010 (gmt 0)

You might be able to do something simpler if JavaScript can crawl the stylesheets before pageLoad fires:


for (i=0; i<document.styleSheets.length; i++){
var mySheet = document.styleSheets[i];
var myRules = mySheet.cssRules? mySheet.cssRules: mySheet.rules
for (j=0; j<myRules.length; j++) {
if (myRules[j].selectorText == '.collapsed-div') {
myRules[j].style.display = 'none';
} // endif .collapsed-div
} // end for j
} // end for i


ronin




msg:4218299
 4:13 pm on Oct 18, 2010 (gmt 0)

Thanks Fotiman and rainborick - very much appreciated! >;->

JavaScript doesn't provide a way to set the style on a collection of elements using a simple syntax


Ah. That's where I was going wrong then. I work almost exclusively in HTML and CSS and my lack of familiarity with javascript led me to guess that it would be possible to formulate CSS style declarations in .js syntax. Live and learn.

Another approach you might consider would be to use JavaScript to attach a class to the body element. For example, you might attach a class "jsEnabled". Then in your CSS, you could do:
.jsEnabled .collapsed-div .article {display:none;}


Ah... yes, this is a brilliant solution.

This led me to realise that there are three types of solutions which might solve this generic type of problem where the developer wants a CSS style to apply to elements only if the user-agent can read javascript:

1) Hard-code the CSS class-name into the elements on the .html document and dynamically apply style attributes to the CSS class using javascript.

2) Hard-code the CSS class style attributes into the .css document and dynamically append the CSS class to the elements on the .html document using javascript.

3) Hard-code the CSS class style attributes into the .css document but specify that the styles only apply when that CSS class follows a parent class (such as "jsEnabled") - and then dynamically append that parent class to the <body> element on the .html document using javascript.

And a fourth solution occurs to me too:

4) Hard-code the [open-div] CSS class-name into the elements on the .html document and hard-code the [collapsed-div] CSS class style attributes into the .css document (without a parent selector class)... and then dynamically cycle through and change all instances of [open-div] on the .html document to [collapsed-div] using javascript. That way the <div>s are intially set to [open-div] and re-initialised to [collapsed-div] only if the user-agent can read javascript. (In all other methods, the <div>s are initially set to [collapsed-div] even though the activation of the collapse behaviour is contingent on javascript being enabled).

At the moment I am favouring method 3) - though I am wondering if method 4) would be more elegant, neither requiring an additional class in the .css stylesheet, nor requiring hardcoded styles in the .html document which are semantically misleading.

Speed of course is the primary priority, so I will split-test methods 3) and 4) and see which one yields the fastest load times.

ronin




msg:4218831
 1:13 pm on Oct 19, 2010 (gmt 0)

Oh and I ought to add, for the sake of reference, that the way I implemented method 3) was simply by adding the following line to the end of the collapse .js :

document.getElementsByTagName('body')[0].className = 'jsEnabled';*

*Credit to Rodrigo and his article: Adding hasJS Class When JavaScript Is Available

Fotiman




msg:4218875
 3:11 pm on Oct 19, 2010 (gmt 0)

That's fine... unless your body ever has some other class assigned to it, in which case you'll be replacing the existing value.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved