改善JavaScript拖曳效果 [英] Improving JavaScript Dragging Effect

查看:88
本文介绍了改善JavaScript拖曳效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设法实现了一个简单的JavaScript拖动效果,以在网页内创建面板窗口,在其中可以从任何角或任何位置拖动对象。我只使用了 onmousedown (表示可能拖动), onmousemove (执行拖动)和 onmouseup (停止拖动)事件。

I have managed to implement a simple JavaScript dragging effect to create "panel windows" inside a webpage, in which I can drag the object from any corner or position. I have only used the onmousedown (to indicate a possible dragging), onmousemove (to perform dragging) and onmouseup (to stop dragging) events.

它工作得很好,除了当我将对象拖动到边缘附近并移动鼠标时即使以正常速度当我将鼠标移到对象外部的区域时,拖动将失败,直到再次移动到该对象的区域,并且我必须单击该对象才能停止拖动它。

It works well except when I drag the object too near an edge and move the mouse even at a normal speed. When I move the mouse towards an area outside the object, the dragging fails until I move again to the object's area, and I have to click the object to stop dragging it.

这就像鼠标太快了一样,但显然它在本机应用程序窗口中不会发生,因为它们实现得更好。

It's like the mouse is too fast, but obviously it doesn't happen in native application windows because they are better implemented.

我可以在当前代码中添加哪些检查所以它不会失败那么多?当前似乎通过某种方式处理 onmouseout 事件来支持此问题,但是当发生这种情况时,窗口会摇晃以将鼠标指针返回到对象区域,并且看起来不太好。

What checks could I add to my current code so it doesn't fail as much? It currently seems to support a little bit of this problem by somehow handling the onmouseout event, but when it happens the window shakes to return the mouse pointer to the object area, and it doesn't look so good.

JavaScript简单拖动效果

    <!doctype html>
    <html>
     <head>
      <title>JavaScript Simple Dragging Effect</title>

      <style type="text/css">
       .moveableRect {
        position:absolute;
        width:320px;
        height:200px;
        background-color:rgba(254, 220, 186, 0.8);
       }
      </style>
     </head>

     <body bgcolor="#abcdef">
      <span id="span0000" class="moveableRect"><b>Drag Me<hr /></b></span>

      <textarea id="txt" cols="40" rows="12"></textarea>
     <script>
      //Custom variable to indicate that we
      //must drag the SPAN:
      ///
       document.getElementById("span0000").myDragFlag = false;


      //When we click and hold the mouse down,
      //we must activate the dragging process:
      ///
       document.getElementById("span0000").onmousedown = function(e)
       {
        if(e.button==0)
        {
         //This is the part of the trick that allows us
         //to drag the object from any starting position
         //that we click on it:
         ///
          this.startX=(e.pageX-this.offsetLeft);
          this.startY=(e.pageY-this.offsetTop);

         //This flag indicates that we must drag
         //when moving the mouse while the button is pressed:
         ///
          this.myDragFlag=true;
        }
       };


      //When we move the mouse, we must follow
      //the mouse cursor around:
      ///
       document.getElementById("span0000").onmousemove = function(e)
       {
        var bcr=this.getBoundingClientRect();

        if(this.myDragFlag)
        {
         //When we start dragging (moving the mouse
         //while the mouse button is pressed)
         //we will perform the effect of dragging from any
         //initial position in the rectangle:
         ///
          this.style.left = (e.pageX-this.startX)+"px";
          this.style.top  = (e.pageY-this.startY)+"px";


          document.getElementById("txt").value=
          "getBoundingClientRect.left="+bcr.left+"\n"+
          "getBoundingClientRect.top="+bcr.top+"\n"+
          "getBoundingClientRect.width="+bcr.width+"\n"+
          "getBoundingClientRect.height="+bcr.height+"\n"+
          "getBoundingClientRect.bottom="+bcr.bottom+"\n"+
          "getBoundingClientRect.right="+bcr.right+"\n"+
          "e.pageX="+e.pageX+"\n"+
          "e.pageY="+e.pageY+"\n"+
          "this.offsetLeft="+this.offsetLeft+"\n"+
          "this.offsetTop="+this.offsetTop+"\n"+
          "relatX="+(e.pageX-this.offsetLeft)+"\n"+
          "relatY="+(e.pageY-this.offsetTop);

        }
       };


      //When we release the mouse button,
      //we must finish the dragging process:
      ///
       document.getElementById("span0000").onmouseup = function(e)
       {
        if(e.button==0)
         this.myDragFlag=false;
       };


       document.getElementById("span0000").onmouseout = function(e)
       {
        if(this.myDragFlag==true)
        {
         //In this code, we basically check that
         //when the mouse slips out from the object
         //area while we are still dragging, we will
         //force moving the object back under the mouse
         //pointer. Here we will check from a logical
         //edge of 48 pixels, and we will move the object
         //back to 90% within those pixels, vertically and/or
         //horizontally. It makes look the object shaky
         //but at least it is minimally functional:
         ///
          var minEdge=48;
          var edgeCorrect=0.90;
          var minEdgeCorrect=(minEdge*edgeCorrect)|0;
          var bcr=this.getBoundingClientRect();
          var bcrw=bcr.width;
          var bcrh=bcr.height;
          if(this.startX<minEdge)
          {
           this.style.left = (e.pageX-minEdgeCorrect)+"px";
          }
          else if(this.startX>bcrw-minEdge)
          {
           this.style.left = (e.pageX-this.startX+minEdgeCorrect)+"px";
          }

          if(this.startY<minEdge)
          {
           this.style.top = (e.pageY-minEdgeCorrect)+"px";
          }
          else if(this.startY>bcrh-minEdge)
          {
           this.style.top = (e.pageY-this.startY+minEdgeCorrect)+"px";
          }
        }
       };

     </script>
     </body>
    </html>


推荐答案

您的 onmousemove事件监听器放在可拖动的div上。因此,如果鼠标离开它,事件将停止触发。而且它在拖动时会熄灭,因为它会按间隔而不是每个像素触发mousemove事件。

Your event listener for onmousemove is placed on the draggable div. So if the mouse goes off of it, the event stops firing. And it goes off while dragging because it fires mousemove events at intervals instead of every pixel.

要修复此问题,请将mousemove侦听器放在容器上。

To fix it, put the mousemove listener on the container.

document.body.onmousemove

您可能需要更改获取坐标的方式。

And you will probably need to change how you get the coordinates.

我想也可以使用其他方法。但这是最简单的。

There are other ways too I imagine. But that's the easiest.

编辑

当我尝试时开始怀疑自己来摆弄它,但最终使其起作用:
http://jsfiddle.net/tg33u8mv/3/

Started to doubt myself when I tried to fiddle this but eventually got it working: http://jsfiddle.net/tg33u8mv/3/

document.body.onmousemove = function (e) {
    if (myDragFlag) {
        var draggable = document.getElementById("span0000");
        var bcr = draggable.getBoundingClientRect();
        draggable.style.left = (e.pageX - draggable.startX) + "px";
        draggable.style.top = (e.pageY - draggable.startY) + "px";
    }
};

然后将 myDragFlag 更改为范围变量而不是 this.myDragFlag

And I changed myDragFlag to a scoped variable instead of this.myDragFlag.

奖金

在此版本中,拖动时添加一个类。 http://jsfiddle.net/tg33u8mv/4/

In this version I add a class when it is dragging. http://jsfiddle.net/tg33u8mv/4/

此类的CSS当前禁用突出显示,从而显着改善外观。您也可以使其变色或添加阴影以获得不错的效果。

The CSS for this class currently disables highlighting, significantly improving the look. You could also make it change color or add a shadow for a nice effect.

这篇关于改善JavaScript拖曳效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆