刷新可拖动的遏制

时间:2010-07-19 01:07:07

标签: jquery jquery-ui

我有一个可以将包含设置为父级的可拖动元素。这很有效,但div内容可以改变,使其更高。无论如何都要触发拖动事件,以确保它不会从其父内部移动。现在,它可以与父项重叠,直到它被拖动,然后收容开始。

最诚挚的问候 标记

3 个答案:

答案 0 :(得分:10)

我已经实现了一个小插件,可以满足您的需求。它可以在可拖动的更改大小之后强制执行包含,甚至可以在您拖动时进行操作。我已经使用jQuery UI 1.8.6和jQuery 1.4.3测试了它,但它可能会破坏过去或未来的版本,因为它必须使用内部方法。

工作演示

http://jsbin.com/uvino4/27

完整来源

插件

/*
 * jQuery UI RefreshContainment v0.1
 *
 * A plugin for jQuery UI's Draggable. It adds a refreshContainment method to
 * every draggable which allows you to use the containment option on draggables
 * with dynamically changing sizes.
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 *  jquery.ui.draggable.js
 */

(function ($){
  var $window = $(window);

  // We need to know the location of the mouse so that we can use it to
  // refresh the containment at any time.

  $window.data("refreshContainment", {mousePosition: {pageX: 0, pageY: 0}});
  $window.mousemove(function (event) {
    $window.data("refreshContainment", {
      mousePosition: {pageX: event.pageX, pageY: event.pageY}
    });
  });

  // Extend draggable with the proxy pattern.
  var proxied = $.fn.draggable;
  $.fn.draggable = (function (method){
    if (method === "refreshContainment") {
      this.each(function (){
        var inst = $(this).data("draggable");

        // Check if the draggable is already being dragged.
        var isDragging = inst.helper && inst.helper.is(".ui-draggable-dragging");

        // We are going to use the existing _mouseStart method to take care of
        // refreshing the containtment but, since we don't actually intend to
        // emulate a true _mouseStart, we have to avoid any extraneous
        // operations like the drag/drop manager and event triggering.
        // So we save the original member values and replace them with dummies.
        var ddmanager = $.ui.ddmanager;
        $.ui.ddmanager = null;
        var trigger = inst._trigger;
        inst._trigger = function () { return true; }


        var mousePosition = $window.data("refreshContainment").mousePosition;
        var fakeEvent = {
          pageX: mousePosition.pageX, pageY: mousePosition.pageY
        };
        inst._mouseStart(fakeEvent);

        // Return those extraneous members back to the original values.
        inst._trigger = trigger;
        $.ui.ddmanager = ddmanager;

        // Clear the drag, unless it was already being dragged.
        if (!isDragging) {
          inst._clear();
        }
      });
      return this;
    }
    else {
      // Delegate all other calls to the actual draggable implemenation.
      return proxied.apply(this, arguments);
    }
  });
})(jQuery);

演示HTML

<!DOCTYPE html>
<html>
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>

<style>
  #container { width: 20em; height: 20em; border: 0.5em solid black; }
  .draggable { width: 5em; height: 5em; border: 0.2em solid black; position: absolute; }
  #one { background-color: #F55; }
  #two { background-color: #5F5; }
</style>
</head>
<body>
  <div id="container">
    <div class="draggable" id="one">drag me</div>
    <div class="draggable" id="two">drag me</div>
  </div>
</body>
</html>

演示JavaScript

var draggables = $('.draggable');

draggables.draggable({containment: 'parent', stack: draggables});

var resizeDraggables = function (){
  draggables.
    each(function (){
      var size = 5 + Math.random() * 5;
      size = size.toString() + "em";
      $(this).css({width: size, height: size});
    }).
    draggable("refreshContainment");
};

resizeDraggables();

setInterval(resizeDraggables, 2000);

答案 1 :(得分:3)

这有用吗?

$("#yourcontainment").bind("resizestop", function () {
  $(".yourdraggables").draggable("option", "containment", $("#yourcontainment"));
});

如果你不使用jQuery UI的可调整大小,你必须触发“resizestop”事件。

答案 2 :(得分:0)

因为您正在修改[包含]元素大小,所以必须为结果实现自己的处理程序。 jQuery知道在拖动过程中该做什么,但在调整大小期间有许多可能的行为:

  • 阻止调整所包含的内容
  • 元素移动内部元素 (哪个方向)
  • 删除元素

可以想象出一系列针对不同UI约束的虚拟场景。

只需为包含的类的所有对象创建一个PostionValidator()方法,并在调用modify方法后执行它。