给jQuery可拖拽组件添加一个回弹“事件”函数

24

我当前的情况:

我有一个可拖动的 div 元素,其 revert 参数设置为 "invalid"。

我的需求:

当 revert 发生时,我想触发另一个元素的 CSS 改变。

问题所在:

"revert" 是一个参数而不是事件,因此当 revert 发生时,我很难触发所需的 CSS 改变。

我的代码:

$('#peg_icon').draggable({
    revert: 'invalid',
    scroll: false,
    stack: "#peg_icon",
    drag: function(event, ui) {
        $('#peg_icon').css('background-image','url(images/peg-icon-when-dragged.png)');
    }
});

我尝试过的:

我曾尝试使用"revert"作为事件,但未成功:

revert: function(event, ui) {
    $('#peg_icon').css('background-image','url(images/peg-icon-default.png)');
},

我也曾试图将revert参数添加到这个函数中,但没有成功:

function(socketObj)
  {
     //if false then no socket object drop occurred.
     if(socketObj === false)
     {
        //revert the peg by returning true
        $('#peg_icon').css('background-image','url(images/peg-icon-default.png)');
        return true;
     }
     else
     {
        //return false so that the peg does not revert
        return false;
     }
  }

背景:

我正在拖动一个 div 元素,当拖动时,其背景图片随之变化;当放开鼠标后,背景图片又恢复到原始状态。

我的问题:

如何在拖动回退时触发对另一个元素 CSS 样式的更改?


4
只是想说,这个问题思考得非常周全并且表达清晰! - Jason M. Batchelor
感谢您的认可。 - Dominor Novus
2个回答

26

原来 revert 命令可以接受一个方法。请参考以下完整示例: http://jsfiddle.net/mori57/Xpscw/

具体而言:

$(function() {
    $("#ducky").draggable({
        revert: function(is_valid_drop){
            console.log("is_valid_drop = " + is_valid_drop);
            // when you're done, you need to remove the "dragging" class
            // and yes, I'm sure this can be refactored better, but I'm 
            // out of time for today! :)
            if(!is_valid_drop){
               console.log("revert triggered");
                $(".pond").addClass("green");
                $(this).removeClass("inmotion");
               return true;
            } else {
                $(".pond").removeClass("green");
                $(this).removeClass("inmotion");
            }
        },
        drag: function(){
            // as you drag, add your "dragging" class, like so:
            $(this).addClass("inmotion");
        }
    });
    $("#boat").droppable({
      drop: function( event, ui ) {
        $(this)
          .addClass("ui-state-highlight");
      }
    });
  });

希望这有所帮助... 我猜测您尝试修改的内容可能是问题所在,而不是尝试使用还原与函数调用。再次查看您尝试设置的 CSS,看看问题是否可能出在那里。


具体来说,我建议您使用addClass()方法而不是.css()方法来为可拖动元素添加类。在CSS中更改图标,而不是在JavaScript中更改,这样当您还原时,只需从可拖动元素中调用.removeCSS('drag-indicator-class')即可使图像自动恢复到默认状态。 - Jason M. Batchelor
谢谢您提供详尽的回答、代码和工作示例。 小注: 我不知道在 CSS 中可以将类附加到 id 上,即 #some_id.some_class。这是我第一次看到这种选择器。我之前一直使用 !important 来强制让 .inmotion 类覆盖默认的 #peg_icon id。 - Dominor Novus
问题:使用addClass/removeClass相对于JavaScript方法有什么优势?是使用一个开/关动作而不是两个分离的动作吗?我最初使用JavaScript方法的原因主要基于这样一种迷信,即默认和“运动中”的背景图像不会通过CSS预加载,并且某种程度上JavaScript方法“强制”更快地在背景图像之间切换。简单来说,CSS和JavaScript方法哪种方法可以更快地预加载或加载背景图像? - Dominor Novus
2
优点在于灵活性,以及将演示与逻辑分离。在某些时候,您可能想要重用代码或更改使用的图像。CSS 是这种信息所属的地方,在 CSS 中进行更改比直接在 JS 中进行更改更不容易无意中引入错误。我无法回答问题中关于预加载部分的问题...那是我需要研究的事情,但是通过 JS 强制执行也意味着引入更多的 HTTP 请求(每次切换图像都需要一个请求),这也是低效的,而缓存的 CSS 则不同。 - Jason M. Batchelor
明白了,我会坚持你建议的添加/删除类的方法。 - Dominor Novus
3
小注释:is_valid_drop从未为真,相反,在成功拖放时,它是可拖动元素。 - Marcel Burkhard

1
你想做这样的事情:
 $('#peg_icon').draggable({
        revert: function (socketObj) {
        if (socketObj === true) {
            // success
            return false;
        }
        else {
            // reverting
            return true;
        }
    },
        scroll: false,
        stack: "#peg_icon",
        drag: function(event, ui) {
            $('#peg_icon').css('background-image','url(images/peg-icon-when-dragged.png)');
        }
    });

DEMO: http://jsfiddle.net/yTMwu/35/

希望这可以帮到你!

3
感谢提供代码和Fiddle演示。由于某些原因,这段代码阻止了我将#peg_icon放置到次要的放置区域(即除正在拖动的放置区域之外的放置区域)。我知道我在之前的问题中提供的上下文有限,可能导致了这个问题。顺便说一句:你的可怕凯奇头像让我感到有些受创。 - Dominor Novus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接