前情提要:最近公司项目业务需求==>能实现在内嵌iframe标签上悬浮一个视频窗口,方便用户观看。
ps:需求过去很久了,最近有时间更新下帖子
1、需求思路
1.1、业务需求初步实现思路很简单,在iframe盒子上定位一个video标签就ok。
1.2、实现的时候因为要实现视频盒子拖拉拽功能,所以采用插件Vue3DraggableResizable,使用也比较简单,开箱即用,
2、下载依赖
npm install --save vue-draggable-resizable
3、vue组件使用
drag.vue
<template>
<Vue3DraggableResizable :initW="300" :initH="170" v-model:x="x" v-model:y="y" v-model:w="w" v-model:h="h"
v-model:active="active" :draggable="true" :resizable="true" @activated="print('activated')"
@deactivated="print('deactivated')" @drag-start="print('drag-start')"
@resize-start="print('resize-start')" @dragging="print('dragging')" @resizing="print('resizing')"
@drag-end="print('drag-end')" @resize-end="print('resize-end')">
<video style="height: 100%; width: 100%" :src="videoUrl" autoplay loop muted controls></video>
</Vue3DraggableResizable>
</template>
<script setup>
import { ref, } from 'vue'
import Vue3DraggableResizable from 'vue3-draggable-resizable'
//default styles
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
const x = ref(1150)
const y = ref(510)
const w = ref(100)
const h = ref(100)
const active = ref(false)
function print(val) {
console.log(val)
}
defineProps({
videoUrl: {
type: String,
default: () => "https://media.w3.org/2010/05/sintel/trailer.mp4"
},
})
</script>
<style></style>
4、问题
需求:在iframe上悬浮一个视频。
实现层面:在iframe的盒子内,加一个video的盒子定位到需求的位置,video盒子支持拖拉拽位置、放大缩小功能。
ps:上述代码基本已经实现功能,在觉得不会出问题的时候bug来了
bug描述:因为iframe中的内容是3d模型,内部有许多功能可以操作模型旋转、爆炸等等...., 在拖拽video盒子的时候鼠标在iframe盒子上会出现错乱的问题,拖拽video功能失效。ps:查询文档、个人理解应该是,因为video盒子实在iframe盒子上层,你的mouseenter事件在移出video盒子时,刚好进入iframe盒子导致浏览器不知道是执行那个事件,导致Vue3DraggableResizable的功能失效。
5、解决思路
在video标签缩放的时候,不是因为鼠标移入到iframe盒子会出现功能失效的问题吗?
简单粗暴:在移动缩放的时候弄个透明div盒子把iframe盒子遮住就OK了
父组件
<div class="cover-main-left-model">
<iframe
ref="iframe"
frameborder="0"
width="100%"
height="100%"
style="width: 100%; height: 100%"
class="iframe"
:key="argument"
:src="argument">
</iframe>
<!--遮罩-->
<div v-show="isResizing" style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"></div>
<Drag
v-if="processData.processResourceUrl"
:videoUrl="processData.processResourceUrl"
style="z-index: 999;"
@changeisResizing="changeisResizing"/>
</div>
<script setup lang='ts'>
import { ref } from 'vue';
const isResizing = ref(false)
// 改变透明盒子显隐藏来确保拖拉拽功能正常
function changeisResizing(value: boolean){
isResizing.value = value
}
</script>
drag.vue
<template>
<Vue3DraggableResizable :initW="300" :initH="170" v-model:x="x" v-model:y="y" v-model:w="w" v-model:h="h"
v-model:active="active" :draggable="true" :resizable="true" @activated="print('activated')"
@deactivated="print('deactivated')" @drag-start="print('drag-start')"
@resize-start="print('resize-start'), handleChange(true)" @dragging="print('dragging')" @resizing="print('resizing')"
@drag-end="print('drag-end')" @resize-end="print('resize-end'), handleChange(false)">
<video style="height: 100%; width: 100%" :src="videoUrl" autoplay loop muted controls></video>
</Vue3DraggableResizable>
</template>
<script setup>
import { defineComponent, ref, } from 'vue'
import Vue3DraggableResizable from 'vue3-draggable-resizable'
//default styles
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
const x = ref(1150)
const y = ref(510)
const w = ref(100)
const h = ref(100)
const active = ref(false)
function print(val) {
console.log(val)
}
const emits = defineEmits(["changeisResizing"]);
defineProps({
videoUrl: {
type: String,
default: () => "https://media.w3.org/2010/05/sintel/trailer.mp4"
},
})
// 触发父组件事件
function handleChange(value) {
emits("changeisResizing", value);
}
</script>
<style></style>
只是个人见解,提供一个解决思路,也有别的解决方案欢迎探讨~~~