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,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,11 @@
# Подсказки
<ul>
<li>Так как высота и ширина окна известны, вёрстка внутри может содержать точные пиксельные размеры.</li>
<li>При обработке события `document.onmousemove`, мы вычисляем новые координаты `left/top` и смотрим, вылезает ли окно за границы. Если да -- меняем `left/top` на максимально возможные, чтобы не вылезало.</li>
<li>На форме вешаем обработчик `onsubmit`, т.к. иначе Enter в поле отправить её на сервер.</li>
</ul>
# Решение
[edit src="solution"]Открыть в песочнице[/edit]

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,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,26 @@
# Переносимые окна
[importance 5]
Создайте виджет окна для чата.
Окно -- это `DIV`, который можно переносить, взявшись за заголовок. По нажатию на "Послать" данные передаются в содержание окна.
[demo src="index.html"/]
Синтаксис:
```js
new DraggableWindow({
title: "Чат с Петей",
template: HTML-шаблон окна
});
```
<ul>
<li>Возможно появление прокрутки внутри окна, если сообщений много. Сообщения не должны вылезать вовне окна.</li>
<li>Окно нельзя вытащить за пределы экрана, даже резкими движениями мыши. Влево-вправо-вверх оно вообще не должно вылезать за границу, а вниз -- только до заголовка. Попробуйте перемещать его в демо, чтобы увидеть.</li>
<li>Для задания DOM-структуры окна используйте шаблон. Может быть создано несколько окон.</li>
</ul>
[edit src="task" task/]

View file

@ -0,0 +1 @@
{"name":"window-src","plunk":"LvOiMPt6359D4X13ZLkB"}

View file

@ -0,0 +1,55 @@
<!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>
<style>
html, body {
padding: 0;
margin: 0;
}
/* ваши стили */
</style>
</head>
<body>
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
<script type="text/template" id="draggable-window-template">
/* шаблон для окна */
</script>
<script>
// если начать перенос и передвинуть мышь максимально вверх -- верхний край окна не должен вылетать за край страницы.
// в другие стороны
// чтобы даже при резких движениях мыши -- окно прилипало к краю но не вылезало за край
// исключение -- максимальная нижняя позиция окна -- это когда только заголовок виден
// позиция мыши смещается
function DraggableWindow(options) {
var self = this;
/* ваш код */
}
var win = new DraggableWindow({
title: "Чат с Петей",
template: $('#draggable-window-template').html()
});
win.getElement().appendTo('body');
</script>
</body>
</html>