Quellcode durchsuchen

[Feature] 飘窗V1.0

AA vor 10 Monaten
Ursprung
Commit
56dd3c8fa5
3 geänderte Dateien mit 172 neuen und 1 gelöschten Zeilen
  1. 8 0
      src/api/tip.js
  2. 160 0
      src/components/FloatWindow/index.vue
  3. 4 1
      src/layout/index.vue

+ 8 - 0
src/api/tip.js

@@ -0,0 +1,8 @@
+import request from '@/utils/request'
+
+export function fetchLatestTip(data) {
+  return request({
+    url: 'tip/getLatestTip',
+    method: 'get'
+  })
+}

+ 160 - 0
src/components/FloatWindow/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <!--悬浮窗口样式的提示信息-->
+  <!--
+    @mouseover:当鼠标移入是触发,移入和移出其子元素时候也会触发
+    @mouseout:当鼠标移出元素时候触发,移入和移出其子元素也会触发
+  -->
+  <div v-show="isShow" id="floatWindowDiv" ref="floatWindowDiv" style="position: absolute" @mouseover="stopFloat" @mouseout="startFloat">
+    <div>
+      <div class="close-btn" @click="isShow = false">关闭</div>
+      <div v-html="content" />
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchLatestTip } from '@/api/tip'
+import { isNull } from '@/utils/convert'
+
+export default {
+  name: 'FloatingWindow',
+  data() {
+    return {
+      // 最顶层左右移动,数值越大越靠右
+      xPos: 0,
+      // 靠左上下移动,数值越大起始位置越靠下
+      yPos: 0,
+      // 移动速度,数值越大移动速度越快
+      step: 1,
+      // 周期性执行或者调用code之间的时间间隔
+      delay: 50,
+      // height: 0,
+      Hoffset: 0,
+      Woffset: 0,
+      // 与yPos结合使用,0代表向上移动,1代表向下移动
+      yon: 0,
+      // 与xPos结合使用,0代表向右下方移动,1代表向左下方移动
+      xon: 0,
+      pause: true,
+      // 开启窗口
+      isShow: false,
+      start: '',
+      //
+      content: ''
+    }
+  },
+  mounted() {
+    // 第一个飘动窗口
+    // setInterval: 会不停的调用函数,直到clearInterval被调用或者窗口被关闭。由setInterval返回的ID值可用做clearInterval方法的参数
+    // setInterval(code,millisec[,"lang"])
+    // code: 必需的。要调用的函数或者要执行的代码串
+    // millisec:必需的.周期性执行或者调用code之间的时间间隔,以毫秒计算
+    // this.start = setInterval(this.changePos, this.delay)
+  },
+  created() {
+    // this.xPos = Math.round(Math.random() * 1670) // 生成0~1670的随机整数
+    // this.yPos = Math.round(Math.random() * 868) // 生成0~868的随机整数
+    this.yon = Math.round(Math.random()) // 生成0~1的随机整数
+    this.xon = Math.round(Math.random()) // 生成0~1的随机整数
+    this.getLatestTip()
+  },
+  methods: {
+    getLatestTip() {
+      fetchLatestTip().then(res => {
+        if (!isNull(res.data)) {
+          this.content = res.data
+          this.isShow = true
+          this.startFloat()
+        }
+      }).catch(error => {
+        console.log(error)
+        this.$message({
+          type: 'error',
+          duration: 0,
+          showClose: true,
+          message: '获取飘窗内容出错: ' + error.message
+        })
+      })
+    },
+    // 飘动窗口配置
+    changePos() {
+      // 网页可见区域的宽度
+      const width = document.documentElement.clientWidth
+      // 网页可见区域的高度
+      const height = document.documentElement.clientHeight
+      // 获取标签元素的高度
+      this.Hoffset = this.$refs.floatWindowDiv.offsetHeight
+      // 获取标签元素的宽度
+      this.Woffset = this.$refs.floatWindowDiv.offsetWidth
+
+      // 滚动部分跟随屏幕滚动
+      // document.body.scrollLeft 网页被卷去的左
+      // scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
+      // document.documentElement.scrollLeft : 设置或获取页面文档向右滚动过的像素数
+      this.$refs.floatWindowDiv.style.left = this.xPos + document.body.scrollLeft + document.documentElement.scrollLeft + 'px'
+      // document.body.scrollTop 网页被卷去的高
+      // scrollTop:设置或获取位于对象对顶端和窗口中可见内容的最顶端之间的距离
+      // document.documentElement.scrollTop :设置或获取页面文档向下滚动过的像素数
+      this.$refs.floatWindowDiv.style.top = this.yPos + document.body.scrollTop + document.documentElement.scrollTop + 'px'
+
+      // 滚动部分不随屏幕滚动
+      // this.$refs.floatWindowDiv.style.left = this.xPos + document.body.scrollLeft + 'px'
+      // this.$refs.floatWindowDiv.style.top = this.yPos + document.body.scrollTop + 'px'
+
+      if (this.yon) {
+        this.yPos = this.yPos + this.step
+      } else {
+        this.yPos = this.yPos - this.step
+      }
+      if (this.yPos < 0) {
+        this.yon = 1
+        this.yPos = 0
+      }
+      if (this.yPos >= height - this.Hoffset) {
+        this.yon = 0
+        this.yPos = height - this.Hoffset
+      }
+
+      if (this.xon) {
+        this.xPos = this.xPos + this.step
+      } else {
+        this.xPos = this.xPos - this.step
+      }
+      if (this.xPos < 0) {
+        this.xon = 1
+        this.xPos = 0
+      }
+      if (this.xPos >= width - this.Woffset) {
+        this.xon = 0
+        this.xPos = width - this.Woffset
+      }
+    },
+    // 鼠标接触停止配置
+    stopFloat() {
+      // clearInterval:可以取消由setInterval设置的timeout时间间隔。参数必需是setInterval返回的ID值-->
+      clearInterval(this.start)
+    },
+    startFloat() {
+      this.start = setInterval(this.changePos, this.delay)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+#floatWindowDiv {
+  z-index: 1200;
+  position: absolute;
+  background-color: rgba(128, 128, 128, 0.4);
+  //overflow: hidden;
+
+  .close-btn {
+    padding: 5px;
+    font-size: 12px;
+    text-align: right;
+    color: red;
+
+    cursor: pointer;
+  }
+}
+</style>

+ 4 - 1
src/layout/index.vue

@@ -10,11 +10,13 @@
       </div>
       <app-main />
     </div>
+    <float-window />
   </div>
 </template>
 
 <script>
 import { HeaderTop, Sidebar, AppMain, TagsView } from './components'
+import FloatWindow from '@/components/FloatWindow'
 // 不适配移动端
 // import ResizeMixin from './mixin/ResizeHandler'
 import { mapState } from 'vuex'
@@ -25,7 +27,8 @@ export default {
     HeaderTop,
     Sidebar,
     AppMain,
-    TagsView
+    TagsView,
+    FloatWindow
   },
   // mixins: [ResizeMixin],
   computed: {