Reputation: 23056
I've tried my best to be a purist with my usage of Javascript/Ajax techniques, ensuring that all Ajax-y behavior is an enhancement of base functionality, while the site is also fully functional when Javascript is disabled. However, this causes some problems.
In some cases, a DOM node should only be visible when Javascript is enabled in the browser. In other cases, it should only be visible when disabled. Take for instance a submit button on a form that has a drop down with an onchange handler that auto-submits (using JQuery's form plugin):
<form method="post" action=".">
<label for="id_state">State:</label>
<select name="state" id="id_state" onchange="$(this.form).ajaxSubmit(ajax_submit_handler);">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
</select>
<input class="with_js_disabled" type="submit" value="OK" />
</form>
and the Javascript:
<script type="text/javascript">
$(document).ready(function()
{
$(".with_js_disabled").hide();
});
</script>
When Javascript is enabled, the submit button is not required (due to the onchange handler). However, JQuery's $(document).ready function (and the more direct document.onload) is only called after the page has been fully loaded and rendered - hence, the submit button is initially displayed and a "flash" occurs when the Javascript is executed and the node's display is set to "none".
I've accepted this as the cost of doing business, and haven't found a way around it. But is there a technique I'm not aware of that will minimize the effect, or even outright eliminate it?
EDIT:
The <noscript>
solution mentioned by many people below seems promising, but isn't working for me on Safari. However Prestaul's 2nd suggestion works beautifully:
<body>
<script type="text/javascript">
document.body.className += ' has_js';
</script>
<!-- the rest of your page -->
</body>
This can then be styled using straight CSS:
body .js_enabled_only { display: none; }
body .js_disabled_only { display: block; }
body.has_js .js_enabled_only { display: block; }
body.has_js .js_disabled_only { display: none; }
This second line is just for reference and can (and should) be removed to avoid circumstances where your element shouldn't be display:block. Likewise, you may need different variations on the third line for other display styles. But this solution is nice and clean, IMO, and in my tests entirely eliminates the flicker effect.
Upvotes: 17
Views: 7034
Reputation: 108480
A simple thing to try: add <script>jQuery.ready();</script>
right before closing the body tag.
This will force all binds to the 'ready' event to fire. And if you make them fire in the end of the document, the DOM is loaded and ready to go, even if the "native" onDomContentLoaded event is not yet fired.
This usually works for me when I want to remove flickering, especially in IE/win, since IE has it's own domready emulator in jQuery's 'ready' event.
Upvotes: 0
Reputation: 85135
How about combining some of these solutions:
<style type="text/javascript">
.only-without-script {
display: none;
}
</style>
<noscript>
<style type="text/javascript">
.only-with-script {
display: none;
}
.only-without-script {
display: block;
}
</style>
</noscript>
or I prefer adding a class to the body (place your <script>
tag at the top of the body and don't use the .ready event):
<head>
<style type="text/javascript">
body.has-script .something-not-ajaxy {
display: none;
}
input.ajaxy-submit {
display: none;
}
body.has-script input.ajaxy-submit {
display: inline;
}
</style>
</head>
<body>
<script type="text/javascript">
document.body.className += ' has-script';
</script>
<!-- the rest of your page -->
</body>
Upvotes: 10
Reputation: 488374
For situations identical to yours, I usually put the submit button around a <noscript>
tag. No one has suggested it, so I am not sure if it is considered bad practice around these parts, but it is what I use and it works for me.
If you only want a node visible when Javascript is enabled, you could do in the head:
<noscript>
<style type="text/css">
.js-enabled { display: none; }
</style>
</noscript>
And then give any Javascript-only elements a class of js-enabled
.
Upvotes: 5
Reputation: 229563
Just like David said, you can add a Javascript, that adds a style sheet to hide all "unnecessary" html-elements:
<head>
...
<script type="text/javascript" language="javascript">
document.write('<style type="text/css"> .disabled-if-javascript { display: none; } </style>');
</script>
</head>
...
If Javascript is enabled, it sets all elements of class "disabled-if-javascript" to hidden, before the body is even loaded. Just add this class to all elements that need to be hidden, if javascript is enabled. You might also need a class enabled-if-javascript that does the opposite, to show certain elements that would be hidden for non-javascript. Maybe you need to add "!important
" to your style definition there, to override the existing (non-javascript) rules.
Upvotes: 2
Reputation: 131550
Just a thought: I'm not sure if this will work, but you could try putting some Javascript in the document head to write a CSS style element that would hide the button.
Upvotes: 1
Reputation: 86805
I can think of two methods:
1 - Pre-detect if Javascript is enabled and save that information in a cookie/session. This could be done at the front page, and should eliminate most flickers.
2 - Use the livequery plugin, which detects elements as they are added to the DOM. You can run it right when Javascript finishes loading, which should be much before the document (it its in the head).
$('.with_js_disabled').livequery(function() {
$(this).hide();
});
Upvotes: 1