一、需求描述
页面中有一个聊天窗口,包括标题栏和内容区。如下所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200731164502188.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MDI0ODg3,size_16,color_FFFFFF,t_70)
实现一个功能:
1、点击并拖动该聊天窗口的标题栏,可以把该窗口移动到页面的任意位置。
2、鼠标点击标题栏的位置 距离 浏览器窗口边缘 的距离,上下不能小于50px,左右不能小于100px。
3、将聊天窗口应用于复杂页面时(含有iframe等),拖动流畅不卡顿。
二、代码实现
<template>
<div id="chat-mask">
<div :id="id1" class="chat-container">
<div class="chat-head" :id="id2"></div>
<div class="chat-body"></div>
</div>
</div>
</template>
<style>
html{
height: 100%;
}
body{
height: 100%;
width: 100%;
background-color: rgb(241, 209, 234);
overflow: hidden;
margin: 0;
padding: 0;
}
.chat-mask{
width:100%;
height: 100%;
background-color: transparent;
z-index: 99;
}
.chat-container{
height: 310px;
width: 360px;
z-index: 100;
position: absolute;
}
.chat-head{
height: 30px;
width: 100%;
background-color: #20A0FF;
}
.chat-body{
height: 280px;
width: 100%;
background-color: #fff;
}
</style>
<script>
import moveWindow from './moveWindow.js'
export default {
name: 'Chat',
data() {
return {
id1:'chatid1' ,
id2:'chatid2' ,
}
},
mounted () {
this.$nextTick(() => {
var mask = $("#chat-mask");
$("body").append(mask);
});
this.moveWindow(this.id1,this.id2);
}
</script>
moveWindow.js
import {addClass,removeClass} from 'wind-dom'
export default function moveWindow(dom1,dom2){
var father = document.getElementById(dom1);
var son = document.getElementById(dom2);
var mask = document.getElementById("chat-mask");
var flag = false;
son.onmousedown = function(event){
var event = event || window.event;
var x = event.clientX - popupfather.offsetLeft;
var y = event.clientY - popupfather.offsetTop;
flag = true;
if(mask){
addClass(mask,'chat-mask');
}
document.onmousemove = function(event){
var event = event || window.event;
var maxWidth = document.body.clientWidth;
var maxHight = document.body.clientHeight;
if(flag && event.clientX > 100 && event.clientX < maxWidth - 100 &&
event.clientY > 50 && event.clientY < maxHight - 50){
father.style.left = event.clientX - x + "px";
father.style.top = event.clientY- y + "px";
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
}
document.onmouseup = function(){
flag = false;
if(mask){
removeClass(mask,'chat-mask');
}
document.onmousemove = null;
}
};
三、代码解析
整个拖动的过程很简单,都是常规操作,不再赘述。
1、遮罩层.
当鼠标点击标题栏(拖动)时,给遮罩层添加样式chat-mask,当鼠标松开时,遮罩层去掉样式chat-mask。这么写是为了解决当页面中含有iframe时,拖动卡顿的问题。
<div id="chat-mask"></div>
.chat-mask{
width:100%;
height: 100%;
background-color: transparent;
z-index: 99;
}
2、有时候一个复杂页面是有很多页面组成的。把遮罩层和内部要拖动的部分放到body的里面,保证聊天框能在整个页面中拖动,不受布局的影响。
var mask = $("#chat-mask");
$("body").append(mask);
3、注意html和body的样式,还有拖动元素是绝对定位。
如果没给HTML和body设置高度,元素就拖不动。如果overflow没有设置为hidden,当你拖动窗口超出浏览器边缘,就会出现滚动条。
html{
height: 100%;
}
body{
height: 100%;
width: 100%;
background-color: rgb(241, 209, 234);
overflow: hidden;
margin: 0;
padding: 0;
}
.chat-container{
height: 310px;
width: 360px;
z-index: 100;
position: absolute;
}
4、小拓展
但凡是拖动元素,或者拖动元素边框改变其大小时,遇到了iframe,如果iframe对你的拖动有影响,导致卡顿,那么可以考虑给iframe加一层遮罩层,就像这个例子一样。