欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

阻止mousemove鼠標(biāo)移動或touchmove觸摸移動觸發(fā)click點(diǎn)擊事件

 更新時間:2023年06月13日 11:50:16   作者:天問  
這篇文章主要為大家介紹了阻止mousemove或touchmove與click事件同時觸發(fā)技巧,一個按鈕綁定了多個事件,所以就要想辦法阻止 mouse 鼠標(biāo)事件或 touch 觸摸事件 與 click 事件同時觸發(fā),不然每次拖拽按鈕后都會觸發(fā) click 事件,這顯然是不友好的

一、背景

最近做了自己的開源項(xiàng)目 Msw-Tools,參考了 VConsole 工具中按鈕的拖拽功能,計(jì)劃給 MSW 按鈕也增加類似的拖拽效果,并兼容PC端和手機(jī)端,但是遇到一個問題:一個按鈕綁定了多個事件,怎樣才能阻止 mousemove 或 touchmove 與 click 事件同時觸發(fā)。

MSW Tools

如上圖所示,實(shí)現(xiàn) MSW 按鈕拖拽要用到 mousedown、mousemove、mouseup 事件,對應(yīng)的移動端要用到 touchstart、touchmove、touchend 事件,但是按鈕上已經(jīng)綁定了 click 點(diǎn)擊事件,所以就要想辦法阻止 mouse 鼠標(biāo)事件或 touch 觸摸事件 與 click 事件同時觸發(fā)。不然每次拖拽按鈕后都會觸發(fā) click 事件,這顯然是不友好的。

二、問題解析

事件的執(zhí)行順序依次是:mousedown > mousemove > mouseup > click,因此,要想 mouseup 事件執(zhí)行完后,不執(zhí)行 click 事件,可能不太好直接處理,但是可以間接的實(shí)現(xiàn)。設(shè)置一個 移動狀態(tài)的開關(guān),并加上 延遲處理 就可以達(dá)到"阻止 click 事件"的目的。

三、代碼實(shí)現(xiàn)

因?yàn)?Msw-Tools 工具是使用 Svelte 框架開發(fā)的,所以這里展示 Svelte 部分代碼。

<!-- msw.svelte -->
<div class="msw-container">
  <div on:click|stopPropagation={showModal}
       bind:this={btnDOM}
       class="msw-show">MSW</div>
</div>
<script>
  import { onMount } from "svelte";
  // 區(qū)分當(dāng)前是PC端,還是移動端,來設(shè)置 mouse 事件 或 touch 事件
  function getModels() {
    let userAgentInfo = navigator.userAgent;
    let mobileAgents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
    return mobileAgents.reduce((prev, ua)=>{
      return userAgentInfo.includes(ua) || prev
    }, false)
  };
  const MSW_BTN_POSITION = '__MSW_BTN_POSITION__'
  let show = false;
  let btnDOM = null;
  let isDrop = false;
  let isMoving = false;
  let offset = {
    x: 0,
    y: 0,
  };
  let offsetDown = {};
  let dropTimer = null;
  let isMobile = getModels();
  let btnW = 0;
  let btnH = 0;
  let clientW = 0;
  let clientH = 0;
  let eventType = isMobile ? 'touchstart' : 'mousedown';
  // DOM 掛載后執(zhí)行
  onMount(async () => {
    // 初始化,獲取按鈕、視口寬高、計(jì)算邊界值
    initClientData();
    return () => {
      // component 卸載后,解除事件綁定
      btnDOM.removeEventListener(eventType, btnMousedown)
    }
  });
  function initClientData() {
    // 按鈕位置保存在本地,可以記住位置,避免每次去拖拽
    let local = localStorage.getItem(MSW_BTN_POSITION)
    if (local) {
      offset = JSON.parse(local)
      btnMove()
    }
    let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
    clientW = isMobile ? w : document.body.clientWidth
    clientH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
    btnW = btnDOM.offsetWidth
    btnH = btnDOM.offsetHeight
    // 給按鈕綁定 mousedown 或 touchstart 事件
    btnDOM.addEventListener(eventType, btnMousedown)
  }
  function eventHandle (type) {
    if (isMobile) {
      document[`${type}EventListener`]('touchmove', mousemove);
      document[`${type}EventListener`]('touchend', mouseup);
    } else {
      document[`${type}EventListener`]('mousemove', mousemove);
      document[`${type}EventListener`]('mouseup', mouseup);
    }
  }
  function showModal () {
    if (!isMoving) {
      show = true;
    }
  }
  function btnMousedown(e) {
    e = e || window.event
    isDrop = true
    offsetDown = {
      ...getOffset(e)
    };
    eventHandle('add')
  }
  function mousemove(e) {
    e = e || window.event
    if (isDrop) {
      let data = getOffset(e);
      // 判斷是否移動了
      isMoving = !(offsetDown.x === data.x && offsetDown.y === data.y)
      let x = data.x - btnW / 2;
      let y = data.y - btnH / 2;
      if (x > 5 && x < (clientW-btnW - 5)) {
        offset.x = x;
      }
      if (y > 5 &&  y < (clientH-btnH - 5)) {
        offset.y = y;
      }
      if (isMoving) {
        btnMove()
      }
      clearTimeout(dropTimer);
      dropTimer = setTimeout(()=>{
        isMoving = false;
        clearTimeout(dropTimer);
        dropTimer = null;
      }, 300);
    }
  }
  function mouseup() {
    if (isDrop) {
      window.localStorage.setItem(MSW_BTN_POSITION, JSON.stringify(offset))
      eventHandle('remove')
    }
    isDrop = false
    // console.log('mouseup')
  }
  function btnMove (){
    btnDOM.style.cssText = `
    left: ${offset.x}px;
    top: ${offset.y}px;
    right: auto;
    bottom: auto;
    `
  }
  function getOffset(e) {
    return isMobile ? {
      x: e.targetTouches[0].clientX,
      y: e.targetTouches[0].clientY,
    } : {
      x: e.clientX,
      y: e.clientY,
    }
  }
</script>
<style lang="scss" type="text/scss">
  @import "index";
</style>

以上就是阻止mousemove鼠標(biāo)移動或touchmove觸摸移動觸發(fā)click點(diǎn)擊事件的詳細(xì)內(nèi)容,更多關(guān)于阻止鼠標(biāo)移動觸發(fā)點(diǎn)擊事件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論