jQuery 可拖动,将位置转换为百分比

jQuery Draggable, convert position to percentage

我不知道该怎么做。我正在使用 jQuery 可拖动,我需要捕获网格位置:

  $("#draggable .item").draggable({
      containment: "#dragablle",
      snap: '.gridlines',
      stop: function(event, ui) {
          console.log(ui)
      }
  });

从停止事件中查看对象接收器:

Object { top=178, left=950}

我需要将 top 和 left 值转换为百分比,以便我可以将 .item 元素作为内联样式应用。父“#draggable”宽度和高度将是动态的,所以这就是为什么我需要百分比而不是像素。因此,当调整屏幕大小时,父元素内的所有内容都将保持不变(位置)

如果您使用的是 jQueryUI Draggable

试试这个:

$("#draggable .item").draggable({
    containment: "#draggable",
    snap: '.gridlines',
    stop: function () {
        var l = ( 100 * parseFloat($(this).position().left / parseFloat($(this).parent().width())) ) + "%" ;
        var t = ( 100 * parseFloat($(this).position().top / parseFloat($(this).parent().height())) ) + "%" ;
        $(this).css("left", l);
        $(this).css("top", t);
    }
});

为了捕获网格位置,您可以使用选项 grid: [x,y]。 如果你想对齐网格功能,你不必将 top 和 left 值转换为百分比,这样做你必须根据 $(window).resize() 事件的动态宽度和高度来计算位置。

在整页模式下尝试运行下面的代码段,

var grid_x = 10; 
var grid_y = 10;
var snapThreshold = 5;
var snapWhileResizing = true;
var old_w, old_h;
$(function() {
    old_w = $("#draggable").width();
    old_h = $("#draggable").height();
    $("#label-old-dimen").html(old_w + ' x ' + old_h); 
    $("#draggable .item").draggable({
        containment: "parent",
        grid: [grid_x, grid_y],
        stop: function (){
            var l = $(this).position().left;
            var t = $(this).position().top;
            var mod_l = l % grid_x;
            var mod_t = t % grid_y;   
            l = (mod_l > snapThreshold) ? (l + (grid_x - mod_l)) : l - mod_l;
            t = (mod_t > snapThreshold) ? (t + (grid_y - mod_t)) : t - mod_t;    
            $(this).html(l + ' x ' + t);
            $(this).data("left", l);
            $(this).data("top", t);
            $(this).css("left", l);
            $(this).css("top", t);   
        }
    });

    $("#snapWhileResizing").change(function(){
        snapWhileResizing = $(this).is(':checked');
    });
});

$(window).resize(function() {
    var new_w = window.innerWidth;
    var new_h = window.innerHeight;
    $("#label-new-dimen").html(new_w + ' x ' + new_h);
    var mod_w = new_w % grid_x;
    var mod_h = new_h % grid_y;
    new_w = ((mod_w > snapThreshold) ? (new_w + (grid_x - mod_w)) : new_w - mod_w) - 40;
    new_h = ((mod_h > snapThreshold) ? (new_h + (grid_y - mod_h)) : new_h - mod_h) - 50;
    
    if(old_w != new_w)
        old_w = $("#draggable").width();
    if(old_h != new_h)
        old_h = $("#draggable").height();
    
    $("#draggable").width(new_w);
    $("#draggable").height(new_h);

    $("#label-old-dimen").html(new_w + ' x ' + new_h);    
    $("#draggable .item").each(function(){
        var old_l, l, new_l, mod_l;
        var old_t, t, new_t, mod_t;            
        old_l = l = $(this).data("left");
        old_t = t = $(this).data("top");
        new_l = $(this).position().left;
        new_t = $(this).position().top;
        
        l = (new_w / old_w) * old_l;
        t = (new_h / old_h) * old_t;            
        mod_l = l % grid_x;  
        mod_t = t % grid_y;            
        new_l = (mod_l > snapThreshold) ? (l + (grid_x - mod_l)) : l - mod_l; 
        new_t = (mod_t > snapThreshold) ? (t + (grid_y - mod_t)) : t - mod_t;            
        if(old_w != new_w){        
            $(this).data("left", l);            
            $(this).css("left", snapWhileResizing ? new_l : l);                
        }
        if(old_h != new_h && $("#draggable").height() > 200){    
                    $(this).data("top", t);
            $(this).css("top", snapWhileResizing ? new_t : t);
        }            

        $(this).html(parseInt(l) + ' x ' + parseInt(t) + '<br />' + parseInt(new_l) + ' x ' + parseInt(new_t));    
    });    
});
#draggable .item { 
    width: 100px; 
    height: 100px; 
    padding: 0.5em; 
    border: 1px solid #555;
    background-color:#efefef;
    position: absolute;
    top: 0;
    cursor: move;
}
#draggable {
    position: relative;
    min-width: 200px;
    height: 100%;
    min-height: 200px;
    overflow: hidden;
    background-image: url(https://dl.dropboxusercontent.com/u/1094060/bg-dots.png);
    background-repeat: repeat;
    background-position: left top;
}
#label-old-dimen, #label-new-dimen {
    background-color: white;
    border: 1px solid gray;
}
.no-select {
    -webkit-user-select: none;  
    -moz-user-select: none;    
    -ms-user-select: none;      
    user-select: none;
} 
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<span id="label-new-dimen"></span>
<span id="label-old-dimen"></span>
<input type="checkbox" id="snapWhileResizing" name="snapWhileResizing" checked />
<label for="snapWhileResizing" class="no-select">snapWhileResizing</label>
<div id="draggable" class="ui-widget-content">
    <div class="item">Drag me around</div>
    <div class="item">Drag me around</div>
</div>

设置 snapWhileResizing = false 将在调整 window 大小时禁用对齐网格。

Note: converting top and left values into percentage will not snap to any grid when resizing. Also, enabling snapWhileResizing will cause slight shifting in items positions when resizing the windows many times.