0

I have code that refreshes a div running on local server without flickering, but when hosting it on a webserver, it does flicker (disappear to background) when refreshing:

 <script>
    setTimeout(function() {
        $.ajax({      
            url: "",
            context: document.body,
            success: function(s,x){
                $(this).html(s);
            }
        });
    }, 1000);
</script>

I've had a good look around SO and the web, and it seems I want to double buffer the div table I am refreshing - have one hidden, refresh that, then swap the display style of the two divs

I started with How to avoid blinking when updating page from ajax

moved on to http://www.brightcherry.co.uk/scribbles/jquery-auto-refresh-div-every-x-seconds/ and Trouble with dynamic refreshing div

And got some good ideas from:How to toggle between two divs

The code I am trying to get to work may be too complicated. I feels like it should work, and the tables refresh, but they flicker with a long time between display.

Divs;

<div id="id1" style="display: none";>
    <div id="allTable1" class = "tableCenter">
        <div id="hiTable" class = "table">
            {% for entry in high_entry_list %}
            <li>
                <a href="/entries/{{ entry.id }}/"> 
                    <div class = "high" style = "text-align: left";>
                        {{ entry.text }}&nbsp;&nbsp;&nbsp;&nbsp;
                        <div style="float: right">
                            {{ entry.score }}
                        </div>
                    </div>
                </a>
            </li>
            {% endfor %}
        </div>
        ....and two more tables as hiTable above...
    </div>
</div>

<div id="id2" style="display: block";>
    <div id="allTable2" class = "tableCenter">
        <div id="hiTable" class = "table">
            {% for entry in high_entry_list %}
            <li>
                <a href="/entries/{{ entry.id }}/"> 
                    <div class = "high" style = "text-align: left";>
                        {{ entry.text }}&nbsp;&nbsp;&nbsp;&nbsp;
                        <div style="float: right">
                            {{ entry.score }}
                        </div>
                    </div>
                </a>
            </li>
            {% endfor %}
        </div>
        ....and two more tables as hiTable above...
    </div>
</div>

Script:

<script>
    var visible_id = 'id2';
    setInterval(function() {
        if(visible_id == 'id2') {               
            document.getElementById('id1').style.display = 'block';             
            document.getElementById('id2').style.display = 'none';
            $.ajax({
                url: "/index",
                context: document.getElementById('allTable2'),
                success: function (s) {
                    $("#allTable2").html(s).load;
                }
            });
            visible_id = 'id1';
        } else {
            document.getElementById('id1').style.display = 'none';            
            document.getElementById('id2').style.display = 'block';
            $.ajax({
                url: "/index",
                context: document.getElementById('allTable1'),
                success: function (s) {
                    $("#allTable1").html(s).load;
                }
            });
            visible_id = 'id2';
        }
    }, 1000);
</script>

So I have div wrappers for the two copies of three tables (one hidden, one shown), the javascript checks the visibility, swaps display style for the two wrappers, and updates the hidden one with an ajax refresh (which works). Is there an obvious logic or coding flaw that may be causing the flicker?

Community
  • 1
  • 1
  • 1
    You're timeout is set to 1 second. What if the response time takes longer than that? Fetching stuff from the server can cause significant delays. Interesting: http://blog.codinghorror.com/the-infinite-space-between-words/ – JDB Aug 19 '14 at 14:33
  • Just for the heck of it I tried it with 2000 and 5000, the result being my tables 'jumped' around a bit, refreshed, and eventually had "insufficient resources". Thanks so much for your suggestion below. I will have a go at it and hope it refreshes without jumping (could that be the result of the one div being on top, even if it swaps?). JDB, J148, you've restored my faith in SO. (after my last question was downvoted, I've been nervous to post). – Helmut Applebaum Aug 19 '14 at 15:14
  • Don't let the voting get you down too much. It's fast and loose and is just meant to provide a rough idea of "quality" and/or "fit" and provide some basic feedback, but it doesn't mean much. Regulars on the site get upvotes and downvotes on a pretty regular basis. Just continue writing good questions that fit within SO's scope (see the [FAQ](http://stackoverflow.com/help)) and you'll certainly gain reputation on the whole. Remember - just about any registered user can vote, so individual votes don't matter that much - it's the average over many, many votes that "counts". – JDB Aug 19 '14 at 18:40

1 Answers1

1

AJAX requests can take significantly longer than a second. You are toggling between the tables whether or not a particular AJAX request has finished, but the AJAX will still execute (perhaps 1.5 seconds later), giving you that undesired flickering behavior.

Rather than setting an interval which will execute whether or not the AJAX request has finished, set a timeout from the AJAX callback. Something like this (you'll probably need to fiddle with it some):

<script>

(function(){
  var visible_id = 'id2';

  function toggleDisplay(){
    // toggle displayed table
    document.getElementById('id1').style.display = visible_id === 'id2' ? 'block' : 'none';
    document.getElementById('id2').style.display = visible_id === 'id2' ? 'none' : 'block';
    var tableId = visible_id === 'id2' ? 'allTable1' : 'allTable2';
    $.ajax({
        url: "/index",
        context: document.getElementById(tableId),
        success: function (s) {
          $("#" + tableId).html(s).load;
          // when the ajax request has finished, initiate the next ajax request
          // after a 1 second delay
          window.setTimeout( toggleDisplay, 1000 );
        }
    });
    visible_id = visible_id === 'id2' ? 'id1' : 'id2';
  }

})();

</script>
JDB
  • 25,172
  • 5
  • 72
  • 123
  • Thanks JDB, I can get this working (with flickers) if I put a setTimeout or setInterval outside the function to start it off. I don't see otherwise how the ajax can initially start the function that it is within... As well, I am wondering if the visible_id is not set to id2 before the function runs every time. As with my other code, when I try to fix these issues, I get updates, but with blinking....I really wonder where this is falling down. – Helmut Applebaum Aug 20 '14 at 13:48