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,30 @@
# События
Три события имеют отношение к подсказке:
<ol>
<li>При `mouseover` -- показать.</li>
<li>При `mousemove` -- показать на новом месте.</li>
<li>При `mouseout` -- спрятать.</li>
</ol>
...Но при заходе на элемент происходят сразу оба события: `mouseover` и `mousemove` на нём же. Зачем вызывать код для показа два раза? Можно оставить его только в `mousemove`.
Стиль элемента подсказки:
```css
.tooltip {
position:absolute;
z-index:100; /* подсказка должна перекрывать другие элементы */
...
}
```
# Решение
[edit src="solution"]Решение в песочнице[/edit]
В нём есть две тонкости.
<ol>
<li>Для того, чтобы можно было получить высоту и ширину, подсказку надо сначала показать.</li>
<li>При показе -- важно, чтобы подсказка не оказалась *под* курсором. Если такое произойдет, то дальнейшие события `mousemove` станут происходить *уже на подсказке*, а не на элементе, и их обработка сломается.</li>
</ol>

View file

@ -0,0 +1 @@
{"name":"tooltip-moving","plunk":"ViHd2RiFFISfNZ10ARlZ"}

View file

@ -0,0 +1,138 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body {
height: 2000px; /* подсказка должна работать независимо от прокрутки */
}
.tooltip {
position:absolute;
z-index:100; /* подсказка должна перекрывать другие элементы */
padding: 10px 20px;
/* красивости... */
border: 1px solid #b3c9ce;
border-radius: 4px;
text-align: center;
font: italic 14px/1.3 arial, sans-serif;
color: #333;
background: #fff;
box-shadow: 3px 3px 3px rgba(0,0,0,.3);
}
</style>
</head>
<body>
<a href="#" id="link">Ссылка с подсказкой</a>
<a href="#" id="link2">Еще ссылка</a>
<div id="elem" style="border:1px solid black; position:absolute;width:300px;height:150px;right:10px;bottom:10px">
<em>Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</em>
</div>
<script>
// должно работать даже если страница имеет прокрутку
// подсказка должна перекрывать текст под ней
// у нижнего и правого края окна подсказка должна идти налево/вверх от курсора
function Tooltip(options) {
var offsetFromCursor = (options.offset === undefined) ? 10 : options.offset;
var tooltipElem;
var isEnabled = true;
var elem = options.elem;
var html = options.html;
elem.on({
mouseenter: onMouseEnter,
mouseleave: onMouseLeave,
mousemove: onMouseMove
});
function onMouseEnter(e) {
show(e.pageX, e.pageY);
}
function onMouseLeave() {
hide();
}
function onMouseMove(e) {
show(e.pageX, e.pageY);
}
function hide() {
getTooltipElem().remove();
};
function getTooltipElem() {
if (!tooltipElem) {
tooltipElem = $('<div/>', {
"class" : 'tooltip',
html: html
});
}
return tooltipElem;
}
function show(pageX, pageY) {
var tooltipElem = getTooltipElem();
if (!tooltipElem.is(':visible')) {
// первым делом - отобразить подсказку, чтобы можно было получить её размеры
tooltipElem.appendTo('body');
}
var scrollY = $(window).scrollTop();
var winBottom = scrollY + $(window).height();
var scrollX = $(window).scrollLeft();
var winRight = scrollX + $(window).width();
var newLeft = pageX + offsetFromCursor;
var newTop = pageY + offsetFromCursor;
if (newLeft + tooltipElem.outerWidth() > winRight) { // если за правой границей окна
newLeft -= tooltipElem.outerWidth();
newLeft -= offsetFromCursor + 2; // немного левее, чтобы курсор был не над подсказкой
}
if (newTop + tooltipElem.outerHeight() > winBottom) { // если за нижней границей окна
newTop -= tooltipElem.outerHeight();
newTop -= offsetFromCursor + 2; // немного выше
}
tooltipElem.css({
left: newLeft,
top: newTop
});
};
}
new Tooltip({
elem: $('#elem'),
html: "Вот <b>такая</b> подсказка!"
});
new Tooltip({
elem: $('#link'),
html: $('#link').html()
});
new Tooltip({
elem: $('#link2'),
html: $('#link2').html()
});
</script>
</body>
</html>

View file

@ -0,0 +1 @@
{"name":"tooltip-moving","plunk":"ViHd2RiFFISfNZ10ARlZ"}

View file

@ -0,0 +1,138 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body {
height: 2000px; /* подсказка должна работать независимо от прокрутки */
}
.tooltip {
position:absolute;
z-index:100; /* подсказка должна перекрывать другие элементы */
padding: 10px 20px;
/* красивости... */
border: 1px solid #b3c9ce;
border-radius: 4px;
text-align: center;
font: italic 14px/1.3 arial, sans-serif;
color: #333;
background: #fff;
box-shadow: 3px 3px 3px rgba(0,0,0,.3);
}
</style>
</head>
<body>
<a href="#" id="link">Ссылка с подсказкой</a>
<a href="#" id="link2">Еще ссылка</a>
<div id="elem" style="border:1px solid black; position:absolute;width:300px;height:150px;right:10px;bottom:10px">
<em>Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</em>
</div>
<script>
// должно работать даже если страница имеет прокрутку
// подсказка должна перекрывать текст под ней
// у нижнего и правого края окна подсказка должна идти налево/вверх от курсора
function Tooltip(options) {
var offsetFromCursor = (options.offset === undefined) ? 10 : options.offset;
var tooltipElem;
var isEnabled = true;
var elem = options.elem;
var html = options.html;
elem.on({
mouseenter: onMouseEnter,
mouseleave: onMouseLeave,
mousemove: onMouseMove
});
function onMouseEnter(e) {
show(e.pageX, e.pageY);
}
function onMouseLeave() {
hide();
}
function onMouseMove(e) {
show(e.pageX, e.pageY);
}
function hide() {
getTooltipElem().remove();
};
function getTooltipElem() {
if (!tooltipElem) {
tooltipElem = $('<div/>', {
"class" : 'tooltip',
html: html
});
}
return tooltipElem;
}
function show(pageX, pageY) {
var tooltipElem = getTooltipElem();
if (!tooltipElem.is(':visible')) {
// первым делом - отобразить подсказку, чтобы можно было получить её размеры
tooltipElem.appendTo('body');
}
var scrollY = $(window).scrollTop();
var winBottom = scrollY + $(window).height();
var scrollX = $(window).scrollLeft();
var winRight = scrollX + $(window).width();
var newLeft = pageX + offsetFromCursor;
var newTop = pageY + offsetFromCursor;
if (newLeft + tooltipElem.outerWidth() > winRight) { // если за правой границей окна
newLeft -= tooltipElem.outerWidth();
newLeft -= offsetFromCursor + 2; // немного левее, чтобы курсор был не над подсказкой
}
if (newTop + tooltipElem.outerHeight() > winBottom) { // если за нижней границей окна
newTop -= tooltipElem.outerHeight();
newTop -= offsetFromCursor + 2; // немного выше
}
tooltipElem.css({
left: newLeft,
top: newTop
});
};
}
new Tooltip({
elem: $('#elem'),
html: "Вот <b>такая</b> подсказка!"
});
new Tooltip({
elem: $('#link'),
html: $('#link').html()
});
new Tooltip({
elem: $('#link2'),
html: $('#link2').html()
});
</script>
</body>
</html>

View file

@ -0,0 +1,34 @@
# Подсказка, следующая за курсором
[importance 4]
Создайте всплывающую подсказку, следующую за курсором.
<ul>
<li>Подсказка должна появляться при наведении на элемент, на небольшом расстоянии справа-снизу от курсора.</li>
<li>При передвижении курсора подсказка следует за ним.</li>
<li>Если курсор слишком низко/справа, то чтобы подсказка не вылезла за нижнюю/правую границу экрана -- пусть отображается сверху/слева от курсора.</li>
</ul>
Вы можете посмотреть поведение подсказки в ифрейме ниже, наведя курсор на правый-нижний угол.
[iframe src="solution" height=200 link border=1]
Способ добавления подсказки к элементу:
```js
new Tooltip({
elem: $('#elem'),
html: "Вот <b>такая</b> подсказка!")
});
```
Естественные пожелания:
<ul>
<li>Подсказка не должна "моргать" при движении мыши.</li>
<li>Подсказка должна правильно работать, если у страницы есть прокрутка.</li>
<li>В подсказке и элементе, на который она поставлена, может быть произвольный HTML. Оформление подсказки должно задаваться CSS.</li>
<li>Объект подсказки не должен иметь публичных методов, только приватные.</li>
</ul>
[edit src="task" task/]

View file

@ -0,0 +1 @@
{"name":"tooltip-moving-src","plunk":"2N1muMlIKBmADQIRbPoY"}

View file

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body {
height: 2000px; /* подсказка должна работать независимо от прокрутки */
}
.tooltip {
/* ваш стиль */
}
</style>
</head>
<body>
<a href="#" id="link">Ссылка с подсказкой</a>
<a href="#" id="link2">Еще ссылка</a>
<div id="elem" style="border:1px solid black; position:absolute;width:300px;height:150px;right:10px;bottom:10px">
<em>Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст
Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</em>
</div>
<script>
// должно работать даже если страница имеет прокрутку
// подсказка должна перекрывать текст под ней
// у нижнего и правого края окна подсказка должна идти налево/вверх от курсора
function Tooltip(options) {
/* ваш код */
}
new Tooltip({
elem: $('#elem'),
html: "Вот <b>такая</b> подсказка!"
});
new Tooltip({
elem: $('#link'),
html: $('#link').html()
});
new Tooltip({
elem: $('#link2'),
html: $('#link2').html()
});
</script>
</body>
</html>