最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue?懸浮窗且?guī)ё詣游焦δ軐?shí)現(xiàn)demo

 更新時間:2023年06月30日 09:05:58   作者:Skywang  
這篇文章主要為大家介紹了vue?懸浮窗且?guī)ё詣游焦δ軐?shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

封裝的組件代碼

之前寫過懸浮窗的效果,這次做了個總結(jié),網(wǎng)頁端和移動端都可以用兼容,封裝的組件代碼,可以引到頁面直接使用

代碼

做了簡單的注釋 大家自行了解

HTML

<template>
  <div
    ref="floatDrag"
    class="float-position"
    :style="{ left: left + 'px', top: top + 'px', zIndex: zIndex }"
    @touchmove.prevent
    @mousemove.prevent
    @mousedown="mouseDown"
    @mouseup="mouseUp"
  >
    <div id="side-windows">
      <div class="shrink">
      <div class="problem-feedback" @click.stop="showDialog()">
        <img :src="feedback" alt="" />
        <p>問題<br />反饋</p>
      </div>
      </div>
    </div>
  </div>
</template>

JS

<script>
export default {
  name: "DragBall",
  props: {
    distanceRight: { // 初始化定位
      type: Number,
      default: 0
    },
    distanceBottom: { // 初始化定位
      type: Number,
      default: 100
    },
    isScrollHidden: { //滾動是否 隱藏
      type: Boolean,
      default: false
    },
    isCanDraggable: { //是否允許拖拽
      type: Boolean,
      default: true
    },
    zIndex: { // 初始化層級
      type: Number,
      default: 50
    },
    value: {
      type: String,
      default: "懸?。?
    }
  },
  //data 域
  data() {
    return {
      clientWidth: null,
      clientHeight: null,
      left: 0,
      top: 0,
      timer: null,
      currentTop: 0,
      mousedownX: 0,
      mousedownY: 0,
      feedback: require('') // 問題
    };
  },
  created() {
    this.clientWidth = document.documentElement.clientWidth;
    this.clientHeight = document.documentElement.clientHeight;
  },
  mounted() {
    this.isCanDraggable &&
      this.$nextTick(() => {
        this.floatDrag = this.$refs.floatDrag;
        // 獲取元素位置屬性
        this.floatDragDom = this.floatDrag.getBoundingClientRect();
        // 設(shè)置初始位置
        this.left =
          this.clientWidth - this.floatDragDom.width - this.distanceRight;
        this.top =
          this.clientHeight - this.floatDragDom.height - this.distanceBottom;
        this.initDraggable();
      });
    this.isScrollHidden && window.addEventListener("scroll", this.handleScroll);
    window.addEventListener("resize", this.handleResize);
  },
  methods: {
      showDialog() {
        let url
        window.open(url, '_blank')
      },
    /**
     * 設(shè)置滾動時隱藏懸浮按鈕,停止時顯示
     */
    handleScroll() {
      this.timer && clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.handleScrollEnd();
      }, 200);
      this.currentTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (this.left > this.clientWidth / 2) {
        // 判斷元素位置再左側(cè)還是右側(cè)
        this.left = this.clientWidth + this.floatDragDom.width;
      } else {
        this.left = -this.floatDragDom.width;
      }
    },
    /**
     * 滾動結(jié)束
     */
    handleScrollEnd() {
      let scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (scrollTop === this.currentTop) {
        console.log(this.left);
        if (this.left > this.clientWidth / 2) {
          // 判斷元素位置
          this.left = this.clientWidth - this.floatDragDom.width;
        } else {
          this.left = 0;
        }
        clearTimeout(this.timer);
      }
    },
    /**
     * 窗口監(jiān)聽
     */
    handleResize() {
      this.clientWidth = document.documentElement.clientWidth;
      this.clientHeight = document.documentElement.clientHeight;
      this.checkDraggablePosition();
    },
    /**
     * 初始化
     */
    initDraggable() {
      this.floatDrag.addEventListener("touchstart", this.toucheStart);
      this.floatDrag.addEventListener("touchmove", e => this.touchMove(e));
      this.floatDrag.addEventListener("touchend", this.touchEnd);
    },
    mouseDown(e) {
      const event = e || window.event;
      this.mousedownX = event.screenX;
      this.mousedownY = event.screenY;
      const that = this;
      let floatDragWidth = this.floatDragDom.width / 2;
      let floatDragHeight = this.floatDragDom.height / 2;
      if (event.preventDefault) {
        event.preventDefault();
      }
      this.canClick = false;
      this.floatDrag.style.transition = "none";
      setTimeout(() => {
        document.onmousemove = function(e) {
            var event = e || window.event;
            that.left = event.clientX - floatDragWidth;
            that.top = event.clientY - floatDragHeight;
            if (that.left < 0) that.left = 0;
            if (that.top < 0) that.top = 0;
            if (that.left >= that.clientWidth - floatDragWidth * 2) {
                that.left = that.clientWidth - floatDragWidth * 2;
            }
            if (that.top >= that.clientHeight - floatDragHeight * 2) {
                that.top = that.clientHeight - floatDragHeight * 2;
            }
            // 解決鼠標(biāo)移出窗口 松開鼠標(biāo)后 回到窗口內(nèi) 懸浮繼續(xù)跟隨問題
            if(event.clientX<=0 || event.clientY<=0 ||  event.clientY>= that.clientHeight || event.clientX>= that.clientWidth){
                that.mouseUp(event)
            }
        };
      }, 20);
    },
    mouseUp(e) {
      const event = e || window.event;
      //判斷只是單純的點(diǎn)擊,沒有拖拽
      if (
        this.mousedownY == event.screenY &&
        this.mousedownX == event.screenX
      ) {
        this.$emit("handlepaly");
      }
      document.onmousemove = null;
      this.checkDraggablePosition();
      this.floatDrag.style.transition = "all 0.3s";
    },
    toucheStart() {
      this.canClick = false;
      this.floatDrag.style.transition = "none";
    },
    touchMove(e) {
      this.canClick = true;
      if (e.targetTouches.length === 1) {
        let touch = event.targetTouches[0];
        this.left = touch.clientX - this.floatDragDom.width / 2;
        this.top = touch.clientY - this.floatDragDom.height / 2;
      }
    },
    touchEnd() {
      if (!this.canClick) return; // 解決點(diǎn)擊事件和touch事件沖突的問題
      this.floatDrag.style.transition = "all 0.3s";
      this.checkDraggablePosition();
    },
    /**
     * 判斷元素顯示位置
     * 在窗口改變和move end時調(diào)用
     */
    checkDraggablePosition() {
      let details = document.querySelector('.details')
      if (this.left + this.floatDragDom.width / 2 >= this.clientWidth / 2) {
        // 判斷位置是往左往右滑動
        this.left = this.clientWidth - this.floatDragDom.width;
        details.style.right = '56px'
      } else {
        this.left = 0;
        details.style.right = '-233px'
      }
      if (this.top < 0) {
        // 判斷是否超出屏幕上沿
        this.top = 0;
      }
      if (this.top + this.floatDragDom.height >= this.clientHeight) {
        // 判斷是否超出屏幕下沿
        this.top = this.clientHeight - this.floatDragDom.height;
      }
    }
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.handleScroll);
    window.removeEventListener("resize", this.handleResize);
  }
};
</script>

樣式

<style lang="less" scoped>
.float-position{
  font-size: 12px;
  position: fixed;
  z-index: 500!important;
  right: 0;
  top: 50%;
  width: 48px;
  height: 168px;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}
</style>

以上就是vue 懸浮窗且?guī)ё詣游焦δ軐?shí)現(xiàn)demo的詳細(xì)內(nèi)容,更多關(guān)于vue 懸浮窗自動吸附的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue CLI3搭建的項(xiàng)目中路徑相關(guān)問題的解決

    Vue CLI3搭建的項(xiàng)目中路徑相關(guān)問題的解決

    這篇文章主要介紹了Vue CLI3搭建的項(xiàng)目中路徑相關(guān)問題的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue中集成省市區(qū)街四級地址組件的實(shí)現(xiàn)過程

    vue中集成省市區(qū)街四級地址組件的實(shí)現(xiàn)過程

    我們在開發(fā)中常會遇到選擇地址的需求,有時候只需要選擇省就可以,有時候則需要選擇到市、縣,以至于鄉(xiāng)鎮(zhèn),甚至哪個村都有可能,下面這篇文章主要給大家介紹了關(guān)于vue中集成省市區(qū)街四級地址組件的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • Vue生態(tài)系統(tǒng)工具庫Vueuse的使用示例詳解

    Vue生態(tài)系統(tǒng)工具庫Vueuse的使用示例詳解

    Vueuse 是一個功能強(qiáng)大的 Vue.js 生態(tài)系統(tǒng)工具庫,它提供了一系列的可重用的 Vue 組件和函數(shù),本文將介紹 Vueuse 的主要特點(diǎn)和用法,以及它在 Vue.js 開發(fā)中的作用和優(yōu)勢,感興趣的可以了解下
    2024-02-02
  • vue實(shí)現(xiàn)把頁面導(dǎo)出成word文件的方法

    vue實(shí)現(xiàn)把頁面導(dǎo)出成word文件的方法

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)把頁面導(dǎo)出成word文件的方法,文中的實(shí)現(xiàn)步驟講解詳細(xì),并且有詳細(xì)的代碼示例,需要的小伙伴可以參考一下
    2023-10-10
  • vue實(shí)現(xiàn)自定義樹形組件的示例代碼

    vue實(shí)現(xiàn)自定義樹形組件的示例代碼

    這篇文章主要介紹了vue實(shí)現(xiàn)自定義樹形組件的示例代碼,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Vue封裝通過API調(diào)用的組件的方法詳解

    Vue封裝通過API調(diào)用的組件的方法詳解

    在日常業(yè)務(wù)開發(fā)中我們會經(jīng)常封裝一些業(yè)務(wù)組件,下面這篇文章主要給大家介紹了關(guān)于Vue封裝通過API調(diào)用的組件的方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • vue實(shí)現(xiàn)給某個數(shù)據(jù)字段添加顏色

    vue實(shí)現(xiàn)給某個數(shù)據(jù)字段添加顏色

    這篇文章主要介紹了vue實(shí)現(xiàn)給某個數(shù)據(jù)字段添加顏色方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue + socket.io實(shí)現(xiàn)一個簡易聊天室示例代碼

    vue + socket.io實(shí)現(xiàn)一個簡易聊天室示例代碼

    本篇文章主要介紹了vue + socket.io實(shí)現(xiàn)一個簡易聊天室示例代碼,具有一定的參考價值,有興趣的可以了解一下。
    2017-03-03
  • vue之Element-Ui輸入框顯示與隱藏方式

    vue之Element-Ui輸入框顯示與隱藏方式

    這篇文章主要介紹了vue之Element-Ui輸入框顯示與隱藏方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 如何測量vue應(yīng)用運(yùn)行時的性能

    如何測量vue應(yīng)用運(yùn)行時的性能

    這篇文章主要介紹了如何測量vue應(yīng)用運(yùn)行時的性能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下
    2019-06-06

最新評論

黑山县| 慈溪市| 磐石市| 新兴县| 福清市| 东丰县| 阿克苏市| 醴陵市| 安吉县| 宁城县| 木里| 沈阳市| 收藏| 延川县| 牙克石市| 离岛区| 北碚区| 定安县| 璧山县| 台安县| 卓尼县| 洛扎县| 绥化市| 蓬溪县| 绵阳市| 简阳市| 台安县| 孟津县| 邵武市| 兴仁县| 木兰县| 阿图什市| 从化市| 平罗县| 黎城县| 汉川市| 开远市| 阳原县| 嵊泗县| 石林| 鲁甸县|