Tag Archives: jQuery

Escape Click/Double Click Hell in IE8 and FireFox With jQuery

While developing a control for a web page, I ran into a cross browser problem related to mouse clicks.  I offer the following guidance to hopefully help someone experiencing the same problem.

The Problem

The click and double click events are closely related. IE8 and Firefox handle them differently. If you were to double click a button on a web page, the following event timelines would occur.

IE8 Double Click Event Timeline

  1. click
  2. doubleclick

FireFox Double Click Event Timeline

  1. click
  2. click
  3. doubleclick

IE8 will fire only the double click DOM event, while Firefox will fire both the click and the double click event. You could have an argument about which method is correct, but the truth is I don’t really care. I just wished it worked a single way.

Background

I wanted a to create simple spin control.  A textbox holds a numeric value, and two buttons on the right can either increment or decrement the value.  Using jQuery, I wrote a couple of simple methods to increment and decrement the value in the textbox. Here’s my first attempt:

    <script type="text/javascript">
     $(document).ready(OnReady);
 
      function OnReady() {
         $("input.GridCellArrowUp").click(OnUpClick);
         $("input.GridCellArrowDown").click(OnDownClick);
     }
 
     function OnUpClick() {
         var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
         var hours = Number(query.val());
 
         if (hours != undefined) {
            hours += 0.5;
            query.val(hours.toFixed(2));
         }
     }
 
     function OnDownClick() {
        var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
        var hours = Number(query.val());
 
        if (hours != undefined) {
           hours -= 0.5;
           query.val(hours.toFixed(2));
        }
     }
 </script>

Performance Problem

This approach was fully functional, but I noticed that the click performance was bad in IE8. If I were to rapidly click a button, it would increment only every other button press. I was unsatisfied. Firefox seemed to work just fine, but I can’t ignore my IE audience.

I found a solution on the internet that would put a delay into the click handler so as to only fire a single click, or a double click. This wouldn’t work for me. I couldn’t wait to see if a double click was going to happen or not. Since I can’t change IE8, I needed to act upon either click or doubleclick events.

Since Firefox will fire both click and doubleclick events after the second click, I put a short delay (20ms) in the handler so that my code doesn’t act twice. The end result is that I can rapidly click my button, and I get a result each and every time. Here is my final result:

<script type="text/javascript">
    $(document).ready(OnReady);
 
    var okToClick = true;
 
    function OnReady() {
        //Attach to both click and dblclick events for IE/Firefox compatibility
        $("input.GridCellArrowUp").click(OnUpClick).dblclick(OnUpClick);
        $("input.GridCellArrowDown").click(OnDownClick).dblclick(OnDownClick);
    }
 
    function OnUpClick() {
        if (okToClick) {
            okToClick = false;
 
            var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
            var hours = Number(query.val());
 
            if (hours != undefined) {
                hours += 0.5;
                query.val(hours.toFixed(2));
            }
            setTimeout(function() { okToClick = true; }, 20);
        }
    }
 
    function OnDownClick() {
        if (okToClick) {
            okToClick = false;
 
            var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
            var hours = Number(query.val());
            if (hours != undefined) {
                hours -= 0.5;
                query.val(hours.toFixed(2));
            }
            setTimeout(function() { okToClick = true; }, 20);
        }
    }
 </script>

Notice that I have attached to both the click and doubleclick events via jQuery. Also, I put a latch around the methods so that they can’t execute twice in a very short period of time.