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 相关文章推荐
showModalDialog 和 showModelessDialog
Jan 22 Javascript
JS 图片缩放效果代码
Jun 09 Javascript
jQuery表单域选择器用法分析
Feb 10 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
Oct 27 Javascript
详解angular element()方法使用
Apr 08 Javascript
基于ES6作用域和解构赋值详解
Nov 03 Javascript
node.js文件上传重命名以及移动位置的示例代码
Jan 19 Javascript
js实现导航跟随效果
Nov 17 Javascript
微信小程序之几种常见的弹框提示信息实现详解
Jul 11 Javascript
vue 如何使用递归组件
Oct 23 Javascript
Python机器学习之决策树和随机森林
Jul 15 Javascript
利用uni-app生成微信小程序的踩坑记录
Apr 05 Javascript
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常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
2014/09/12 PHP
PHP封装的MSSql操作类完整实例
2016/05/26 PHP
[原创]PHPCMS遭遇会员投稿审核无效的解决方法
2017/01/11 PHP
PHP实现的mysql读写分离操作示例
2018/05/22 PHP
php生成HTML文件的类方法
2019/10/11 PHP
javascript 获取所有id中包含某关键字的控件的实现代码
2010/11/25 Javascript
javascript实现点击后变换按钮显示文字的方法
2015/05/13 Javascript
整理AngularJS中的一些常用指令
2015/06/16 Javascript
javascript加减乘除的简单实例
2016/07/12 Javascript
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
2016/07/26 NodeJs
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
Angular2数据绑定详解
2017/04/18 Javascript
利用forever和pm2部署node.js项目过程
2017/05/10 Javascript
利用babel将es6语法转es5的简单示例
2017/12/01 Javascript
React组件中的this的具体使用
2018/02/28 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
webpack是如何实现模块化加载的方法
2019/11/06 Javascript
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
python批量查询、汉字去重处理CSV文件
2018/05/31 Python
Numpy数据类型转换astype,dtype的方法
2018/06/09 Python
Python识别快递条形码及Tesseract-OCR使用详解
2019/07/15 Python
Python 二叉树的层序建立与三种遍历实现详解
2019/07/29 Python
深入浅析python的第三方库pandas
2020/02/13 Python
keras K.function获取某层的输出操作
2020/06/29 Python
python使用numpy中的size()函数实例用法详解
2021/01/29 Python
css3 条纹化和透明化表格Firefox下测试成功
2014/04/15 HTML / CSS
小区门卫岗位职责
2013/12/31 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
校园学雷锋活动月总结
2014/03/09 职场文书
预备党员的自我评价
2014/03/12 职场文书
毕业班联欢会主持词
2014/03/27 职场文书
小学清明节活动总结
2014/07/04 职场文书
事业单位财务人员岗位职责
2015/04/14 职场文书
MySQL root密码的重置方法
2021/04/21 MySQL
Mysql数据库索引面试题(程序员基础技能)
2021/05/31 MySQL
浅析python中特殊文件和特殊函数
2022/02/24 Python