jQuery 的可拖动网格

发布于 2024-09-05 12:45:58 字数 1399 浏览 16 评论 0原文

看起来 Draggable 的构造函数中的 'grid' 选项与原始坐标相对绑定被拖动元素的位置 - 简而言之,如果您有三个可拖动的 div,其 top 分别设置为相对于其父级的 100、200、254 像素:

<div class="parent-div" style="position: relative;">
    <div id="div1" class="draggable" style="top: 100px; position: absolute;"></div>
    <div id="div2" class="draggable" style="top: 200px; position: absolute;"></div>
    <div id="div3" class="draggable" style="top: 254px; position: absolute;"></div>
</div>

并且所有这些都可以进行拖动'grid' 设置为 [1, 100]:

draggables = $('.draggable');
$.each(draggables, function(index, elem) {
    $(elem).draggable({
                       containment: $('#parent-div'),
                       opacity: 0.7,
                       revert: 'invalid',
                       revertDuration: 300,
                       grid: [1, 100],
                       refreshPositions: true
    });
});

这里的问题是,一旦您向下拖动 div3,它的顶部就会增加 100,将其移动到 354px 而不是仅增加 46px (254 + 46 = 300),这将使它到达网格中的下一站 - 300px,如果我们正在查看parent-div 作为参考点和“网格持有者”。

我查看了可拖动源,这似乎是一个内置缺陷 - 它们只是相对于可拖动元素的原始位置进行所有计算。

我想避免对可拖动库的代码进行猴子修补,我在这里真正寻找的是如何使可拖动库计算相对于包含父级的网格位置的方法。然而,如果猴子补丁是不可避免的,我想我将不得不忍受它。

It looks like that the 'grid' option in the constructor of Draggable is relatively bound to the original coordinates of the element being dragged - so simply put, if you have three draggable divs with their top set respectively to 100, 200, 254 pixels relative to their parent:

<div class="parent-div" style="position: relative;">
    <div id="div1" class="draggable" style="top: 100px; position: absolute;"></div>
    <div id="div2" class="draggable" style="top: 200px; position: absolute;"></div>
    <div id="div3" class="draggable" style="top: 254px; position: absolute;"></div>
</div>

Adn all of them are getting enabled for dragging with 'grid' set to [1, 100]:

draggables = $('.draggable');
$.each(draggables, function(index, elem) {
    $(elem).draggable({
                       containment: $('#parent-div'),
                       opacity: 0.7,
                       revert: 'invalid',
                       revertDuration: 300,
                       grid: [1, 100],
                       refreshPositions: true
    });
});

Problem here is that as soon as you drag div3, say, down, it's top is increased by 100, moving it to 354px instead of being increased by just mere 46px (254 + 46 = 300), which would get it to the next stop in the grid - 300px, if we are looking at the parent-div as a point of reference and "grid holder".

I had a look at the draggable sources and it seem to be an in-built flaw - they just do all the calculations relative to the original position of the draggable element.

I would like to avoid monkey-patching the code of draggable library and what I am really looking for here is the way how to make the Draggable calculate the grid positions relative to containing parent. However if monkey-patching is unavoidable, I guess I'll have to live with it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泪眸﹌ 2024-09-12 12:45:58

由于@Pez的答案丢失了(404),所以我是这样做的:

$('#elem').draggable({
    ....,
    drag: function(e, ui) {
        ui.position.left = Math.floor(ui.position.left / 10) * 10;
        ui.position.top = Math.floor(ui.position.top / 10) * 10;
    }
});

演示: http://jsfiddle.net/ThiefMaster/yGsSE/< /a>

Since @Pez's answer is lost (404), here's how I did it:

$('#elem').draggable({
    ....,
    drag: function(e, ui) {
        ui.position.left = Math.floor(ui.position.left / 10) * 10;
        ui.position.top = Math.floor(ui.position.top / 10) * 10;
    }
});

Demo: http://jsfiddle.net/ThiefMaster/yGsSE/

蓝海 2024-09-12 12:45:58

我通过简单地添加我自己的脚本来解决这个问题:在draggable下添加我自己的脚本并将其设置为

divide math.Floor(x/100)*100 

与Y相同。

I got around this problem by simply adding my own script to drag: under draggable and setting it to

divide math.Floor(x/100)*100 

and the same for Y.

往事风中埋 2024-09-12 12:45:58

在过去的几天里我开始使用 JQuery Draggable 并找到了一个简单的解决方案。

将位置属性设置为绝对,然后添加小部件,并将顶部和左侧设置为与网格对齐的值。

由于顶部/左侧的值是绝对值,因此在将它们存储在数据库中时也更有意义。

I've started using JQuery draggable over the last couple of days and found an easy fix to this.

Set the position property to absolute and add your widgets with top and left set to values that line up to your grid.

As the values for top/left are absolute they also make more sense when going off and storing them in a db.

笑咖 2024-09-12 12:45:58

Jquery 桌面:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
<link rel="stylesheet/less" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/base/jquery-ui.css">

<div class="parent-div" style="position: relative;">
    <div id="div1" class="draggable" style="top: 100px; position: absolute;">1</div>
    <div id="div2" class="draggable" style="top: 200px; position: absolute;">2</div>
    <div id="div3" class="draggable" style="top: 254px; position: absolute;">3</div>
</div>

<script>
var Z_INDEX_APP = 0;
var Z_INDEX_WINDOW_COUNTER = 1;
var Z_INDEX_NOTE_COUNTER = 999;
var Z_INDEX_FOR_DRAGGED = 99999;
var Z_INDEX_FOR_NOTIF = 999999; 
var ICONS_GRID_CELL_SIZE = 75;
var ICONS_GRID_PADDING_LEFT = 20;
var ICONS_GRID_PADDING_TOP = 50; 
draggables = $('.draggable');
$.each(draggables, function(index, elem) {
    $(elem).draggable({
        containment: $('#parent-div'),
        start: function(event) {
        icon = $(this);
        icon.css('z-Index', Z_INDEX_FOR_DRAGGED);
        dragStartLeft = icon.css('left');
        dragStartTop = icon.css('top');
        icon.addClass('desktop-app-dragging');
        icon.removeClass('desktop-app-pressed');
    },
    stop: function(event) {         
        icon.css('z-Index', Z_INDEX_APP);
        var appId = icon.attr('id').split('_')[1];
        icon.removeClass('desktop-app-dragging');
        var alignedX = ICONS_GRID_PADDING_LEFT + Math.floor(parseInt(icon.css('left'))/ICONS_GRID_CELL_SIZE) * ICONS_GRID_CELL_SIZE;
        var alignedY = ICONS_GRID_PADDING_TOP + Math.floor(parseInt(icon.css('top'))/ICONS_GRID_CELL_SIZE)  * ICONS_GRID_CELL_SIZE;
        if ( alignedX < ICONS_GRID_PADDING_LEFT ) alignedX = ICONS_GRID_PADDING_LEFT;
        if ( alignedY < ICONS_GRID_PADDING_TOP ) alignedY = ICONS_GRID_PADDING_TOP;         
        var iconToSwitch = null;
        $(".desktop-app").each(function(index, app) {           
            if ( app.style.top == ( alignedY + 'px' ) && app.style.left == ( alignedX + 'px' ) ) {
                iconToSwitch = app;
            }
        });
        if ( iconToSwitch != null ) {
            var appToSwitchId = iconToSwitch.id.split('_')[1];
            var updateUrl = 'api/desktop?cmd=update&id=' + appToSwitchId + '&x=' + parseInt(dragStartLeft) + '&y=' + parseInt(dragStartTop);
            //$.getJSON(updateUrl);
            iconToSwitch.style.left = dragStartLeft;
            iconToSwitch.style.top = dragStartTop;
        }       
        icon.css('left', alignedX + 'px');
        icon.css('top', alignedY + 'px');
        var updateUrl = 'api/desktop?cmd=update&id=' + appId + '&x=' + alignedX + '&y=' + alignedY;
        //$.getJSON(updateUrl);
    }

    });
});
</script>

Jquery Desktop:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
<link rel="stylesheet/less" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/base/jquery-ui.css">

<div class="parent-div" style="position: relative;">
    <div id="div1" class="draggable" style="top: 100px; position: absolute;">1</div>
    <div id="div2" class="draggable" style="top: 200px; position: absolute;">2</div>
    <div id="div3" class="draggable" style="top: 254px; position: absolute;">3</div>
</div>

<script>
var Z_INDEX_APP = 0;
var Z_INDEX_WINDOW_COUNTER = 1;
var Z_INDEX_NOTE_COUNTER = 999;
var Z_INDEX_FOR_DRAGGED = 99999;
var Z_INDEX_FOR_NOTIF = 999999; 
var ICONS_GRID_CELL_SIZE = 75;
var ICONS_GRID_PADDING_LEFT = 20;
var ICONS_GRID_PADDING_TOP = 50; 
draggables = $('.draggable');
$.each(draggables, function(index, elem) {
    $(elem).draggable({
        containment: $('#parent-div'),
        start: function(event) {
        icon = $(this);
        icon.css('z-Index', Z_INDEX_FOR_DRAGGED);
        dragStartLeft = icon.css('left');
        dragStartTop = icon.css('top');
        icon.addClass('desktop-app-dragging');
        icon.removeClass('desktop-app-pressed');
    },
    stop: function(event) {         
        icon.css('z-Index', Z_INDEX_APP);
        var appId = icon.attr('id').split('_')[1];
        icon.removeClass('desktop-app-dragging');
        var alignedX = ICONS_GRID_PADDING_LEFT + Math.floor(parseInt(icon.css('left'))/ICONS_GRID_CELL_SIZE) * ICONS_GRID_CELL_SIZE;
        var alignedY = ICONS_GRID_PADDING_TOP + Math.floor(parseInt(icon.css('top'))/ICONS_GRID_CELL_SIZE)  * ICONS_GRID_CELL_SIZE;
        if ( alignedX < ICONS_GRID_PADDING_LEFT ) alignedX = ICONS_GRID_PADDING_LEFT;
        if ( alignedY < ICONS_GRID_PADDING_TOP ) alignedY = ICONS_GRID_PADDING_TOP;         
        var iconToSwitch = null;
        $(".desktop-app").each(function(index, app) {           
            if ( app.style.top == ( alignedY + 'px' ) && app.style.left == ( alignedX + 'px' ) ) {
                iconToSwitch = app;
            }
        });
        if ( iconToSwitch != null ) {
            var appToSwitchId = iconToSwitch.id.split('_')[1];
            var updateUrl = 'api/desktop?cmd=update&id=' + appToSwitchId + '&x=' + parseInt(dragStartLeft) + '&y=' + parseInt(dragStartTop);
            //$.getJSON(updateUrl);
            iconToSwitch.style.left = dragStartLeft;
            iconToSwitch.style.top = dragStartTop;
        }       
        icon.css('left', alignedX + 'px');
        icon.css('top', alignedY + 'px');
        var updateUrl = 'api/desktop?cmd=update&id=' + appId + '&x=' + alignedX + '&y=' + alignedY;
        //$.getJSON(updateUrl);
    }

    });
});
</script>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文