Search code examples
javascriptjqueryweb-applicationspull-to-refresh

How to detect Pull to refresh


There are many "pull to refresh" plugins. I have already tested 5 of them. But none of them running fast (especially on old smartphones).

What is the best (buttery UX performance and responsiveness) way to check for pull to refresh?

PS: I don't need any animation. I just want to recognize if a user "pull to refresh"


Solution

  • Performance requires minimal code

    Plugins and libraries have to be written to be as flexible and general as possible, in order to solve many related problems. This means they'll always be bulkier than you need, impacting performance. It also means you'll never have to maintain that code. That's the trade off.

    If performance is your goal, build it yourself.

    Since ALL you need is a pull-down detection, build a simple swipe detector. Of course, you'll have to adapt this to your needs, and the event-properties, event-triggers of the OS and browser you're targeting.

    Simplified from my old js-minimal-swipe-detect

    var pStart = { x: 0, y: 0 };
    var pStop = { x: 0, y: 0 };
    
    function swipeStart(e) {
      if (typeof e["targetTouches"] !== "undefined") {
        var touch = e.targetTouches[0];
        pStart.x = touch.screenX;
        pStart.y = touch.screenY;
      } else {
        pStart.x = e.screenX;
        pStart.y = e.screenY;
      }
    }
    
    function swipeEnd(e) {
      if (typeof e["changedTouches"] !== "undefined") {
        var touch = e.changedTouches[0];
        pStop.x = touch.screenX;
        pStop.y = touch.screenY;
      } else {
        pStop.x = e.screenX;
        pStop.y = e.screenY;
      }
    
      swipeCheck();
    }
    
    function swipeCheck() {
      var changeY = pStart.y - pStop.y;
      var changeX = pStart.x - pStop.x;
      if (isPullDown(changeY, changeX)) {
        alert("Swipe Down!");
      }
    }
    
    function isPullDown(dY, dX) {
      // methods of checking slope, length, direction of line created by swipe action
      return (
        dY < 0 &&
        ((Math.abs(dX) <= 100 && Math.abs(dY) >= 300) ||
          (Math.abs(dX) / Math.abs(dY) <= 0.3 && dY >= 60))
      );
    }
    
    document.addEventListener(
      "touchstart",
      function (e) {
        swipeStart(e);
      },
      false
    );
    document.addEventListener(
      "touchend",
      function (e) {
        swipeEnd(e);
      },
      false
    );