【问题标题】:javascript, moving a div, what is the smoothest implementation?javascript,移动一个div,最流畅的实现是什么?
【发布时间】:2017-01-20 01:24:02
【问题描述】:

我正在使用以下代码移动一个 div,但是在 jsfiddle 中它很流畅,在我的代码中它很跳跃,体验不是最好的。

我想知道我是否在这里跳过了一些东西,然后是关于是否有任何特定的编码方式的问题。比如只能用css做吗?

https://jsfiddle.net/59sxn1jy/2/

html

<div id="panel_log"></div>

css

#panel_log {
  position:absolute;
  width:100px;
  height:100px;
  border:1px solid #000;
  background-color:#fff;
  top:20px;
  left:20px;
  cursor:move;
}

javsascript

var spaceY;
var spaceX;

var move_start = function(e) {
  var panel_log = document.getElementById('panel_log');
  spaceY = parseInt(window.getComputedStyle(panel_log,null).getPropertyValue('top')) - parseInt(e.clientY);
  spaceX = parseInt(window.getComputedStyle(panel_log,null).getPropertyValue('left')) - parseInt(e.clientX);

  window.addEventListener('mousemove',moving,false);
  window.addEventListener('mouseup',finishing,false);
};

var moving = function(e) {
  var panel_log = document.getElementById('panel_log');
  panel_log.style.top = parseInt(e.clientY) + spaceY + 'px';
  panel_log.style.left = parseInt(e.clientX) + spaceX + 'px';
};

var finishing = function(e) {
  var panel_log = document.getElementById('panel_log');
  window.removeEventListener('mousemove', moving, false);
  window.removeEventListener('mouseup', finishing, false);
};
document.getElementById('panel_log').addEventListener('mousedown',move_start,false);

【问题讨论】:

    标签: javascript html drag-and-drop draggable


    【解决方案1】:

    尝试使用 css transform 属性而不是 lefttop https://jsfiddle.net/59sxn1jy/5/

    这应该会更快,因为 transform: translate3d() 使用 gpu,更多关于 http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/ 的信息

    这种方法的问题是你不能轻易得到计算的变换值,所以你必须存储位置。

    这是代码

    var spaceX, spaceY;
    
    var left = 20;
    var top = 20;
    
    var setPosition = function(elem, x, y) {
      elem.style.transform = 'translate3d(' + parseInt(x) + 'px, ' + parseInt(y) + 'px, ' + '0)';
      left = x;
      top = y;
    }
    
    setPosition(document.getElementById('panel_log'), left, top)
    
    var move_start = function(e) {
      var panel_log = document.getElementById('panel_log');
          
      spaceX = parseInt(left) - parseInt(e.clientX);
      spaceY = parseInt(top) - parseInt(e.clientY);
    
      window.addEventListener('mousemove', moving, false);
      window.addEventListener('mouseup', finishing, false);
    }
    
    var moving = function(e) {
      var panel_log = document.getElementById('panel_log');
      setPosition(panel_log, parseInt(e.clientX) + spaceX, parseInt(e.clientY) + spaceY)
    };
    
    var finishing = function(e) {
      var panel_log = document.getElementById('panel_log');
      window.removeEventListener('mousemove', moving, false);
      window.removeEventListener('mouseup', finishing, false);
    };
    
        document.getElementById('panel_log').addEventListener('mousedown', move_start, false);
    #panel_log {
      position: absolute;
      width: 100px;
      height: 100px;
      border: 1px solid #000;
      background-color: #fff;
      cursor: move;
    }
    &lt;div id="panel_log"&gt;&lt;/div&gt;

    【讨论】:

    • 我已经在jsfiddle.net/59sxn1jy/6 中更新了你的代码(在理解它之后,非常感谢)并适应了我的代码,我认为它会更好一点,但事实是体验仍然不错(但也许这是我能得到的最好的)
    • 你还能做的就是尝试调整 div 的转换属性,例如,将其设置为 transition: transform 0.1s linear; 并调整持续时间以在 div 移动速度和更流畅的体验之间找到平衡
    【解决方案2】:

    试试 jQuery UI:https://jqueryui.com/draggable/

    更流畅并具有跨平台支持。请尝试以下操作:

    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
    <script>
      $(document).ready(function() {
        $("#panel_log").draggable();
      });
    </script>
    

    【讨论】:

    • 但我正在寻找一个无 jQuery 的解决方案
    【解决方案3】:

    function drag_start(event) {
        var style = window.getComputedStyle(event.target);
        event.dataTransfer.setData("text/plain",
        (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
    } 
    function drag_over(event) { 
        event.preventDefault(); 
        return false; 
    } 
    function drop(event) { 
        var offset = event.dataTransfer.getData("text/plain").split(',');
        var dm = document.getElementById('dragme');
        dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
        dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
        event.preventDefault();
        return false;
    } 
    var dm = document.getElementById('dragme'); 
    dm.addEventListener('dragstart',drag_start,false); 
    document.body.addEventListener('dragover',drag_over,false); 
    document.body.addEventListener('drop',drop,false); 
    #dragme {
      width: 100px;
      height: 100px;
      border: 1px solid #000;
      background-color:#fff;
      cursor: move;
      left: 0;
      top: 0;
      position: absolute;
    }
    
    body {
      width: 100vw;
      height: 100vh;
    }
    &lt;div id="dragme" draggable="true"&gt;&lt;/div&gt;

    取自this answer。不幸的是,我不相信没有 JavaScript 就可以做到这一点。

    【讨论】:

    • 您的代码 sn-p 似乎不起作用。感谢您的链接,老实说,但是我看到代码更加模糊,除非有人告诉我该实现中的性能得到了改进,否则我将继续使用上述解决方案
    猜你喜欢
    • 1970-01-01
    • 2012-02-04
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多