Как создать собственную анимацию из функции jQuery longpress - PullRequest
1 голос
/ 09 ноября 2019

Обновлено (с дополнениями из ответа)

(function($) {
    $.fn.longpress = function(longCallback, duration) {

    // set some defaults
    let defaults = {
        click:      function(el, e) {},
        start:      function(el, e) { el.css("color", "#000"); },
        complete:   function(el, e) { el.css("color", "#FFF"); },
        cancel:     function(el, e) { el.css("color", "#F00"); },
        duration:   1000
    };

    // extend the options
    let options = $.extend({}, defaults);

    return this.each(function() {
        var $this = $(this);

        // to keep track of how long something was pressed
        var mouse_down_time;
        var timeout;
        $this.data("clicked", "false");

        // mousedown or touchstart callback
        function mousedown_callback(e) {

            // start callback
            options.start($this, e);

            $this.data("clicked", "true");
            mouse_down_time = new Date().getTime();
            var context = $(this);

            // set a timeout to call the longpress callback when time elapses
            timeout = setTimeout(function() {
                if (typeof longCallback === "function") {
                    longCallback.call(context, e);
                    options.complete($this, e);
                    $this.data("clicked", "false");
                } else {
                    $.error('Callback required for long press. You provided: ' + typeof longCallback);
                }
            }, options.duration);

        }

        // mouseup or touchend callback
        function mouseup_callback(e) {
            var press_time = new Date().getTime() - mouse_down_time;

            if (press_time < options.duration) {
                // cancel the timeout
                clearTimeout(timeout);
                $this.data("clicked", "false");

                // call the click if provided
                options.click($this, e);
            }
        }

        // cancel long press event if the finger or mouse was moved
        function move_callback(e) {
            let isClicked = $this.data("clicked");
            if (isClicked == "false")
                return;

            // call the cancel callback
            options.cancel($this, e);
            clearTimeout(timeout);
            $this.data("clicked", "false");
        }


      // Browser Support
      $this.on('mousedown', mousedown_callback);
      $this.on('mouseup', mouseup_callback);
      $this.on('mousemove', move_callback);

      // Mobile Support
      $this.on('touchstart', mousedown_callback);
      $this.on('touchend', mouseup_callback);
      $this.on('touchmove', move_callback);
    });
  };
}(jQuery));

У меня есть плагин jQuery, который я недавно обнаружил (не могу вспомнить источник), который позволил мне иметьфункции долгого нажатия на веб-сайте:

(function(b) {
    b.fn.longpress = function(e, c, d) {
        "undefined" === typeof d && (d = 1000);
        return this.each(function() {
            function g(a) {
                h = (new Date).getTime();
                var c = b(this);
                f = setTimeout(function() {
                    "function" === typeof e ? e.call(c, a) : b.error("Callback required for long press. You provided: " + typeof e)
                }, d)
            }

            function k(a) {
                (new Date).getTime() - h < d && (clearTimeout(f), "function" === typeof c ? c.call(b(this), a) : "undefined" !== typeof c && b.error("Optional callback for short press should be a function."))
            }

            function l(a) {
                clearTimeout(f)
            }
            var a = b(this),
                h, f;
            a.on("mousedown", g);
            a.on("mouseup", k);
            a.on("mousemove", l);
            a.on("touchstart", g);
            a.on("touchend", k);
            a.on("touchmove", l)
        })
    }
})(jQuery);

Это прекрасно работает, но мне было интересно, можно ли было сказать, что фон изменился с #fff до #000 или сделать какую-либо другую пользовательскую анимацию на основена длительное нажатие.

Я играл, но не мог понять. Я пытался добавить класс для каждой секунды, когда удерживалось долгое нажатие, затем для каждого правила было CSS. Затем я попытался использовать steps в CSS, чтобы сделать это тоже время, но не смог заставить это работать, так как классы добавляли только тогда, когда долгое нажатие было успешным и не загружалось.

Ответы [ 2 ]

1 голос
/ 12 ноября 2019

Поскольку вы определяете плагин, вы можете добавить некоторые варианты поведения. Одним из способов анимации было бы использование переходов на основе классов, которые вы добавляете на разных этапах. И на время вы можете определить его в плагине, чтобы он имел ту же длину, что и задержка длинного нажатия. Вот так например:

(function(b) {
  b.fn.longpress = function(e, c, d) {
    "undefined" === typeof d && (d = 1000);
    return this.each(function() {
      function g(a) {
        h = (new Date).getTime();
        var c = b(this);
        // here you define transition duration using user defined or default long press delay
        c.css("transition-duration", d + 'ms');
        // the class while element is being pressed
        c.addClass("pressing");
        f = setTimeout(function() {
          // when delay is done you remove pressing, add another class to signify the element has been long pressed
          c.removeClass("pressing").addClass("pressed");

          "function" === typeof e ? e.call(c, a) : b.error("Callback required for long press. You provided: " + typeof e)
        }, d)
      }

      function k(a) {
        // this is the cancel callback, so you remove pressing
        $(this).removeClass("pressing");
        (new Date).getTime() - h < d && (clearTimeout(f), "function" === typeof c ? c.call(b(this), a) : "undefined" !== typeof c && b.error("Optional callback for short press should be a function."))
      }

      function l(a) {
        clearTimeout(f)
      }
      var a = b(this),
        h, f;
      a.on("mousedown", g);
      a.on("mouseup", k);
      a.on("mousemove", l);
      a.on("touchstart", g);
      a.on("touchend", k);
      a.on("touchmove", l)
    })
  }
})(jQuery);


$('#a').longpress(function(e) {
  this.text('pressed')
}, function() {}, 1500)
div {
  background-color: #fff;
  transition: background-color;
  transition-timing-function: linear;
  cursor: pointer;
}

.pressing {
  background-color: #000;
}

.pressed {
  background-color: #FF0;
  transition: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=a>
  long press me
</div>
0 голосов
/ 12 ноября 2019

Оригинальный плагин можно найти здесь: https://github.com/vaidik/jquery-longpress.

Я изменил, чтобы принять объект параметров (объяснено в комментариях). Вот пример:

(function($) {
  $.fn.longpress = function(opts) {
    let defaults = {
      click: function(el, e) {},
      start: function(el, e) {},
      complete: function(el, e) {},
      duration: 500
    };

    let options = $.extend({}, defaults, opts);

    return this.each(function() {
      var $this = $(this);

      // to keep track of how long something was pressed
      var mouse_down_time;
      var timeout;
      $this.data("clicked", "false");

      // mousedown or touchstart callback
      function mousedown_callback(e) {

        // start callback
        options.start($this, e);

        $this.data("clicked", "true");
        mouse_down_time = new Date().getTime();
        var context = $(this);

        // set a timeout to call the longpress callback when time elapses
        timeout = setTimeout(function() {
          options.complete($this, e);
          $this.data("clicked", "false");
        }, options.duration);
      }

      // mouseup or touchend callback
      function mouseup_callback(e) {
        var press_time = new Date().getTime() - mouse_down_time;
        if (press_time < options.duration) {
          // cancel the timeout
          clearTimeout(timeout);
          $this.data("clicked", "false");

          // call the click if provided
          options.click($this, e);
        }
      }

      // cancel long press event if the finger or mouse was moved
      function move_callback(e) {
        let isClicked = $this.data("clicked");
        if (isClicked == "false")
          return;

        // call the cancel callback
        options.cancel($this, e);
        clearTimeout(timeout);
        $this.data("clicked", "false");
      }


      // Browser Support
      $this.on('mousedown', mousedown_callback);
      $this.on('mouseup', mouseup_callback);
      $this.on('mousemove', move_callback);

      // Mobile Support
      $this.on('touchstart', mousedown_callback);
      $this.on('touchend', mouseup_callback);
      $this.on('touchmove', move_callback);
    });
  };
}(jQuery));

let options = {
  // Callback after a "normal" click has completed
  click: function(el, event) {
    el.removeClass("rotate");
  },
  // callback after longpress completed
  complete: function(el, event) {
    el.removeClass("rotate");
  },
  // callback before click starts (for both normal and longpress clicks)
  start: function(el, event) {
    el.addClass("rotate");
  },
  // Callback when click is cancelled (user moves mouse)
  cancel: function(el, event) {
    el.removeClass("rotate");
  },
  // Longpress duration
  duration: 5000
};
$('#button').longpress(options);
div {
  border: 1px solid;
  width: 200px;
  height: 200px;
  left: 50px;
  top: 50px;
  position: relative;
}

.rotate {
  animation: 1s rotate infinite linear;
}

@keyframes rotate {
  100% {
    transform: rotate(1turn);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='button'>

</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...