Pinaki Mukherjee
Pinaki Mukherjee

Reputation: 1656

Jquery hoverIntent/hover function to support touch devices

We have a jquery js function that opens and closes overlay based on mouse over and mouse out. But this doesn't work on touchscreen laptops or tablets. I was reading about touchstart and touchmove function and implemented new functions like below. But it's not working like mouse over or out. What would be the best way I can achieve this.

$("#someDiv").hoverIntent({
            sensitivity: 2,
            interval: 200,
            timeout: 500,
            over: function(){
            //opens the overlay 
            $(this).someFunc();
            },
            out: function(){
                $(this).someFunc1();//closes the overlay
            }
        })

new functions:

$('#someDiv').on('touchstart',function (event) {
                 setTimeout(function() {
                   $(this).someFunc();//open overlay
               }, 500);
             });

//touchend not working - looking something similar to mouseout

$('#someDiv').on('touchend',function () {
        $(this).someFunc1();//close overlay
        });

//close it

$('body').on('touchstart', function(e){
    $(this).someFunc1();//close overlay
});

P.S - I need to implement this using jquery only.

Thanks a lot.

Upvotes: 0

Views: 569

Answers (1)

gforce301
gforce301

Reputation: 2984

Found this: jQuery taphold Event

Here is the code from that page.

Here is the link to the documentation on taphold

$(document).on("pagecreate","#pageone",function(){
  $("p").on("taphold",function(){
    $(this).hide();
  });                       
});
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<div data-role="page" id="pageone">
  <div data-role="header">
    <h1>The taphold Event</h1>
  </div>

  <div data-role="main" class="ui-content">
    <p>If you tap and hold me for one second, I will disappear.</p>
    <p>Tap and hold me!</p>
    <p>Tap and hold me too!</p>
  </div>

  <div data-role="footer">
    <h1>Footer Text</h1>
  </div>
</div>

An example using this: richadams/jquery-taphold. I converted his test.html page for use in the code snippet here and put his script in a script tag. This uses only jQuery and not jQuery UI or jQuery mobile. If you don't want to use his code you can examine how he did it and adapt it to your needs.

$(function()
    {
        $("#one").bind("taphold", function() { console.log("\ntap and hold on ONE"); });

        $("#two").on("taphold", function() { console.log("\ntap and hold on TWO"); });

        $("#three").on("taphold",
                       {clickHandler: function() { console.log("\nclick on THREE"); }},
                       function() { console.log("\ntap and hold on THREE"); });

        $("#four").on("taphold", function() { console.log("\ntap and hold on FOUR"); })
                  .on("click",   function() { console.log("\nclick on FOUR"); });

        $("#seven").on("taphold", {duration: 5000}, function() { console.log("\ntap and hold on SEVEN"); });
    });
.events div {
        width: 100px;
        height: 100px;
        margin: 20px;
        float: left;
        padding: 10px;
        font-weight: bold;
    }

    .events #one {
        background: #f00;
    }

    .events #two {
        background: #0f0;
    }

    .events #three {
        background: #000;
        color: #fff;
    }

    .events #four {
        background: #fff;
        color: #000;
        border: 1px solid #000;
    }

    .events #five {
        background: #dcda07;
        color: #000;
    }

    .events #six {
        background: #f10fff;
        color: #000;
    }

    .events #seven {
        background: #3cc9f4;
        color: #000;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
// @author Rich Adams <[email protected]>

// Implements a tap and hold functionality. If you click/tap and release, it will trigger a normal
// click event. But if you click/tap and hold for 1s (default), it will trigger a taphold event instead.

;(function($)
{
    // Default options
    var defaults = {
        duration: 1000, // ms
        clickHandler: null
    }

    // When start of a taphold event is triggered.
    function startHandler(event)
    {
        var $elem = jQuery(this);

        // Merge the defaults and any user defined settings.
        settings = jQuery.extend({}, defaults, event.data);

        // If object also has click handler, store it and unbind. Taphold will trigger the
        // click itself, rather than normal propagation.
        if (typeof $elem.data("events") != "undefined"
            && typeof $elem.data("events").click != "undefined")
        {
            // Find the one without a namespace defined.
            for (var c in $elem.data("events").click)
            {
                if ($elem.data("events").click[c].namespace == "")
                {
                    var handler = $elem.data("events").click[c].handler
                    $elem.data("taphold_click_handler", handler);
                    $elem.unbind("click", handler);
                    break;
                }
            }
        }
        // Otherwise, if a custom click handler was explicitly defined, then store it instead.
        else if (typeof settings.clickHandler == "function")
        {
            $elem.data("taphold_click_handler", settings.clickHandler);
        }

        // Reset the flags
        $elem.data("taphold_triggered", false); // If a hold was triggered
        $elem.data("taphold_clicked",   false); // If a click was triggered
        $elem.data("taphold_cancelled", false); // If event has been cancelled.

        // Set the timer for the hold event.
        $elem.data("taphold_timer",
            setTimeout(function()
            {
                // If event hasn't been cancelled/clicked already, then go ahead and trigger the hold.
                if (!$elem.data("taphold_cancelled")
                    && !$elem.data("taphold_clicked"))
                {
                    // Trigger the hold event, and set the flag to say it's been triggered.
                    $elem.trigger(jQuery.extend(event, jQuery.Event("taphold")));
                    $elem.data("taphold_triggered", true);
                }
            }, settings.duration));
    }

    // When user ends a tap or click, decide what we should do.
    function stopHandler(event)
    {
        var $elem = jQuery(this);

        // If taphold has been cancelled, then we're done.
        if ($elem.data("taphold_cancelled")) { return; }

        // Clear the hold timer. If it hasn't already triggered, then it's too late anyway.
        clearTimeout($elem.data("taphold_timer"));

        // If hold wasn't triggered and not already clicked, then was a click event.
        if (!$elem.data("taphold_triggered")
            && !$elem.data("taphold_clicked"))
        {
            // If click handler, trigger it.
            if (typeof $elem.data("taphold_click_handler") == "function")
            {
                $elem.data("taphold_click_handler")(jQuery.extend(event, jQuery.Event("click")));
            }

            // Set flag to say we've triggered the click event.
            $elem.data("taphold_clicked", true);
        }
    }

    // If a user prematurely leaves the boundary of the object we're working on.
    function leaveHandler(event)
    {
        // Cancel the event.
        $(this).data("taphold_cancelled", true);
    }

    // Determine if touch events are supported.
    var touchSupported = ("ontouchstart" in window) // Most browsers
                         || ("onmsgesturechange" in window); // Microsoft

    var taphold = $.event.special.taphold =
    {
        setup: function(data)
        {
            $(this).bind((touchSupported ? "touchstart"            : "mousedown"),  data, startHandler)
                   .bind((touchSupported ? "touchend"              : "mouseup"),    stopHandler)
                   .bind((touchSupported ? "touchmove touchcancel" : "mouseleave"), leaveHandler);
        },
        teardown: function(namespaces)
        {
            $(this).unbind((touchSupported ? "touchstart"            : "mousedown"),  startHandler)
                   .unbind((touchSupported ? "touchend"              : "mouseup"),    stopHandler)
                   .unbind((touchSupported ? "touchmove touchcancel" : "mouseleave"), leaveHandler);
        }
    };
})(jQuery);
</script>

<div class="events">
    <div id="one">ONE<br/><br/>tap-hold</div>
    <div id="two">TWO<br/><br/>tap-hold (alt)</div>
    <div id="three">THREE<br/><br/>tap-hold<br/>click</div>
    <div id="four">FOUR<br/><br/>tap-hold<br/>click (alt)</div>
    <div id="seven">SEVEN<br/><br/>5s<br/>tap-hold</div>
</div>

Upvotes: 1

Related Questions