jQuery Draggable,将位置转换为百分比

Posted

技术标签:

【中文标题】jQuery Draggable,将位置转换为百分比【英文标题】:jQuery Draggable, convert position to percentage 【发布时间】:2016-10-20 23:56:30 【问题描述】:

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

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

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

Object  top=178, left=950

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

【问题讨论】:

请检查我的答案并试一试,看看它是否适合您的需求。 您的问题和预期结果描述性不够,请尽可能包含您的 html 资源。 【参考方案1】:

如果你使用的是 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);
    
);

【讨论】:

谢谢我尝试了游览解决方案,但收到错误“TypeError: $(...).position(...).left is not a function” @Alko 我在上面做了更新,尝试在 left 和 top 之后不加括号。那是错误的。 您可能需要查看outerWidth()outerHeight() 以获得更精确的计算。 @Luka 我有一个类似的question。我想知道您是否可以给我一些指示。 效果很好。谢谢。【参考方案2】:

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

尝试在全页模式下运行下面的 sn-p,

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 将在调整窗口大小时禁用对齐网格。

注意:将顶部和左侧值转换为百分比不会对齐 调整大小时的任何网格。此外,启用snapWhileResizing 将导致 调整窗口大小时,项目位置略有变化 次。

【讨论】:

以上是关于jQuery Draggable,将位置转换为百分比的主要内容,如果未能解决你的问题,请参考以下文章

Jquery UI Draggable:将帮助器对齐鼠标位置

包含到父级的JQuery Draggable和额外的一个

jQuery UI:将 Selectable 与 Draggable 结合起来

jQuery UI 拖动(Draggable) - 还原位置

javascript jQuery UI Draggable转换比例修复

jquery-ui-处理拖动位置Droppable,Draggable