这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
前言
需求:实现弹框可拖拽移动,内嵌的聊天对话框为iframe。
问题
遇到的问题:由于内嵌的是iframe,当鼠标按下快速移动时(鼠标脱离外框),鼠标事件失效,造成的直观感受是拖动卡顿,左右移动还行,但是快速下移就失效。
原因分析
左右移动时鼠标始终在边框淡蓝色区域,快速下移时鼠标脱离淡蓝色区域并移到iframe的元素上鼠标事件失效
解决办法
pointer-events 值none表示鼠标事件“穿透”该元素并且指定该元素“下面”的任何东西。(MDN)
因此,在鼠标按下mousedown时设置iframe的pointer-events值为none,使得事件能够穿透整个框。鼠标松开事件mouseup为unset。
另外在弹框拖拽移动时,底图地图也会跟着移动,设置思路同iframe相同。
完整功能代码:
<template>
<div
class="draggable-div"
:id="domId"
@mousedown="handleMouseDown"
:style="dragStyleStr"
>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'DraggableDiv',
data() {
return {
dragStyleStr: '',
dragMes: {},
domId: ''
};
},
props: {
artDomId: String
},
mounted() {
this.domId = this.artDomId ? this.artDomId : new Date().getTime();
},
methods: {
handleMouseDown(e) {
const ele = document.getElementById('chatPanelIframe');
ele.style.pointerEvents = 'none';
this.bus.$emit('setPan', false);
const that = this;
const oBox = document.getElementById(this.domId);
this.dragMes.disX = e.clientX - oBox.offsetLeft;
this.dragMes.disY = e.clientY - oBox.offsetTop;
document.onmousemove = e => {
let left = e.clientX - this.dragMes.disX + 'px';
let top = e.clientY - this.dragMes.disY + 'px';
this.dragStyleStr = `left: ${left};top: ${top}`;
};
document.onmouseup = () => {
this.bus.$emit('setPan', true);
ele.style.pointerEvents = 'auto';
document.onmousemove = document.onmouseup = null;
};
e.preventDefault();
}
}
};
</script>
<style lang="scss" scoped>
.draggable-div {
position: fixed;
z-index: 9999;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
总结
以上就是开发弹框拖拽时遇到的一些问题,供大家参考。可能开发过程中遇到地图比较少,此处只是举个例子,可以举一反三,比如在处理滚动条时也可以用相同的思路。