2

I have problem with making map. I realized it with table, but hover is too slow. So, what instruments can you advice me to solve my problem? Should I use canvas? And what way is better - generate map using json on client or do it on the server?

Full example: http://jsfiddle.net/MSpbW/3/ (table was automatically generated).

html:

<tbody>
<tr>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
</tr>
<tr>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-border"></td>
</tr>
<tr>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-border"></td>
</tr>
<tr>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-empty" style=""></td>
    <td class="cell cell-hotel-border"></td>
</tr>
<tr>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
    <td class="cell cell-hotel-border"></td>
</tr>
</tbody>

js:

$(document).ready(

    function() {
        var color;

        $(".cell-hotel-empty").hover( function () {
            color = $(this).css('background');
            $(".cell-hotel-empty").css('background', '0');

        }, function() {
                $(".cell-hotel-empty").css('background', color);
        }
        )
    }
)
manyrus
  • 23
  • 1
  • 4
  • If you only set the styles in the hover functions, don't use a hover bound function, but pure `css :pseudostyle` i.e. `.cell-hotel-empty:hover` syntax instead. It introduces far less overhead. You might also use `` instead of tables, for very long listings due to the "predictive rendering" of tables, which is costly when changes occur mid- or post-render. – Lorenz Lo Sauer Sep 04 '13 at 20:10

2 Answers2

0

You have ton's of td's having classname cell-hotel-empty, when you move your mouse over(then out of) them, event handler function is triggered each time, and in the handler function you once more select all td's with ".cell-hotel-empty" selector, bloating javascript's event queue and resulting in poor performance.

One other reason for poor performance is that, you are trying to emulate a computer screen(with very low resolution) in which every pixel corresponds to a DOM object(td's). Which creates a memory/cpu monster.

Try to assign a mousemove event handler to the table it self, then calculate the hovered cell, then execute on it.

If it is too complex for you, then why not use HTML5 canvas technology? You can even use kinetic.js to assign events for the shapes you put in canvas. That would be much better.

Rich
  • 5,603
  • 9
  • 39
  • 61
Kemal Dağ
  • 2,743
  • 21
  • 27
0

Your JavScript hover bindings, mimic an effect that could be purely done in Css, yet with an optimized event queue, which is faster.

I am also not sure if your intended effect isn't actually highlighting each individual cell/pixel, as follows:

.cell-hotel-empty:hover{ 
            background:none; }
.cell-hotel-empty{
            background:#ccc; }

See this jsfiddle.

If you want to change the color of the entire block, just set

.cell-hotel-empty{
            background:transparent; }
table:hover { background: #0078a3;}

which is fast.


To answer your questions:

  • Whether the table should be generated on the server or client depends on parameters such as the connectivity and CPU of the target's audience web-appliances. If you require compatibility to older browsers, static markup output in your API is the way to go. Avoiding whole-page refreshes is favorable in most cases. Moreover mime-type based caching control may be easier to setup this way, in addition to the HTTP Header Cache-Control. Do not use this during your development/debugging though!

  • SVG would be a better option. It gives you the ease of ready-to-use DOM event binding, but a more lightweight DOM-tree, than is the case with HTML elements.
    Emulating an image-map based on hundreds to thousands of pixel-sized HTML elements, is never a good idea.

  • If your target audience has HTML5 compatible browsers with canvas enabled, using 2D canvas could be a good option at this point, depending on your further requirements. By using canvas you will have to take care of implementing mouse and event-handlers yourself. But there are ready-to-use libaries like KinectJS and Zebra.

  • Judging from your given example, a good option may be to listen to the mousemove event, within a boundary box condition based on the absolute position of your table intersecting with the mouse-coordinates. The mousemove-event contains within the target the hovered element. You may respond to the target only upon a certain idle timelimit in the millisecond range e.g. 10-30ms. See also this question.

  • Theoretically, you could use a 2D space partitioning technique like an qadtree, see this post on SO, and respond dynamically to events similar as you normally would, but with some overhead removed.

    enter image description here

Community
  • 1
  • 1
Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
  • 1
    Thank you for your answer. So, I used KinetikJs - it is very powerfull framework. I like it :) – manyrus Sep 24 '13 at 20:05