Search code examples
jqueryonclickclickmousedownmouseup

How to still highlight / copy / paste when I'm using a click event?


I have a click event attached to a table row (could be any object):

<table>
<tr class="row"><td>http://google.com</td></tr>
<tr class="row"><td>http://teslamotors.com</td></tr>
<tr class="row"><td>http://solarcity.com</td></tr>
</table>

<script>
    $(document).ready(function() {
       $(".row").click(function() {
           var href = $(this).find("td").html();
           window.location.href = href;
       }
    }
</script>

When I have a click event on the row, once I start to left-click and highlight the text, the click event fires before the user has a chance to copy/paste.

How do I still allow the user to select text on that row for copy and pasting?

NOTE: This question is instructional, I'll be providing my own answer.


Solution

  • The answer is in the tags. You have capture the mousedown and mouseup events.

    1. First catch the mousedown event and store the state.
    2. Next catch the mouseup event and compare the coordinates of with the mousedown state.
    3. If the mouse has moved significantly between events, don't process the click.

    Replace the above script section as follows:

    <script>
    $(document).ready(function() {
        var lastMouseDownEvent = null;
    
        // capture your last "mousedown" event and store it
        $(".row").mousedown(function(event) {
            console.log(event); // lets see the data in your Developer Mode log
            lastMouseDownEvent = event;
        });
    
        // catch the "mouseup" event and compare the distance from "mousedown"
        $(".row").mouseup(function(event) {
            console.log(event);
    
            var href = $(this).find("td").html();
            switch(event.which) {
                case 1: // left click
                    // only process left click if mousedown and mouseup occur at the same location on screen.
                    // NOTE: for my mom's shaky hand I added the 5 pixel allowance.
                    if (Math.abs(event.clientX-lastMouseDownEvent.clientX) < 5 &&
                        Math.abs(event.clientY-lastMouseDownEvent.clientY < 5))
                        window.location.href = href;
                    break;
            }
            lastMouseDownEvent = null;
        });
    });
    </script>