// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы. // в другие стороны // чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край // исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден // позиция мыши смещается 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 = $('
').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 = $('