Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)


Posted in Javascript onJanuary 23, 2015

今天我们就来解决上一次拖拽雏形中的一些问题。下面看看有哪些问题?

附上上期的Javascript代码,方便大家查看问题。

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event; 
     disX = oEvent.clientX - oDiv.offsetLeft; 
     disY = oEvent.clientY - oDiv.offsetTop;

     oDiv.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px'; 
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     oDiv.onmouseup = function() {
      oDiv.onmousemove = null;
      oDiv.onmouseup = null;
     };

    };

   };
  </script>

1. 现在的这个拖拽如果我鼠标移动的快点,Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)你会发现这个鼠标从这个div出来了,这个时候div不会跟着鼠标走了。

那为什么会出现这个问题呢?

原因其实很简单,mousemove的事件我们是给div加的,所以鼠标一旦脱离了这个div,那么这个时候mousemove已经不触发了。

解决方案: 事件加载document 上,因为你鼠标无论如何都还在页面里面,怎么样都会触发mousemove 这样移动的在快也没问题。

那么我们相应的修改下代码。

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event; 
     disX = oEvent.clientX - oDiv.offsetLeft; 
     disY = oEvent.clientY - oDiv.offsetTop;
    // 事件加载document 上
     document.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px';
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     oDiv.onmouseup = function() {
      document.onmousemove = null;
      oDiv.onmouseup = null; 
     };

    };

   };
  </script>

那么这个问题就可以解决了。

2. 我们看看现在还有什么问题,虽然拖的快的问题解决了,但是当我把鼠标移动到这个位置

Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)

现在可以明显看到鼠标不在div上,如果这个时候抬起鼠标,你可以看到回来之后它还会动。Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理) 这就又是一个bug!

其实这个问题和上面的是一样的。所以呢解决起来也很简单我们把mouseup也加到document上,我们来试一下看看

document.onmouseup = function() { 
      document.onmousemove = null; 
      document.onmouseup = null; 
     };

这样 现在如果在移动到刚才的那个位置,就不会在出现之前的bug了,并且移动的快也没有任何的问题。一切都很正常。

3. 我们看看浏览器兼容的问题

其实在低版本的火狐浏览器中有这样一个问题
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)。怎么出现的呢,当你第一次拖的时候是对的,在拖一次的时候按住在移动,你会发现会有个这个影子在后面。这个是怎么回事呢?

实际上来说我们现在拖动的是一个空的div火狐是有bug的,那么如果在div中加点内容呢

Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)

你会发现现在又没有问题了。

所以火狐的bug就只有在空div中出现的。

解决方案:

其实很简单,我们就只要阻止浏览器默认事件就可以了 return false; 在onmousedown中。 为什么要加在onmousedown中呢?

大家可以想一下,拖拽是从哪个事件开始的,是从onmousedown开始的吧,当鼠标按下的时候拖拽就开始了。所以要加载onmousedown中。

实际上就是加了一句return false; 把火狐的bug屏蔽掉了。

这样不管怎么拖就没有问题了。

附上代码:

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event;
     disX = oEvent.clientX - oDiv.offsetLeft;
     disY = oEvent.clientY - oDiv.offsetTop;
     // 事件加载document 上
     document.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px';
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     document.onmouseup = function() {
      document.onmousemove = null;
      document.onmouseup = null;
     };

     return false;

    };

   };
  </script>

现在程序是完整了,但是在用户体验上还有一些问题。

比如说用户可能会把这个div拖出浏览器外面,那怎么解决呢?

那我们就在加个判断呗。 这个很简单吧,如果从左边出去了

Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)

,那就直接等于0,他就从左边出不去了。那么上边也是一样的。

那么怎么防止不能从右边出去?? 画个图就清楚了。 其实我们只要把页面的可视取的宽度减掉div的宽度就能算出来了。

那这个就是所谓的最大值,判断一下如果移动的距离超过了这个最大值就等于这个最大值即可。那么下边是一样的。

附上完整代码:

<script type="text/javascript">
       // 拖拽空div 低版本的火狐有bug
      window.onload = function() {
        var oDiv = document.getElementById("div1");var disX = 0;
        var disY = 0;
        oDiv.onmousedown = function(ev) {
          var oEvent = ev || event;
          disX = oEvent.clientX - oDiv.offsetLeft;
          disY = oEvent.clientY - oDiv.offsetTop;

          document.onmousemove = function(ev) {
            var oEvent = ev || event;
            // 存储div当前的位置
            var oDivLeft = oEvent.clientX - disX;
            var oDivTop = oEvent.clientY - disY;


            // 从左边拖出去了
            if (oDivLeft < 0) {
              oDivLeft = 0;
            } else if (oDivLeft > document.documentElement.clientWidth - oDiv.offsetWidth) {
              oDivLeft = document.documentElement.clientWidth - oDiv.offsetWidth;
            }

            if (oDivTop < 0) {
              oDivTop = 0;
            } else if (oDivTop > document.documentElement.clientHeight - oDiv.offsetHeight) {
              oDivTop = document.documentElement.clientHeight - oDiv.offsetHeight;
            }

            oDiv.style.left = oDivLeft + 'px';
            oDiv.style.top = oDivTop + 'px';
          };

          document.onmouseup = function() {
            document.onmousemove = null;
            document.onmouseup = null;
          };
          return false; // 阻止默认事件,解决火狐的bug
        };
      };
    </script>

那么现在这个拖拽就比较完整啦。O(∩_∩)O

Javascript 相关文章推荐
JavaScript中也使用$美元符号来代替document.getElementById
Jun 19 Javascript
jquery隐藏标签和显示标签的实例
Nov 11 Javascript
JS动态添加与删除select中的Option对象(示例代码)
Dec 25 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
Aug 30 Javascript
JS实现超炫网页烟花动画效果的方法
Mar 02 Javascript
JS获取时间的相关函数及时间戳与时间日期之间的转换
Feb 04 Javascript
原生JS中slice()方法和splice()区别
Mar 06 Javascript
解决webpack无法通过IP地址访问localhost的问题
Feb 22 Javascript
vue 子组件向父组件传值方法
Feb 26 Javascript
Vue 设置axios请求格式为form-data的操作步骤
Oct 29 Javascript
VUE DEMO之模拟登录个人中心页面之间数据传值实例
Oct 31 Javascript
如何在vue-cli中使用css-loader实现css module
Jan 07 Vue.js
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 #Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 #Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
Jan 23 #Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 #Javascript
jQuery选择器querySelector的使用指南
Jan 23 #Javascript
jQuery中DOM操作实例分析
Jan 23 #Javascript
jquery实现点击页面计算点击次数
Jan 23 #Javascript
You might like
PHP概述.
2006/10/09 PHP
PHP 开发环境配置(Zend Studio)
2010/04/28 PHP
paypal即时到账php实现代码
2010/11/28 PHP
php fputcsv命令 写csv文件遇到的小问题(多维数组连接符)
2011/05/24 PHP
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
2011/08/15 PHP
ThinkPHP实现生成和校验验证码功能
2017/04/28 PHP
jquery中this的使用说明
2010/09/06 Javascript
基于jQuery实现选取月份插件附源码下载
2015/12/28 Javascript
通过JS获取Request.QueryString()参数的值实现方法
2016/09/27 Javascript
JS实现页面跳转参数不丢失的方法
2016/11/28 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
详解VUE 定义全局变量的几种实现方式
2017/06/01 Javascript
基于Vue过渡状态实例讲解
2017/09/14 Javascript
vue中实现滚动加载更多的示例
2017/11/08 Javascript
vue引入ueditor及node后台配置详解
2018/01/03 Javascript
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
2018/01/25 jQuery
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
bootstrap动态调用select下拉框的实例代码
2018/08/09 Javascript
详解@angular/cli 改变默认启动端口两种方式
2018/11/29 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
NodeJs 实现简单WebSocket即时通讯的示例代码
2019/08/05 NodeJs
微信小程序 弹窗输入组件的实现解析
2019/08/12 Javascript
详解datagrid使用方法(重要)
2020/11/06 Javascript
Python深入学习之装饰器
2014/08/31 Python
Python 3.x 新特性及10大变化
2015/06/12 Python
Python排序搜索基本算法之堆排序实例详解
2017/12/08 Python
对python字典元素的添加与修改方法详解
2018/07/06 Python
浅谈python3.6的tkinter运行问题
2019/02/22 Python
解决Python二维数组赋值问题
2019/11/28 Python
英国豪华针织品牌John Smedley的在线销售商:The Outlet by John Smedley
2018/04/08 全球购物
美国基督教约会网站:ChristianCafe.com
2020/02/04 全球购物
电子商务专业毕业生工作推荐信
2013/11/17 职场文书
大学毕业寄语大全
2014/04/10 职场文书
幼儿园运动会口号
2014/06/07 职场文书
学校会议通知范文
2015/04/15 职场文书
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android