Задача: необходимо иметь диалоговое окно, которое можно перетаскивать и которое при изменении размера окна будет сохранять свое положение относительно центра экрана.
Решение:
Для перетаскивания объектов на javascript уже существует такой замечательный инструмент как jquery.ui.draggable, он очень богат и именно его мне и хотелось бы использовать, но у него перетаскиваемые элементы позиционируются абсолютно. Значит, необходимо выполнить небольшую подмену.
Суть идеи такова: диалоговое окно по умолчанию находится в относительном позиционировании (left: 50%, margin-left: -width/2). Перед началом перетаскивания мы просто переводим относительные координаты в абсолютные и срабатывает стандартный jQuery.ui.draggable со всеми его особенностями. По окончании перетаскивания мы просто возвращаем объекту относительные координаты.
Реализация задуманной идеи:
Реализация задуманной идеи:
$.widget('ui.reldraggable', $.ui.draggable, { create: function () { this.element.data('uiDraggable', this); this._super('_create'); }, _setOption: function (key, value) { this._super('_setOption', key, value); }, disabled: function(){ this.element.addClass("ui-draggable-disabled"); }, _mouseCapture: function(event) { var o = this.options; // among others, prevent a drag on a resizable-handle if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { return false; } //Quit if we're not on a valid handle this.handle = this._getHandle(event); //if ( ! this.handle) return false; $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({ width: this.offsetWidth+"px", height: this.offsetHeight+"px", position: "absolute", opacity: "0.001", zIndex: 1000}) .css($(this).offset()) .appendTo("body"); }); return true; }, _mouseStart: function(d){ $(d.currentTarget).css({ 'left': d.currentTarget.offsetLeft, 'margin-left': 0, 'right': 'auto' }); this._super(d, true); }, _mouseStop: function(d){ var a = $(this.element).offset().left, b = parseFloat($('body').width()), margin = parseInt(a - b/2) + 'px'; $(this.element).css({ 'left' : '50%', 'right' : 'auto', 'margin-left': margin }); this._super(d, true); } });Хочу заметить, что предложенный код будет работать только с jquery.ui.1.10.x. Для того, чтобы это работало в jquery.ui.1.9.x надо заменить _create на:
_create: function() { this.element.data('draggable', this); this._super('_create'); }
Комментариев нет:
Отправить комментарий