91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用JavaScript實現手勢庫

發布時間:2021-05-07 09:49:48 來源:億速云 閱讀:153 作者:小新 欄目:web開發

小編給大家分享一下怎么使用JavaScript實現手勢庫,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

JavaScript的特點

1.JavaScript主要用來向HTML頁面添加交互行為。 2.JavaScript可以直接嵌入到HTML頁面,但寫成單獨的js文件有利于結構和行為的分離。 3.JavaScript具有跨平臺特性,在絕大多數瀏覽器的支持下,可以在多種平臺下運行。

Start 事件

怎么使用JavaScript實現手勢庫

首先我們會觸發一個 start 事件,也就是當我們手指觸摸到屏幕時第一個觸發的事件。這時會有三種情況:

  • 手指松開

    • 會觸發 end 事件,這樣就構成一個 tap 點擊的行為

    • 通過監聽 end 事件來實現即可

  • 手指拖動超過 10 px

    • 這種就是 pan start 拖動的行為

    • 我們可以在 move 事件判斷當前與上一個觸點的距離

  • 手指停留在當前位置超過 0.5s

    • 這種就是 press start 按壓的行為

    • 我們可以添加一個 setTimeout 來實現

Press 事件

怎么使用JavaScript實現手勢庫

所以我們第一步就是在 start 函數中加入一個 setTimout 的 handler 處理程序。

let handler;let start = point => {
  handler = setTimeout(() => {
    console.log('presss ');
  }, 500);};

一般來說 press 是我們比較常見的一個行為。但是實際上這里是 press start 事件,后面還會跟隨著一個 press end 的事件。我們也可以統稱這個為 press 事件,然后這個手勢庫的使用者只需要監聽這個 press 事件即可,極少的情況下是需要監聽 press end 事件的。

這里我們需要注意的是,當我們觸發其他的事件的時候,這個 500 毫秒的 setTimout 是有可能會被取消掉的。所以我們需要給這段邏輯一個 handler,并且放在全局作用域中,讓其他事件可以獲取到這個變量,并且可使用它取消掉這個處理邏輯。

Pan 事件

怎么使用JavaScript實現手勢庫

接下來我們就去監聽移動 10px 的 pan 事件,這里就需要我們記錄一開始用戶觸摸屏幕時的 x 和 y 坐標,當用戶移動手指的時候,持續計算新移動到的位置與初始位置的距離。如果這個距離超過了 10px 就可以觸發我們的 pan start 的事件了。

所以首先我們需要在 start 函數中加入 startXstartY 的坐標記錄,這里要注意的是,因為這兩個值都是會在多個地方被使用的,所以也是需要在全局作用域中聲明。

然后在 move 函數中計算當前觸點與起點的直徑距離。這里我們需要用到數學中的直徑運算公式  z 2 x^2 + y^2 = z^2x 2 +y 2 =z 2 ,而這里面的 x 是 當前觸點的 x 坐標 - 起點的 x 坐標 的 x 軸的距離, y 就是 當前出點的 y 坐標 - 起點的 y 坐標 運算出來的 y 軸的距離。最終兩個距離二次冪相加就是直徑距離的二次冪。

在代碼中我們一般都會盡量避免使用根號運算,因為根號運算會對性能有一定的影響。我們知道最終要判斷的是直徑距離是否是大于一個固定的 10px。那就是說 z = 10,而 z 的二次冪就是 100,所以我們直接判斷這個直徑距離是否大于 100 即可。

這里還有一個需要注意的,就是當我們手指移動超過 10px 之后,如果我們手指沒有離開屏幕而是往回移動了,這樣的話我們距離起點已經不夠 10px了。但是這個其實也是算 pan 事件,因為我們確實有移動超過 10px 距離,超過這個距離之后所有的移動都是屬于 pan 事件。

所以我們需要一個 isPan 的狀態,第一次移動超出 10px 的時候,就會觸發 pan-start 事件,并且把 isPan 置為 true,而后面的所有移動都會觸發 pan 事件。

根據我們上面講到的 press 事件,如果我們按下手指后 0.5 秒內出現了移動,那么 press 事件就會被取消。所以這里我們就需要 clearTimeoutpressstarthandler 給清楚掉。

let handler;let startX, startY;let isPan = false;let start = point => {
  (startX = point.clientX), (startY = point.clientY);

  isPan = false;

  handler = setTimeout(() => {
    console.log('pressstart');
  }, 500);};let move = point => {
  let dx = point.clientX - startX,
    dy = point.clientY - startY;

  let d = dx ** 2 + dy ** 2;

  if (!isPan && d > 100) {
    isPan = true;
    console.log('pan-start');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log(dx, dy);
    console.log('pan');
  }};

Tap 事件

怎么使用JavaScript實現手勢庫

Tap 的這個邏輯我們可以在 end 事件里面去檢查。首先我們默認有一個 isTap 等于 true 的狀態,如果我們觸發了 pan 事件的話,那就不會去觸發 tap 的邏輯了,所以 tap 和 pan 是互斥的關系。但是為了不讓它們變得很耦合,所以我們不使用原有的 isPan 作為判斷狀態,而是另外聲明一個 isTap 的狀態來記錄。

這里我們 tap 和 pan 都有單獨的狀態,那么我們 press 也不例外,所以也給 press 加上一個 isPress 的狀態,它的默認值是 false。如果我們 0.5 秒的定時器被觸發了,isPress 也就會變成 true。

既然我們給每個事件都加入了狀態,那么這里我們就給每一個事件觸發的時候設置好這些狀態的值。

  • press 時

    • isTap = false

    • isPan = false

    • isPress = true

  • pan 時

    • isTap = false

    • isPan = true

    • isPress = false

  • tap 時

    • isTap = true

    • isPan = false

    • isPress = false

如果我們發現用戶沒有移動,也沒有按住觸屏超過 0.5 秒,當用戶離開屏幕時就會調用 end 函數,這個時候我們就可以認定用戶的操作就是 tap。這里我們要注意的是,我們 press 的 0.5 秒定時器是沒有被關閉的,所以我們在 isTap 的邏輯中需要 clearTimeout(handler)

說到取消 press 定時器,其實我們 handler 的回調函數中,也需要做一個保護代碼邏輯,在觸發了 press-start 之后,我們需要保證每次點擊屏幕只會觸發一次,所以在 setTimout 的回調函數中的最后,我們需要加上 handler = null。這樣只要 press-start 觸發了,就不會再被觸發。

let handler;let startX, startY;let isPan = false,
  isPress = false,
  isTap = false;let start = point => {
  (startX = point.clientX), (startY = point.clientY);

  isPan = false;
  isTap = true;
  isPress = false;

  handler = setTimeout(() => {
    isPan = false;
    isTap = false;
    isPress = true;
    console.log('press-start');
    handler = null;
  }, 500);};let move = point => {
  let dx = point.clientX - startX,
    dy = point.clientY - startY;

  let d = dx ** 2 + dy ** 2;

  if (!isPan && d > 100) {
    isPan = true;
    isTap = false;
    isPress = false;
    console.log('pan-start');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log(dx, dy);
    console.log('pan');
  }};let end = point => {
  if (isTap) {
    console.log('tap');
    clearTimeout(handler);
  }};

End 事件

到了最后這里我們要處理的就是所有的結束時間,包括 press-endpan-end

這兩個 end 事件都會在 end 函數中判斷所得,如果在用戶操作的過程中觸發了 pan-start 或者 press-start 事件,到了 end 函數這里,對應的狀態就會是 true。

所以我們對 end 函數做了以下改造:

let end = point => {
  if (isTap) {
    console.log('tap');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log('pan-end');
  }

  if (isPress) {
    console.log('press-end');
  }};

最后我們需要在 cancel 事件觸發的時候,清楚掉 press 事件的 setTimeout。既然我們的操作被打斷了,那也不可能會觸發我們的長按事件了。

// 加入 cancellet cancel = point => {
  clearTimeout(handler);
  console.log('cancel');};

我們除了 flick 的邏輯,我們已經完成所有手勢庫里面的事件了。并且也能正確的區分這幾種手勢操作了。

以上是“怎么使用JavaScript實現手勢庫”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汉中市| 永定县| 公安县| 大名县| 周宁县| 泰安市| 达尔| 定西市| 凌云县| 呼伦贝尔市| 论坛| 莱西市| 达拉特旗| 宜川县| 宝应县| 伽师县| 石首市| 盐边县| 临西县| 中西区| 明溪县| 仙桃市| 蓝山县| 元江| 灵寿县| 阿坝| 宝清县| 江永县| 德阳市| 丰都县| 渝北区| 湘阴县| 吴川市| 班玛县| 云安县| 邢台市| 金川县| 石狮市| 苏尼特左旗| 崇仁县| 陇西县|