jQuery 拖放 - 检查可放置范围之外的放置

发布于 2024-12-14 22:52:49 字数 756 浏览 1 评论 0原文

如果在另一个问题中回答了这个问题,我很抱歉,我找不到针对我的问题的答案!

我正在尝试测试 jQuery 可拖动对象是否被放置在合法可放置对象之外。通常 90% 的情况下可以通过恢复可拖动来解决这个问题,但我不想这样做。相反,如果将可拖动对象拖放到可拖放对象上(效果很好!),我想做一件事,如果将可拖放对象拖放到所有可能的可拖放对象之外,我想做另一件事(目前比我更好!)。

简而言之:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    stop: function()
    {
        // need some way to check to see if this draggable has been dropped
        // successfully or not on an appropriate droppable...
        // I wish I could comment out my headache here like this too...
    }
});

我觉得我错过了一些非常明显的东西......提前感谢您的任何帮助!

My apologies if this was answered in another question, I could not find an answer specific to my problem!

I'm trying to test whether a jQuery draggable is being dropped outside of a legal droppable. This would normally be solved 90% of the time by reverting the draggable, but I don't want to do that. Instead, I want to do one thing if the draggable is dropped onto a droppable (working great!), and something else if it is dropped outside of all possible droppables (currently getting the better of me!).

In a nutshell:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    stop: function()
    {
        // need some way to check to see if this draggable has been dropped
        // successfully or not on an appropriate droppable...
        // I wish I could comment out my headache here like this too...
    }
});

I feel like I'm missing something really obvious...thanks in advance for any help!

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

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

发布评论

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

评论(7

掩饰不了的爱 2024-12-21 22:52:49

因为 droppable 的 drop 事件在draggable 的 stop 事件之前触发,所以我认为您可以在 drop 事件中拖动的元素上设置一个标志,如下所示:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        ui.helper.data('dropped', true);
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    start: function(event, ui) {
        ui.helper.data('dropped', false);
    },
    stop: function(event, ui)
    {
        alert('stop: dropped=' + ui.helper.data('dropped'));
        // Check value of ui.helper.data('dropped') and handle accordingly...
    }
});

Because the droppable's drop event fires before the draggable's stop event, I think you can set a flag on the element being dragged in the drop event like so:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        ui.helper.data('dropped', true);
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    start: function(event, ui) {
        ui.helper.data('dropped', false);
    },
    stop: function(event, ui)
    {
        alert('stop: dropped=' + ui.helper.data('dropped'));
        // Check value of ui.helper.data('dropped') and handle accordingly...
    }
});
淡水深流 2024-12-21 22:52:49

我看到你已经得到答案了;无论如何,我今天遇到了同样的问题,我用这种方式解决了它:

var outside = 0;

// this one control if the draggable is outside the droppable area
$('#droppable').droppable({
    accept      : '.draggable',
    out         : function(){
        outside = 1;
    },
    over        : function(){
        outside = 0;
    }
});

// this one control if the draggable is dropped
$('body').droppable({
    accept      : '.draggable',
    drop        : function(event, ui){
        if(outside == 1){
            alert('Dropped outside!');
        }else{
            alert('Dropped inside!');
        }
    }
});

我需要它,因为我无法更改我的可拖动的选项,所以我只能使用可放置的(我需要它在很棒的 FullCalendar 插件)。
我想使用 droppables 的“贪婪”选项可能会出现一些问题,但在大多数情况下它应该可以工作。

PS:抱歉我的英语不好。

编辑:按照建议,我使用 jQuery.data 创建了版本;它可以在这里找到: jsfiddle.net/Polmonite/WZma9/

无论如何 jQuery.data 文档说:

请注意,此方法目前不提供在 XML 文档上设置数据的跨平台支持,因为 Internet Explorer 不允许通过 Expando 属性附加数据。

(这意味着它不适用于 8 之前的 IE)

编辑 2: 正如 @Darin Peterson 所指出的,之前的代码不适用于多个放置区域;这应该可以解决该问题: http://jsfiddle.net/Polmonite/XJCmM/

编辑3: EDIT 2 中的示例有一个错误。如果我拖动“拖动我!”到底部可投放项,然后将“Drag me too”投放到上部可投放项,然后将“Drag me too”投放到外面,它会提醒“已放入内部!”所以,不要使用它。

编辑 4: 正如 @Aleksey Gor 所指出的,编辑 2 中的示例是错误的;实际上,它更多的是一个例子来解释如何循环所有的可拖动/可放置的,但我实际上忘记删除警报消息,所以它非常令人困惑。 这里更新的小提琴。

I see that you already got an answer; anyway I had this same problem today and I solved it this way:

var outside = 0;

// this one control if the draggable is outside the droppable area
$('#droppable').droppable({
    accept      : '.draggable',
    out         : function(){
        outside = 1;
    },
    over        : function(){
        outside = 0;
    }
});

// this one control if the draggable is dropped
$('body').droppable({
    accept      : '.draggable',
    drop        : function(event, ui){
        if(outside == 1){
            alert('Dropped outside!');
        }else{
            alert('Dropped inside!');
        }
    }
});

I needed that because I couldn't change the options of my draggables, so I had to work only with droppables (I needed it inside the awesome FullCalendar plugin).
I suppose it could have some issues using the "greedy" option of droppables, but it should work in most cases.

PS: sorry for my bad english.

EDIT: As suggested, I created the version using the jQuery.data; it can be found here : jsfiddle.net/Polmonite/WZma9/

Anyway jQuery.data documentation say:

Note that this method currently does not provide cross-platform support for setting data on XML documents, as Internet Explorer does not allow data to be attached via expando properties.

(meaning that it doesn't work on IE prior to 8)

EDIT 2: As noted by @Darin Peterson , the previous code doesn't work with more than one drop-area; this should fix that issue: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3: Example from EDIT 2 has a bug. If I drag "Drag me!" to the bottom droppable, then drop "Drag me too" to the upper droppable and then drop "Drag me too" outside, it alerts "Dropped inside!" So, don't use it.

EDIT 4: As noted by @Aleksey Gor, the example in Edit 2 was wrong; actually, it was more of an example to explain how to loop through all the draggables/droppables, but I actually forgot to remove the alert messages, so it was pretty confusing. Here the updated fiddle.

情绪失控 2024-12-21 22:52:49

尝试使用droppable元素的事件“out”

这是 文档

“当接受的可拖动对象被拖出时(在该可滴落物的耐受性。”
如果我是对的,这就是你所需要的。

还可以在整个页面上创建一个元素覆盖。如果该元素被放置在那里,您就会触发您的事件。不是最好的,但我认为是唯一的方法。因为您需要一些其他“可放置”项目来触发这些事件。

Try to use the event "out" of a droppable element.

This is the documentation

"This event is triggered when an accepted draggable is dragged out (within the tolerance of) this droppable."
If I'm right, this is what you need.

What is also possible is to create an element overlay over the whole page. If the element is dropped there you fire your event. Not the best, but I think the only way to do it. Because you need some other "droppable" item to fire these events.

痴者 2024-12-21 22:52:49

以下示例的优点是您无需更改或了解可放置代码:

可拖动恢复属性可以具有函数(值){}。一个值作为参数传递,指示 helper 是否被拖放到某个元素上(拖放元素),如果没有拖放到某个元素上(拖放到外部或不被接受),则为“false”。

注意:您需要从中返回正确的布尔值
恢复功能,以告诉助手是否恢复
(正确/错误)。 true表示是,将helper带回原来的样子
位置,通过以慢动作将其移回(开箱即用)。 False 意味着没有,只是
突然移除助手。将恢复属性设置为“无效”,
是说的快捷方式

  • “是的,如果掉到外面,则恢复助手”
  • “不,如果掉落在可掉落元素上并被接受,则立即杀死助手”。

我的猜测是,您可以在启动事件期间将当前的 ui 帮助器添加到具有 data 属性的可拖动容器中。然后从数据属性的恢复函数中选取它。然后向助手添加一个属性,指示它是否被删除。然后最终在停止事件中检查此数据属性值,并执行您想要的操作。

可拖动的事件/函数调用顺序:
start-revert-stop

这可能是一个例子:

jQuery('#draggable').draggable(
{
    start: function(event, ui) {
        $(this).data('uihelper', ui.helper);
    },
    revert: function(value){
        var uiHelper = (this).data('uihelper');
        uiHelper.data('dropped', value !== false);
        if(value === false){
             return true;
        }
        return false;
    },
    stop: function(event, ui)
    {
        if(ui.helper.data('dropped') === true){
            // handle accordingly...
        }
    }
});

您甚至可以在恢复函数中返回 true,并在停止事件期间删​​除助手,具体取决于 ui.helper.remove() 的 data('dropped') 值。或者,如果你今天仍然心情不好,你甚至可以用 CSS3 来分解它;)

The advantage of the following example, is that you don't need to change or know about the droppable code:

The draggable revert property can have a function(value){}. A value is passed as argument, indicating if helper was dropped onto an element (the drop element), or 'false' if not dropped on an element (drop outside or not accepted).

Note: you need to return the correct bool value from that
revert-function, in order to tell the helper to revert or not
(true/false). True means yes, take the helper back to its original
position, by moving it back in a slow motion (out-of-the-box). False means no, just
remove the helper abdruptly. Setting the revert property to 'invalid',
is a shortcut of saying

  • 'yes, if dropped outside, then revert helper'
  • 'no, if dropped on a droppable element and accepted, then kill the helper right away'.

My guess is that you can add current ui helper to draggable container with data property during start event. Then pick it up in the revert function from the data property. Then add a property to the helper, indicating if it was dropped or not. Then ultimately in the stop event, check this data property value, and do what you intended.

Order of event/function calls for draggable:
start-revert-stop

This could be an example:

jQuery('#draggable').draggable(
{
    start: function(event, ui) {
        $(this).data('uihelper', ui.helper);
    },
    revert: function(value){
        var uiHelper = (this).data('uihelper');
        uiHelper.data('dropped', value !== false);
        if(value === false){
             return true;
        }
        return false;
    },
    stop: function(event, ui)
    {
        if(ui.helper.data('dropped') === true){
            // handle accordingly...
        }
    }
});

You can even return true in the revert function, and just remove the helper during the stop event instead, depending on the data('dropped') value with ui.helper.remove(). Or you could even explode it with CSS3 if you still have a bad day ;)

蓝天 2024-12-21 22:52:49

老问题和老答案意味着这个“可能”是一个新的解决方案。正如问题所述,您(也许)还想知道可拖动对象是否被放置在可放置对象之外。对我来说,至少在 95% 的情况下,我并不真正关心是否,我只是希望事情回到原来的样子,而不需要在发生这种情况时做出任何改变。

revert 设置为字符串 invalid 即可完成所需的行为,而无需任何额外的代码或时髦的事情要做。

$( '#draggable' ).draggable({
    revert: "invalid",
    stop: function( event, ui )
    {
       // whatever
    }
});

同样,它不会告诉您“是否将其放置在可放置的范围之外”,但如果发生这种情况,它将恢复到初始状态。

Old question and old answers mean that this "may" be a new solution. You (maybe) also wanted, as the question states, to know IF a draggable was dropped outside of a droppable. For me, in at least 95% of the cases, I don't really care IF, I just want things to go back to how they were without any changes being made WHEN that happens.

Setting revert to the string invalid accomplishes the desired behavior without any extra code or funky things to do.

$( '#draggable' ).draggable({
    revert: "invalid",
    stop: function( event, ui )
    {
       // whatever
    }
});

Again, it won't tell you "if it was dropped outside of a droppable," but it will revert to the initial state if that happens.

晨光如昨 2024-12-21 22:52:49

我添加了我采用的解决方案,因为您可以从要移动的对象的 css 类中轻松理解这一点:

jQuery('#draggable').draggable({
  stop: function(event, ui) {
    if (ui.helper.hasClass('ui-draggable-dragging')) {
      console.log('dropped out');
    } else {
      console.log('dropped successfully');
    }
  }
});

I add the solution I adopted since you can understand this very easily from the css classes of the object you are moving:

jQuery('#draggable').draggable({
  stop: function(event, ui) {
    if (ui.helper.hasClass('ui-draggable-dragging')) {
      console.log('dropped out');
    } else {
      console.log('dropped successfully');
    }
  }
});
も让我眼熟你 2024-12-21 22:52:49

这对我来说工作:

<script>
$( function() {
    $( "#draggable" ).draggable();
    $( ".droppable" ).droppable({
        drop: function( event, ui ) {
            if( $(this) ){
                $( "#draggable" ).draggable( "disable" );
            }                
        },
    });
} );

This work for me:

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