JS实现页面中拖动元素,并解决页面中含有iframe时卡顿问题。

一、需求描述

页面中有一个聊天窗口,包括标题栏和内容区。如下所示。

在这里插入图片描述

实现一个功能:
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; //当前鼠标点击处相对于father所在位置x
    var y = event.clientY - popupfather.offsetTop; //当前鼠标点击处相对于father所在位置y
    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加一层遮罩层,就像这个例子一样。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个问题可能是由于鼠标事件和 iframe 渲染事件的冲突导致的。您可以尝试在拖拽iframe 隐藏或者将其 z-index 设置为 -1,以避免冲突。另外,您可以使用 CSS3 的 transform 属性来实现拖拽,这样可以减少因为重排和重绘导致的顿。具体做法如下: 1. 在拖拽开始,将 iframe 的 z-index 设置为 -1 或者将其隐藏起来: ``` iframe { z-index: -1; /* 或者 */ display: none; } ``` 2. 使用 CSS3 的 transform 属性来实现拖拽: ``` <div class="draggable" @mousedown="handleMouseDown"> <!-- your content here --> </div> <script> export default { data() { return { dragging: false, startX: 0, startY: 0, translateX: 0, translateY: 0, }; }, methods: { handleMouseDown(event) { this.dragging = true; this.startX = event.clientX; this.startY = event.clientY; }, handleMouseMove(event) { if (this.dragging) { this.translateX = event.clientX - this.startX; this.translateY = event.clientY - this.startY; this.$refs.draggable.style.transform = `translate(${this.translateX}px, ${this.translateY}px)`; } }, handleMouseUp(event) { this.dragging = false; }, }, mounted() { document.addEventListener('mousemove', this.handleMouseMove); document.addEventListener('mouseup', this.handleMouseUp); }, beforeDestroy() { document.removeEventListener('mousemove', this.handleMouseMove); document.removeEventListener('mouseup', this.handleMouseUp); }, }; </script> <style scoped> .draggable { position: absolute; top: 0; left: 0; cursor: move; } </style> ``` 注意,这里的 translate 属性是相对于元素自身的位置进行位移,而不是相对于父元素的位置进行位移。如果您需要相对于父元素进行位移,可以使用 position 和 top/left 属性来实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值