This commit is contained in:
Ilya Kantor 2014-10-26 22:10:13 +03:00
parent 06f61d8ce8
commit f301cb744d
2271 changed files with 103162 additions and 0 deletions

View file

@ -0,0 +1,142 @@
// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы.
// в другие стороны
// чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край
// исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден
// позиция мыши смещается
function DraggableWindow(options) {
var self = this;
var title = options.title;
var template = typeof options.template == 'function' ? // компиляция, если строка
options.template : _.template(options.template);
var elem, contentElem;
var mouseDownShift;
function render() {
elem = $('<div tabindex="0" class="window"/>').html(template({
title: title
}));
$('form', elem).on('submit', onSubmit);
titleElem = elem.find('.window-title');
titleElem.on('selectstart dragstart', false);
titleElem.on('mousedown', onTitleMouseDown);
contentElem = elem.find('.window-content'); // = children[1]
elem.on('focusin', onFocus);
}
this.getElement = function() {
if (!elem) render();
return elem;
}
function onFocus() {
$(self).triggerHandler({ type: 'focus' });
}
function onTitleMouseDown(e) {
startDrag(e.pageX, e.pageY);
setTimeout(onFocus, 0);
return false; // returning false prevents onfocus
};
function startDrag(mouseDownX, mouseDownY) {
// запомнить координаты нажатия
var coords = elem.offset();
mouseDownShift = {
x: mouseDownX - coords.left,
y: mouseDownY - coords.top
};
// двигать
$(document).on({
'mousemove.draggablewindow': onDocumentMouseMove,
'mouseup.draggablewindow': onDocumentMouseUp
});
elem.addClass('window-moving');
}
function onDocumentMouseUp() {
$(document).off('.draggablewindow');
elem.removeClass('window-moving');
}
function onDocumentMouseMove(e) {
moveWindowAtCursor(e.pageX, e.pageY);
}
function moveWindowAtCursor(pageX, pageY) {
var newLeft = pageX - mouseDownShift.x;
var newTop = pageY - mouseDownShift.y;
// проверим, не вылезем ли мы за границы экрана
var windowLeft = window.pageXOffset || document.documentElement.scrollLeft;
var windowTop = window.pageYOffset || document.documentElement.scrollTop;
var windowRight = windowLeft + document.documentElement.clientWidth;
var windowBottom = windowTop + document.documentElement.clientHeight;
// тут не if..else, а if т.к., возможно, обе координаты надо поправить
if (newLeft < windowLeft) {
newLeft = windowLeft;
}
if (newLeft > windowRight - elem.outerWidth()) {
newLeft = windowRight - elem.outerWidth(); // внешняя ширина с учетом рамки внешней
}
if (newTop < windowTop) {
newTop = windowTop;
}
if (newTop > windowBottom - titleElem.outerHeight()) {
newTop = windowBottom - titleElem.outerHeight();
// внизу заголовок будет немного залезать за край, т.к. нужно мерять вместе с рамкой верхней на самом деле
// но здесь это не страшно
}
elem.css({
left: newLeft,
top: newTop
});
};
function onSubmit(e) {
// принять события, совершить обработку события, связанную с формой
var form = e.currentTarget;
var value = form.elements.message.value;
form.elements.message.value = '';
if (value) {
submit(value); // логика по отправке сообщения
}
return false;
}
function submit(message) {
// добавить
var newMessageElem = $('<div>', {text: message }).appendTo(contentElem);
// прокрутить к новому сообщению
contentElem.prop('scrollTop', 999999999);
}
this.setZIndex = function(zIndex) {
elem.css('z-index', zIndex);
};
this.getZIndex = function() {
return +elem.css('z-index') || 0;
};
this.toString = function() {
return "[Window " + options.title + " " + elem.css('z-index') + "]";
}
}