有和没有requestAnimationFrame

时间:2018-08-19 02:58:13

标签: javascript drag requestanimationframe

我一直在使用以下简单代码在屏幕上拖动固定位置分区。它可以工作,但是响应速度不如拖动浏览器弹出窗口(例如“打开文件”窗口)时那样。

如您所见,除了修改包含元素的顶部和左侧位置的样式之外,mousemove事件处理程序内部几乎没有发生任何事情。如果从最边缘拖动元素,则鼠标将保持在元素前方约半英寸处,特别是在以缓慢到中等的速度移动时,这与浏览器弹出式窗口会紧贴鼠标指针保持一致。

我尝试将元素位置更新与mousemove事件分离,并在单独的函数中使用requestAnimationFrame来更新元素位置;响应能力也不会更好,甚至可能会更差。该代码还在函数名称中带有_rAF后缀。

这两个版本的代码中是否都存在问题,这是一种更好的方法,还是这是浏览器中拖动事件的最佳选择?

This问题有点相似,我阅读了它提供给HTML5 Rocks网站的链接;这就是为什么我尝试将位置更新与mousemove事件分开的原因。奇怪的是,两个问题的答案都将requestAnimationFrame语句放回到mousemove事件中,这似乎与所引用的html5岩石文章所推荐并称为反跳的内容完全相反。也就是说,除非我遗漏了这一点。

下面提供的代码足够好,但是我想知道它是否应该与浏览器自身的拖动事件一样灵敏。在从下面的luke-codewalker的注释中了解了片段之后,我添加了具有固定位置元素的片段-一个常规拖动,另一个带有requestAnimationFrame。我没有发现两者之间有任何区别,而且两者的响应速度都比拖动浏览器自己的窗口之一慢。

谢谢。

更新(六个月后)

我没有试图以任何方式批评这种反跳方法,并且想知道我是否不理解它,因为今天我在自定义滚动条中尝试了相同的方法。我首先设置好它,只有在滚动条上的mousemove事件上,才可以更改元素的滚动位置。效果很好,但有点怪癖,与浏览器滚动条一样。我认为这可能是反跳方法的更好应用,因为页面中包含很多元素。因此,我将鼠标移动与屏幕更新分开,并使用requestAnimationFrame根据鼠标位置更新滚动位置,直到用户放开鼠标按钮为止。它也运行得很好,很难区别。我以为第一种方法看起来要好一些,让其他人看时不告诉她原因或区别,于是她也选择了第一种。

也许,在使用此方法的这两个应用程序中,我期望很高。或者,我仍然不了解某些内容,可以使动作更流畅。

"use strict";

     document.querySelectorAll(".drag_handle")[0].addEventListener( 'mousedown', function(event) { drag_fixed( this.parentNode, event ); }, true );

document.querySelectorAll(".drag_handle_rAF")[0].addEventListener( 'mousedown', function(event) { drag_fixed_rAF( this.parentNode, event ); }, true );


     function drag_fixed( e, evt )
       {       
         evt.stopPropagation(); 
         evt.preventDefault();

         let dx = e.offsetLeft - evt.clientX,
             dy = e.offsetTop - evt.clientY;

         document.addEventListener( 'mousemove', move, true )
         document.addEventListener( 'mouseup', stop, true );
 
         function move(evt)
           { 
             evt.stopPropagation(); 
             e.style.left = ( evt.clientX + dx ) + 'px';
             e.style.top = ( evt.clientY + dy ) + 'px';
           } // close move

         function stop(evt)
           {
             evt.stopPropagation();
             document.removeEventListener( 'mousemove', move, true )
             document.removeEventListener( 'mouseup', stop, true );
             e = evt = dx = dy = null;
           } // close stop

       } // close drag_fixed


 
     function drag_fixed_rAF( e, evt )
       {       
         evt.stopPropagation(); 
         evt.preventDefault();

         let dx = e.offsetLeft - evt.clientX,
             dy = e.offsetTop - evt.clientY, 
             x = evt.clientX,
             y = evt.clientY,
             r;

         document.addEventListener( 'mousemove', move, true )
         document.addEventListener( 'mouseup', stop, true );

         requestAnimationFrame( update );
 
         function move(evt)
           { 
             evt.stopPropagation(); 
             x = evt.clientX,
             y = evt.clientY;
           } // close move

         function update()
           {
             e.style.left = ( x + dx ) + 'px';
             e.style.top = ( y + dy ) + 'px';
             r = requestAnimationFrame( update );
           } // close update

         function stop(evt)
           {
             evt.stopPropagation();
             cancelAnimationFrame( r );
             document.removeEventListener( 'mousemove', move, true )
             document.removeEventListener( 'mouseup', stop, true );
             e = evt = dx = dy = null;
           } // close stop

       } // close drag_fixed_rAF
* { box-sizing: border-box; } 

     html { background-color: rgba(73,110,147,0.75); }

     body { margin: 0; }

    .container {
      position: fixed; 
      top: 50px;
      left: 50px;
      width: 300px;
      height: 200px;
      overflow-y: hidden;
      background-color: white;
      border-radius: 5px;
      border: 1px solid black;  }

    .drag_handle, .drag_handle_rAF { 
      width: 100%;
      height: 100%;
      color: white;
      background-color: rgb(90,120,70);
      }

    .scrollWindow {
      overflow-y: auto;
      position: absolute; 
      top: 75px; 
      left: 10px;
      width: 280px;
      height: 115px;
      border-radius: 5px;
      border: 1px solid black; 
      background-color: rgba(255,255,225,1);
       }

    .flexContainer {
      position: absolute; 
      top: 35px; 
      left: 10px;
       }

    .data { 
      width: 100%;    
      padding: 30px 0 50px 0; }

    .close { position : absolute; top: 5px; right: 5px; }
<!DOCTYPE html> 

    <html lang="en">

    <head>

    <meta charset="utf-8"> 
  
    <title>Drag Test</title> 

    <style>


    </style>

    </head>

    <body>
      <div class="container">
        <div class="drag_handle">Drag Handle</div>
        <button class="close">X</button> 

        <div class="flexContainer">
           <button>Button 1</button>
           <button>Button 2</button>
           <button>Button 3</button>
        </div>

        <div class= "scrollWindow">
          <div class="data""></div>
        </div>
      </div>

      <div class="container" style="left: 400px;">
        <div class="drag_handle_rAF">Drag Handle rAF</div>
        <button class="close">X</button> 

        <div class="flexContainer">
           <button>Button 1</button>
           <button>Button 2</button>
           <button>Button 3</button>
        </div>

        <div class= "scrollWindow">
          <div class="data""></div>
        </div>


    </body

    </html>

0 个答案:

没有答案