Задача: необходимо иметь диалоговое окно, которое можно перетаскивать и которое при изменении размера окна будет сохранять свое положение относительно центра экрана.
Решение:
Для перетаскивания объектов на 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');
}
Комментариев нет:
Отправить комментарий