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.