Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessible way of hiding an element until jQuery's $(document).ready()?

I have a large survey that I have made more usable with jQuery by arranging it into sections and using an accordian menu to flip through each section.

The trouble is, there is a noticable snap when $(document).ready() fires and condenses everything into an accordian menu. That is to say that before $(document).ready(), you can see the whole survey.

I did consider setting #surveyForm to display: none; in css and #surveyForm.active to display: block; but that creates a new problem:

Browsers without javascript enabled will never get to see #surveyForm.active and so they won't be able to use the survey.

Any ideas?

Cheers

-Iain

like image 586
Iain Fraser Avatar asked Aug 25 '10 06:08

Iain Fraser


4 Answers

It's not clean and unobtrusive like good Javascript should be, but you can just add a Javascript snippet directly after your accordian content to initialize the accordian and hide the pieces that need hiding. The net effect should completely eliminate the "snap" and keep the form accessable to non-JS clients.

like image 147
Chris Heald Avatar answered Sep 26 '22 00:09

Chris Heald


If you want to easily manage non-javascript browsers/users without the snap when JS is enabled, try the following snippet inside the head node of your page:

document.documentElement.className = 'has-js'
// or any other class name, use += and append it if you already have a class on your *html* tag

In your CSS write for the non-js scenario first and then set display to none or hide it any other way that fits you by prefixing your js-relevant css selector with .has-js.

I'll probably get downvoted for putting javascript in the head but keep in mind that from a performance standpoint (Yahoo et al) only javascript files (external) need to be loaded as late as possible.

A javascript tag itself will not make your page load longer except for the fact that it will block render while it is being parsed and executed, but in this case we want that, since you need the .has-js class before rendering starts to avoid flickering.

like image 23
Denis 'Alpheus' Cahuk Avatar answered Sep 25 '22 00:09

Denis 'Alpheus' Cahuk


I haven't tried this, but perhaps you could wrap the content in <noscript> tags. Those with Javascript disabled will always see the content. Those with Javascript will not see the content. Then use JQuery to remove the <noscript> tags, thus making the content visible to those with Javascript.

EDIT:

The following example almost works. What I intended was to delete the <noscript> tags, whilst keeping their content. However, the code ends up escaping the HTML. The idea works, but I'm not sure how to implement it properly—perhaps someone else can shed some light on it:

<noscript>
    <p>Display me!</p>
</noscript>
<script type="text/javascript" language="javascript">
    $(document).ready(function() {
        $('noscript').contents().unwrap();
    });
</script>

Here's what I wanted to get:

<p>Display me!</p>

Here's what I actually get:

&lt;p&gt;Display me!&lt;/p&gt;

EDIT 2:

After a little more investigation, the unwrap() method works correctly for non <noscript> tags: it works, for example, for the contents of a <div>. I'm not sure what the solution is here. It is presumably something to do with the way browsers interpret <noscript>.

like image 33
Mike Avatar answered Sep 23 '22 00:09

Mike


This is the progressive enhancement solution I use for situations like this.

like image 42
Mitch Rosenburg Avatar answered Sep 24 '22 00:09

Mitch Rosenburg