jQuery可拖动问题

Posted

技术标签:

【中文标题】jQuery可拖动问题【英文标题】:Jquery draggable issue 【发布时间】:2013-01-16 17:15:09 【问题描述】:

基本上我想要的是,在拖动时,如果我走出收容区域并在那里释放鼠标点击,可拖动元素只会粘在我离开收容区域的边框上。当我将光标移回时,元素会回到光标上。当您只是移动光标(而不是拖动)并且元素仍在被拖动时,它看起来不太好。

Here 是一个可以玩的小提琴。只需在输出区域外拖动并释放光标,您就会明白我在说什么。

我想了两种方法

    在被拖动时限制鼠标移动到包含区域(我搜索了它,但没有找到怎么做。也许这不可能?)

    如果光标离开包含区域,则将可拖动对象恢复到其位置。 (还是找不到办法)

有任何方法或更多聪明的想法来实现这一目标???

Relevant Code(用于堆栈溢出)

【问题讨论】:

在这里工作正常。你用什么浏览器? 在 Firefox 中有效,在 chrome 中无效 你的真实生活(不是小提琴)代码也在 iframe 中吗? 【参考方案1】:

我认为这是因为它在 iframe 中。 这就像在浏览器外拖动一样。 mouseup 事件不会在页面中注册。

看起来 chrome 不允许这样做,但 firefox 可以。

试试这个: fiddle

$('body').mouseleave(function()
    
    $(document).trigger("mouseup");
    );

这是您的解决方案,无需每次都设置事件。

矫枉过正的版本(这将允许用户暂时(1 秒)离开 iframe 并返回而不丢失拖动):

$('body').prop('mouseuptimer',null)
    .mouseleave(function()
        
        var objTimer = setTimeout(function() 
            
            $(document).trigger("mouseup")
            , 1000);
        $(document).prop('mouseuptimer', objTimer);
        )
    .mouseenter(function()
        
        var objTimer = $(document).prop('mouseuptimer');
        if (objTimer) clearTimeout(objTimer);
        );
$(function() 
    
    $( "#sortable" ).sortable(revert: true );
    $( "#draggable" ).draggable(
        connectToSortable: "#sortable",
        helper: "clone",
        revert: "invalid" );
    $( "ul, li" ).disableSelection();
    );

编辑:

回答你的第一个问题:

您可以通过在选项中添加“包含”来包含可拖动对象,即:

$( "#draggable" ).draggable(
    connectToSortable: "#sortable",
    helper: "clone",
    revert: "invalid",
    containment: "document" );

但这只能包含拖动到边界框的元素(在本例中为“文档”,但也可以是“父”或“#somediv”)。 鼠标光标仍然可以移动到 iframe 之外的任何位置,并从那里调度事件,超出 iframe 文档的范围。

【讨论】:

那么我们如何在 chrome 中实现相同的行为呢? 会调查并告诉你:) 添加了对您的收容问题的答案。 使用包含体仍然不会在 chrome 中调度 iframe 之外的事件【参考方案2】:

好的,我找到了解决方法。适用于 IE8 和 Chrome。

为可拖动元素添加了此代码。

drag: function()
     $('body').mouseleave(function()
          $('body').mouseup();
     );

Working Fiddle

编辑:感谢Rembunator 指出缺陷,我决定使用.one() 以获得更好的性能,并将代码从拖动切换到开始

start: function()
     $('body').one("mouseleave", function()
          $('body').mouseup();
     );

编辑 2:

终于找到了解决办法。

代码如下:

var flag=true;
start: function( event, ui )
    if(flag)
         flag = false;
         $('body').one("mouseleave", function()
             $('body').mouseup();
              flag = true; //event occured, rebind
          );
     
     else
         flag = false;
     

感谢Rembunator 的帮助

【讨论】:

虽然是个好主意,但我认为这会在每次拖动时设置 mouseleave 事件。 添加了一种借助计时器让拖动“不那么紧张”的方法。 好的,我之所以在拖动中编写函数是因为我不希望每次用户不拖动时都触发该事件。我认为用户可能将鼠标移入和移出该 iframe 的次数将大于他拖动元素的次数。你说什么? 只有当鼠标离开 iframe 时才会触发该事件。每次拖动可能会触发拖动事件数百次。为了使事情尽可能干净,您可以在 drag.start 上将 mouseleave 事件添加到 body 并在 drag.stop 上将其删除。 我认为在每次拖动时添加和删除事件将比触发简单事件花费更多的处理时间。

以上是关于jQuery可拖动问题的主要内容,如果未能解决你的问题,请参考以下文章

jQuery可拖动嵌套div并再次拖动

克隆时的jQuery可拖动元素不可拖动

拖动时jQuery可拖动克隆大小

jQuery可拖动问题

JQuery-UI 可拖动项变为不可拖动

带有可点击对象的jQuery可拖动列表 - 防止点击拖动