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 @@
{"name":"window","plunk":"4EQ5K3IYSLg2jE7DOgpy"}

View file

@ -0,0 +1,126 @@
// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы.
// в другие стороны
// чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край
// исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден
// позиция мыши смещается
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/>', {
"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]
}
this.getElement = function() {
if (!elem) render();
return elem;
}
function onTitleMouseDown(e) {
startDrag(e.pageX, e.pageY);
return false;
};
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);
}
}

View file

@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<link type="text/css" rel="stylesheet" href="window.css" />
<style>
html, body {
padding: 0;
margin: 0;
}
</style>
<script src="draggableWindow.js"></script>
</head>
<body style="height:2000px">
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
<script type="text/template" id="draggable-window-template">
<div class="window-title"><%=title%></div>
<div class="window-content"></div>
<form class="window-message-form">
<input type="text" name="message" class="window-message-text"><input type="submit" name="submit" class="window-message-submit" value="Послать">
</form>
</script>
<script>
var win = new DraggableWindow({
title: "Чат с Петей",
template: $('#draggable-window-template').html()
});
win.getElement().appendTo('body');
</script>
</body>
</html>

View file

@ -0,0 +1 @@
{"name":"window-manager","plunk":"WahQdnjtnXesAuix7gsv"}

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') + "]";
}
}

View file

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<link type="text/css" rel="stylesheet" href="window.css" />
<style>
html, body {
padding: 0;
margin: 0;
}
</style>
<script src="draggableWindow.js"></script>
<script src="windowManager.js"></script>
</head>
<body>
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
<script type="text/template" id="draggable-window-template">
<div class="window-title"><%=title%></div>
<div class="window-content"></div>
<form class="window-message-form">
<input type="text" name="message" class="window-message-text"><input type="submit" name="submit" class="window-message-submit" value="Послать">
</form>
</script>
<script>
WindowManager.setTemplate( $('#draggable-window-template').html().trim() );
WindowManager.addWindow({
title: "Чат с Петей"
});
WindowManager.addWindow({
title: "Чат с Машей"
});
</script>
</body>
</html>

View file

@ -0,0 +1,56 @@
.window {
position: absolute;
left: 0;
top: 0;
z-index: 10;
width: 200px;
height: 300px;
border: 2px #ADD8E6 groove;
/* раскомментировать для проверки, вылезает ли внешняя рамка за экран
border: 2px red solid;
*/
background: white;
}
.window-title {
width: 100%;
height: 30px;
line-height: 30px;
background-color: #4169E1;
color: white;
text-align:center;
cursor: pointer;
}
.window-moving .window-title {
cursor: move;
}
.window-message-form {
position: absolute;
bottom: 0;
height: 30px;
line-height: 30px;
width: 100%;
background: #ADD8E6;
}
.window-content {
height: 240px;
padding: 3px;
overflow-y: auto;
}
.window-message-text {
width: 120px;
}
.window-message-submit {
width: 70px;
margin-left: 2px;
}

View file

@ -0,0 +1,52 @@
var WindowManager = new function() {
var windows = [];
var activeWindow;
var template;
this.setTemplate = function(newTemplate) {
template = _.template(newTemplate);
};
this.addWindow = function(options) {
var win = new DraggableWindow({
title: options.title,
template: template
});
$(win).on("focus", function() {
activateWindow(this);
});
win.getElement().appendTo('body');
windows.push(win);
activateWindow(win);
return win;
}
function activateWindow(win) {
if (activeWindow == win) return;
activeWindow = win;
sortWindows();
}
/**
* пересортировать окна
*/
function sortWindows() {
windows.sort(function(a, b) {
if (activeWindow == a) return 1; // активное окно больше всех
if (activeWindow == b) return -1; // активное окно больше всех
return a.getZIndex() - b.getZIndex(); // порядок среди остальных - оставляем "как есть"
});
for(var i=0; i<windows.length; i++) {
windows[i].setZIndex(i+1);
}
}
}

View file

@ -0,0 +1,56 @@
.window {
position: absolute;
left: 0;
top: 0;
z-index: 10;
width: 200px;
height: 300px;
border: 2px #ADD8E6 groove;
/* раскомментировать для проверки, вылезает ли внешняя рамка за экран
border: 2px red solid;
*/
background: white;
}
.window-title {
width: 100%;
height: 30px;
line-height: 30px;
background-color: #4169E1;
color: white;
text-align:center;
cursor: pointer;
}
.window-moving .window-title {
cursor: move;
}
.window-message-form {
position: absolute;
bottom: 0;
height: 30px;
line-height: 30px;
width: 100%;
background: #ADD8E6;
}
.window-content {
height: 240px;
padding: 3px;
overflow-y: auto;
}
.window-message-text {
width: 120px;
}
.window-message-submit {
width: 70px;
margin-left: 2px;
}