Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to eliminate post-render "flicker"?

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.

like image 678
Daniel Naab Avatar asked Jan 21 '09 00:01

Daniel Naab


People also ask

What is an anti-flicker filter?

The Anti-flicker Filter control, located in the Effect Controls tab > Motion effect, can reduce or eliminate this flicker. As you increase its strength, more flicker is eliminated, but the image also becomes softer. You may need to set it relatively high for images with lots of sharp edges and high contrast.

How do I fix flickering frame rate?

Simply match the frame rate of your video camera to the refresh rate of the monitor. In Windows, right-click the desktop, select “Screen Resolution,” click “Advanced Settings,” and select a refresh rate from the Monitor settings menu.


3 Answers

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>
like image 153
Prestaul Avatar answered Oct 18 '22 13:10

Prestaul


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.

like image 30
Paolo Bergantino Avatar answered Oct 18 '22 13:10

Paolo Bergantino


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.

like image 45
sth Avatar answered Oct 18 '22 14:10

sth