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

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

附上上期的Javascript代码,方便你们查看问题。java

<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. 如今的这个拖拽若是我鼠标移动的快点,image你会发现这个鼠标从这个div出来了,这个时候div不会跟着鼠标走了。浏览器

那为何会出现这个问题呢? spa

     缘由其实很简单,mousemove的事件咱们是给div加的,因此鼠标一旦脱离了这个div,那么这个时候mousemove已经不触发了。code

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

那么咱们相应的修改下代码。事件

<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>

那么这个问题就能够解决了。ip

2. 咱们看看如今还有什么问题,虽然拖的快的问题解决了,可是当我把鼠标移动到这个位置image,如今能够明显看到鼠标不在div上,若是这个时候抬起鼠标,你能够看到回来以后它还会动image。 这就又是一个bug!get

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

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

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

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

其实在低版本的火狐浏览器中有这样一个问题,image。怎么出现的呢,当你第一次拖的时候是对的,在拖一次的时候按住在移动,你会发现会有个这个影子在后面。这个是怎么回事呢?

实际上来讲咱们如今拖动的是一个空的div火狐是有bug的,那么若是在div中加点内容呢image你会发现如今又没有问题了。

因此火狐的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拖出浏览器外面,那怎么解决呢?

那咱们就在加个判断呗。 这个很简单吧,若是从左边出去了,那就直接等于0,他就从左边出不去了。那么上边也是同样的。

那么怎么防止不能从右边出去?? 画个图就清楚了。image 其实咱们只要把页面的可视取的宽度减掉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