1

The code below works just fine, does exactly what it says on the tin. It just doesn't do it very well.

The project involves a master and slave system. One is a large screen map, the other a small touch screen with lots of buttons. The user can turn the map layers (transparent PNGs) on and off by pressing the buttons. I am using a very tiny MySQL database as the "go-between" the buttons on the control page sets a record to a 1 or 0 and the map page polls the database every 100 milliseconds (or whatever) and looks for a change. Both pages are run from the same server (one system is merely acting as a dumbish terminal)

This all works like a charm, but the fading animation doesn't work well. If I constantly toggle the button, the layer fades in and fades out...sometimes. Most times the layer merely appears and disappears but in the same interval that the animation should have taken. The map-layers are semi-transparent boxes that dim the legend depending on what layer is shown or not (just so you know)

I can't seem to figure out how to get the animation smooth out. Any ideas? Also if anyone knows how to get one webpage to control another without polling like this I would love to know, so far this is the only solution I can come up with.

var layerChange = setInterval(function() {
    $.ajax({
        type: 'GET',
        url: '/php/db-get-layers.php',
        dataType: 'json',
        success: function(data) {
          $.each(data, function(key, value) {
                if (value == 0) {
                    $('#legend-' + key).fadeOut(400);
                    $('#map-layers #' + key).fadeIn(400);
                } else {
                    $('#legend-' + key).fadeIn(400);
                    $('#map-layers #' + key).fadeOut(400);
                 }
            });
        },
    });
}, 100);

Here is the php file

<?php 
include('../config/config.php');
include('../config/db.php');

$provinces = $_GET['layer'];

$selectQuery = "SELECT oil, naturalgas, hydro, wind, coal, nuclear, tidal, thermal, solar FROM layers";
$query = mysql_query($selectQuery) or die(mysql_error());
$output = mysql_fetch_array($query, MYSQL_ASSOC);
echo json_encode($output);
?>

Thanks in advance for any help.

Update: The relevent HTML for the map page

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Map of Canada</title>
    <link rel="stylesheet" href="/styles/reset.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="/styles/structure-map.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="/styles/maps.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="/styles/fonts.css" type="text/css" media="screen" />
    <script src="scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script src="scripts/kiosk-map.js" type="text/javascript"></script>
</head>
<body>
<!-- Page Container -->
<div id="site-wrapper">
    <section id="map-layers">
        <div id="basemap" class="canada"></div>
        <div id="oil" class="canada"></div>
        <div id="naturalgas" class="canada"></div>
        <div id="rivers" class="canada"></div>
        <div id="hydro" class="canada"></div>
        <div id="wind" class="canada"></div>
        <div id="coal" class="canada"></div>
        <div id="nuclear" class="canada"></div>
        <div id="tidal" class="canada"></div>
        <div id="thermal" class="canada"></div>
        <div id="solar" class="canada"></div>
        <div id="labels" class="canada"></div>
    </section>
    <section id="map-legend">
        <div id="legend"></div>
        <div id="legend-oil" class="legend-overlay"></div>
        <div id="legend-naturalgas" class="legend-overlay"></div>
        <div id="legend-hydro" class="legend-overlay"></div>
        <div id="legend-wind" class="legend-overlay"></div>
        <div id="legend-coal" class="legend-overlay"></div>
        <div id="legend-nuclear" class="legend-overlay"></div>
        <div id="legend-tidal" class="legend-overlay"></div>
        <div id="legend-thermal" class="legend-overlay"></div>
        <div id="legend-solar" class="legend-overlay"></div>
    </section>
<!-- End Page Container  -->
</div>
</body>
</html>

The file kiosk-map.js contains the JS code included above - only that code, nothing else.

Taz
  • 3,527
  • 2
  • 33
  • 54
archdata
  • 15
  • 4
  • What version of browser is displaying the map image where the fade in/out is failing? – Chris Baker Jun 15 '11 at 16:36
  • I am using Safari (well Plainview - still webkit) and the fading is failing right from the start. If I really quickly set and unset the layer (hitting the button as fast as I can) then the fades tend to work (again sometimes). If I wait a second or two between the button pressing the fading fails. I am at a loss as to why. – archdata Jun 15 '11 at 16:59
  • Can you post the HTML (or at least the relevant parts?). I don't see any reason why it wouldn't work based on the code you've provided. If you post your HTML, I can try it out on my server and see what happens. – Chris Baker Jun 15 '11 at 17:21

2 Answers2

1

You have duplicate IDs on your HTML, which is not valid. Try turning this

<section id="map-layers">
    <div id="basemap" class="canada"></div>
    <div id="oil" class="canada"></div>

Into this

<section id="map-layers">
    <div class="basemap canada"></div>
    <div class="oil canada"></div>

etc...

Then try this:

$('#map-layers .' + key).stop().fadeIn(400);

and so on and so forth with the other selector.

Shef
  • 41,793
  • 15
  • 74
  • 88
  • Thanks for catching that. I stuck "legend-" in front of the ids - that way I only have to make minor changes to the CSS and JS. Doesn't solve the problem, but at least I know it didn't cause the problem. I have a sinking feeling it is webkit - Firefox seems to work fine... – archdata Jun 15 '11 at 19:26
  • Then use `$('#legend-' + key).fadeOut(400);` instead of two ids in an ancestor descendant way, it's much faster to use just the id. Also, did you try adding `.stop()` before `fadeIn()` or `fadeOut()`? – Shef Jun 15 '11 at 19:44
  • Check on the `$('#legend-' + key).fadeOut(400);` (did that when I noticed I could do so) Haven't got the system in front of me now so I can't test the `.stop()`, but will when I get back to it tomorrow. – archdata Jun 15 '11 at 20:02
  • It looks to be (for all intents and purposes) that this is a bug in Webkit. Firefox, IE, Camino, and Chrome all seem to work fine. Thanks for the help. I will accept this answer as it caught my coding mistakes. – archdata Jun 16 '11 at 15:51
0

To avoid polling, you might look at something like the Socket.IO library for node.js. Over the past few years, there have been many new solutions to real-time updates that stream from the server to the browser. You might want to ask another question specifically about just the polling issue or search around the site for existing answers.

justis
  • 504
  • 4
  • 6
  • Since you're using PHP, you may want to look at this SO question: http://stackoverflow.com/questions/603201/using-comet-with-php – justis Jun 15 '11 at 19:22