UI组件之浮出层的拖拽

上次总结了一下简单的浮出层的设计,不了解的可以猛戳下面这条链接:

UI组件之浮出层

这次的这篇总结主要是参考的这篇文章:js拖拽事件实例,不过自己多做了一点分析

这次来总结一下浮出层的拖拽,期间遇到了一些小问题,不过最后也解决了,这里也总结一下。

首先,我们要实现的效果是浮出层在鼠标点击之后随着鼠标移动,松开之后停止移动,并且边框不得超出边界。

网上很多教程已经说得很清楚了,这里就再啰嗦两句,这个过程总共分为三步:

  1. 鼠标点下之时用onmousedown事件记录鼠标点下时与浮出层的相对位置
  2. 用onmousemove事件让浮出层跟随鼠标移动,每当用户将鼠标移动一个像素,就会发生一个 mousemove 事件,我们在这个事件中改变浮出层的位置即可
  3. 用onmouseup事件在鼠标松开时清除onmousemove中的事件

还需要一些额外的知识,是关于offsetWidth,offsetLeft等等,在网上找到一篇文章不错(图画的比较清楚),链接如下:

关于offsetWidth、offsetLeft等概念的理解

接下来是代码实现:

1、计算鼠标与浮出层的相对位置

 horizen.onmousedown=function(ev) //鼠标按下浮出层
  {
    var oEvent=ev||event;//这里是为了浏览器兼容,大家可以上网去查一下
disX=oEvent.clientX-horizen.offsetLeft; /*鼠标的X坐标减去浮出层的左边距就等于disX, 这个disX是用于确定鼠标移动浮出层时鼠标点和浮出层之间的左面距离,    这个距离是不会变的,通过这个新鼠标的X坐标减去disX就是浮出层的Left*/
    disY=oEvent.clientY-horizen.offsetTop;    ……       ……}
  • 其中的clientX是鼠标相对于整个屏幕在X轴上的位置,clientY是鼠标相对于整个屏幕在Y轴上的位置

2、根据鼠标的移动计算出浮出层的offsetLeft应有的距离,从而改变浮出层的位置,并根据此距离判断浮出层是否超出边界

 horizen.onmousedown=function(ev)
  {
    var oEvent=ev||event;
    disX=oEvent.clientX-horizen.offsetLeft;
    disY=oEvent.clientY-horizen.offsetTop;
    document.onmousemove=function(ev)
    {
      var oEvent=ev||event;  //此处是为了浏览器兼容,大家可以上网去查一下
      var oLeft=oEvent.clientX-disX; //新鼠标X坐标减去disX,也就是鼠标移动浮出层后的Left
      var oTop=oEvent.clientY-disY;
      if(oLeft<0) //浮出层的Left小于0,也就是移出了左边
      {
        oLeft=0; //就把浮出层的Left设置为0,就不能移出左边
      }
      else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth) //屏幕宽度减去浮出层的宽度就得出了浮出层到达最右边的宽度
      {
        oLeft=document.documentElement.clientWidth-horizen.offsetWidth; //如果Left大于这个像素,就把Left设置为这个像素
      }
      if(oTop<0)
      {
        oTop=0;
      }
      else if(oTop>document.documentElement.clientHeight-horizen.offsetHeight)
      {
        oTop=document.documentElement.clientHeight-horizen.offsetHeight;
      }
      console.log(oLeft);
      horizen.style.left=oLeft+‘px‘; //浮出层的Left设置为新鼠标X坐标减去disX的值
      horizen.style.top=oTop+‘px‘;
    };
    return false; //阻止FireFox的默认事件 bug,(额……不太理解,有大神知道希望赐教)
  }
  • 以上注释只写了左右的,上下的是一样的

3.鼠标松开时清除onmousemove中的事件

document.onmouseup=function() //鼠标松开时
{
     document.onmousemove=null; //把鼠标移动清除
};

这样我们的浮出层的拖拽就做好了……

一切看似如此完美,可是当我打开浏览器调试的时候却发现,浮出层左边拖拽时会超出边界,右边会到达不了边界,上下也是这样

浏览器也并没有报错,检查了代码也没有错误,最后打了个断点调试了一下,发现在计算鼠标相对位置时,disX(只讨论x轴上的的值比较小,究其原因是因为offsetLeft过大,上网查了一下以后发现,原来是translate的原因,元素利用translate移动后不会影响offsetLeft的值,意思就是它是按我向左移动前的那个浮出层计算offsetLeft的,那么offset的值自然就会变大了,并且其变大的值就是我向左移动的值(浮出层的width是400px;我想左移动了自身的50%也就是200px),所以我们需要对判定的条件进行一些修改:

 if(oLeft<200) //移动前浮出层的Left小于200,也就是移出左边
      {
        oLeft=0; //就把浮出层的Left设置为200,就不能移出左边
      }
 else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth+200) //屏幕宽度减去DIV的宽度就得出了浮出层到达最右边的宽度,
      {
        oLeft=document.documentElement.clientWidth-horizen.offsetWidth+200; //如果Left大于这个值就把Left设置为这个值
      }

上下也根据浮出层的高度改一下就可以了

这样我们的浮出层拖拽的效果就真的做好了~

 
时间: 2024-08-23 19:11:02

UI组件之浮出层的拖拽的相关文章

关于弹出层的拖拽,封装

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin: 0; padding: 0; } html{ height: 100%; } body{ width: 100%; height: 100%; position: relative

CSS常用浮出层的写法

<!doctype html><html><head><meta charset="utf-8"><title>CSS常用浮出层的写法</title><style type="text/css">/* poptip */.poptip{position: absolute;top: 20px;left:20px;padding: 6px 10px 5px;*padding: 7px

浮出层的css写法,完美兼容IE6~10

利用元素间的绝对定位差一像素,使用不同颜色做出浮出层小三角的效果,完美兼容各浏览器! html部分: <div class="poptip"> <span class="poptip-arrow poptip-arrow-top"><em>◆</em><i>◆</i></span> <span class="poptip-arrow poptip-arrow-righ

高仿富途牛牛-组件化(一)-支持页签拖拽、增删、小工具

目录 一.概述 二.效果展示 三.实现方案分析 1.第一阶段 2.第二阶段 3.第三阶段 一.概述 好久没有做业务相关的UI功能了,比较炫酷的交互效果也写的少了,最近花了2天时间写了一个简易的高仿富途牛牛组件化的功能,当然了这只是一个初步的效果,而且没有做贴图.美化等工作,但是基本的功能已经有了.本篇文章只是作为组件化的一个开始,后续还会陆续引入更多关于组件化的介绍,相信功能也会越来越丰富.除此之外,富途牛牛的一些其他高级功能也会陆续引入,不乏有k线.分时.五日.指标.自选这样的复杂功能. 自选

JS组件系列——Bootstrap Table 表格行拖拽

原文:JS组件系列--Bootstrap Table 表格行拖拽 前言:之前一直在研究DDD相关知识,好久没更新JS系列文章了.这两天做了一个简单的业务需求,觉得效果还可以,今天在这里分享给大家,欢迎拍砖~~ 一.业务需求及实现效果 项目涉及到订单模块,那天突然接到一个需求,说是两种不同状态的订单之间要实现插单的效果,页面上呈现方式是:左右两个Table,左边Table里面是状态为1的订单,右边Table里面是状态为2订单,左边Table里面的行数据拖动到右边Table里面指定行的位置,拖动完成

EasyUI, Dialog 在框架页(ifrmae)的Top页面弹出时,拖拽Dialog边缘(以改变窗口大小),UI界面被卡死的解决办法

将Dialog的modal属性设置为true,可以解决卡死的问题(但会给用户使用体验带来影响) 1 var par = { 2 title: This.title, 3 width: This.width, 4 height: This.height, 5 cache: This.cache, 6 modal: This.modal, 7 resizable: This.resizable, 8 maximizable: This.maximizable, 9 onResize: This.on

原生JS实现弹出窗口的拖拽(直接copy可用)

上一篇说了一下弹出窗口功能的实现思路,一般情况下紧接着就会需要做到弹窗的移动,当然现在有很插件.库比如hammer可以使用,效率也非常好.但我觉得还是有必要了解一下原生JS的实现思路及方式,如下: 思路:拖动这个操作起始分为三个部分: 鼠标左键按下,此时才开始可以拖动: 鼠标移动,拖动开始:根据光标的移动给div相对应的纵轴.横轴的偏移: 鼠标左键松手,拖动结束,不可以再拖动了. 每一步需要做的事: 1中需要将初始化的拖动标示量置为true(可以拖动了).记录光标起始坐标和div的起始坐标 2中

Jquery学习之路(三) 实现弹出层插件

弹出层的应用还是比较多的,登陆,一些同页面的操作,别人的总归是别人的,自己的才是自己的,所以一直以来想写个弹出层插件.不多废话,直接开始吧! 不想看可以在这里直接下载源码xsPop.zip 1:遮罩层 要弹出层,先要用一个遮罩层挡在下面的页面,此遮罩层是全屏的,页面滚动也要有,所以设置 position: fixed;还要有透明效果,下面是我定义的遮罩层css,取名mask .mask { position: fixed; width: 100%; height: 100%; backgroun

弹出框组件,可拖拽

/** * 弹出框组件 */ (function($) { var Utils = { showMask: function() { var $mask = $("#mask"); if( $mask.length === 0 ) { $('body').prepend("<div id='mask' class='mask'></div>"); } $("#mask").css({ width: Math.max(doc