up
This commit is contained in:
parent
5f2d199054
commit
e4db23fa56
13 changed files with 42 additions and 62 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
# Lookahead (in progress)
|
||||||
|
|
||||||
|
The article is under development, will be here when it's ready.
|
|
@ -87,7 +87,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// сортировать
|
// sort
|
||||||
rowsArray.sort(compare);
|
rowsArray.sort(compare);
|
||||||
|
|
||||||
tbody.append(...rowsArray);
|
tbody.append(...rowsArray);
|
||||||
|
|
|
@ -78,11 +78,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onmouseout = function() {
|
document.onmouseout = function() {
|
||||||
// возможно такое, что mouseout сработал, а мы все еще внутри элемента (всплытие)
|
// it is possible that mouseout triggered, but we're still inside the element (cause of bubbling)
|
||||||
// но в этом случае сразу же будет и mouseover,
|
// but in this case we'll have an immediate mouseover,
|
||||||
// то есть подсказка будет уничтожена и тут же показана заново
|
// so the tooltip will be destroyed and shown again
|
||||||
//
|
//
|
||||||
// это лишние расходы, их можно избежать дополнительными проверками
|
// that's an overhead, but here it's not visible
|
||||||
|
// can be fixed with additional checks
|
||||||
if (tooltip) {
|
if (tooltip) {
|
||||||
tooltip.remove();
|
tooltip.remove();
|
||||||
tooltip = false;
|
tooltip = false;
|
||||||
|
|
|
@ -58,7 +58,7 @@ class HoverIntent {
|
||||||
this.elem.removeEventListener('mousemove', this.onMouseMove);
|
this.elem.removeEventListener('mousemove', this.onMouseMove);
|
||||||
clearInterval(this.checkSpeedInterval);
|
clearInterval(this.checkSpeedInterval);
|
||||||
if (this.isHover) {
|
if (this.isHover) {
|
||||||
// если была остановка над элементом
|
// if there was a stop over the element
|
||||||
this.out.call(this.elem, event);
|
this.out.call(this.elem, event);
|
||||||
this.isHover = false;
|
this.isHover = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,12 +175,13 @@ Try to move the cursor in and out of table cells and inside them. Fast or slow -
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Итого
|
## Summary
|
||||||
|
|
||||||
У `mouseover, mousemove, mouseout` есть следующие особенности:
|
We covered events `mouseover`, `mouseout`, `mousemove`, `mouseenter` and `mouseleave`.
|
||||||
|
|
||||||
- При быстром движении мыши события `mouseover, mousemove, mouseout` могут пропускать промежуточные элементы.
|
Things that are good to note:
|
||||||
- События `mouseover` и `mouseout` -- единственные, у которых есть вторая цель: `relatedTarget` (`toElement/fromElement` в IE).
|
|
||||||
- События `mouseover/mouseout` подразумевают, что курсор находится над одним, самым глубоким элементом. Они срабатывают при переходе с родительского элемента на дочерний.
|
|
||||||
|
|
||||||
События `mouseenter/mouseleave` не всплывают и не учитывают переходы внутри элемента.
|
- A fast mouse move can make `mouseover, mousemove, mouseout` to skip intermediate elements.
|
||||||
|
- Events `mouseover/out` and `mouseenter/leave` have an additional target: `relatedTarget`. That's the element that we are coming from/to, complementary to `target`.
|
||||||
|
- Events `mouseover/out` trigger even when we go from the parent element to a child element. They assume that the mouse can be only over one element at one time -- the deepest one.
|
||||||
|
- Events `mouseenter/leave` do not bubble and do not trigger when the mouse goes to a child element. They only track whether the mouse comes inside and outside the element as a whole.
|
||||||
|
|
|
@ -70,5 +70,4 @@
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -1,46 +1,38 @@
|
||||||
// элемент TD, внутри которого сейчас курсор
|
// <td> under the mouse right now (if any)
|
||||||
var currentElem = null;
|
let currentElem = null;
|
||||||
|
|
||||||
table.onmouseover = function(event) {
|
table.onmouseover = function(event) {
|
||||||
if (currentElem) {
|
if (currentElem) {
|
||||||
// перед тем, как зайти в новый элемент, курсор всегда выходит из предыдущего
|
// before entering a new element, the mouse always leaves the previous one
|
||||||
//
|
// if we didn't leave <td> yet, then we're still inside it, so can ignore the event
|
||||||
// если мы еще не вышли, значит это переход внутри элемента, отфильтруем его
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// посмотрим, куда пришёл курсор
|
let target = event.target.closest('td');
|
||||||
var target = event.target;
|
if (!target || !table.contains(target)) return;
|
||||||
|
|
||||||
// уж не на TD ли?
|
// yeah we're inside <td> now
|
||||||
while (target != this) {
|
|
||||||
if (target.tagName == 'TD') break;
|
|
||||||
target = target.parentNode;
|
|
||||||
}
|
|
||||||
if (target == this) return;
|
|
||||||
|
|
||||||
// да, элемент перешёл внутрь TD!
|
|
||||||
currentElem = target;
|
currentElem = target;
|
||||||
target.style.background = 'pink';
|
target.style.background = 'pink';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
table.onmouseout = function(event) {
|
table.onmouseout = function(event) {
|
||||||
// если курсор и так снаружи - игнорируем это событие
|
// if we're outside of any <td> now, then ignore the event
|
||||||
if (!currentElem) return;
|
if (!currentElem) return;
|
||||||
|
|
||||||
// произошёл уход с элемента - проверим, куда, может быть на потомка?
|
// we're leaving the element -- where to? Maybe to a child element?
|
||||||
var relatedTarget = event.relatedTarget;
|
let relatedTarget = event.relatedTarget;
|
||||||
if (relatedTarget) { // может быть relatedTarget = null
|
if (relatedTarget) { // possible: relatedTarget = null
|
||||||
while (relatedTarget) {
|
while (relatedTarget) {
|
||||||
// идём по цепочке родителей и проверяем,
|
// go up the parent chain and check -- if we're still inside currentElem
|
||||||
// если переход внутрь currentElem - игнорируем это событие
|
// then that's an internal transition -- ignore it
|
||||||
if (relatedTarget == currentElem) return;
|
if (relatedTarget == currentElem) return;
|
||||||
relatedTarget = relatedTarget.parentNode;
|
relatedTarget = relatedTarget.parentNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// произошло событие mouseout, курсор ушёл
|
// we left the element. really.
|
||||||
currentElem.style.background = '';
|
currentElem.style.background = '';
|
||||||
currentElem = null;
|
currentElem = null;
|
||||||
};
|
};
|
|
@ -69,7 +69,7 @@
|
||||||
|
|
||||||
<textarea id="text"></textarea>
|
<textarea id="text"></textarea>
|
||||||
|
|
||||||
<input type="button" onclick="text.value=''" value="Очистить">
|
<input type="button" onclick="text.value=''" value="Clear">
|
||||||
|
|
||||||
|
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<script>
|
|
||||||
function getChar(event) {
|
|
||||||
if (event.which == null) { // IE
|
|
||||||
if (event.keyCode < 32) return null; // спец. символ
|
|
||||||
return String.fromCharCode(event.keyCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.which != 0 && event.charCode != 0) { // все кроме IE
|
|
||||||
if (event.which < 32) return null; // спец. символ
|
|
||||||
return String.fromCharCode(event.which); // остальные
|
|
||||||
}
|
|
||||||
|
|
||||||
return null; // спец. символ
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,5 +1,3 @@
|
||||||
# События в деталях
|
# Events in details
|
||||||
|
|
||||||
В этом разделе мы разбираем конкретные события и особенности работы с ними.
|
Here we cover most important events and details of working with them.
|
||||||
|
|
||||||
Вы можете читать его в любом порядке или кратко просмотреть его и вернуться к конкретным событиям, когда они понадобятся.
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ For instance:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let option = new Option("Text", "value");
|
let option = new Option("Text", "value");
|
||||||
// creates <option value="value">Текст</option>
|
// creates <option value="value">Text</option>
|
||||||
```
|
```
|
||||||
|
|
||||||
The same element selected:
|
The same element selected:
|
||||||
|
|
|
@ -42,7 +42,8 @@ Your email please: <input type="email" id="input">
|
||||||
};
|
};
|
||||||
|
|
||||||
*!*input.onfocus*/!* = function() {
|
*!*input.onfocus*/!* = function() {
|
||||||
if (this.classList.contains('invalid')) { // сбросить состояние "ошибка", если оно есть
|
if (this.classList.contains('invalid')) {
|
||||||
|
// remove the "error" indication, because the user wants to re-enter something
|
||||||
this.classList.remove('invalid');
|
this.classList.remove('invalid');
|
||||||
error.innerHTML = "";
|
error.innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ Requirements:
|
||||||
- When the form is shown, the focus should be inside the `<input>` for the user.
|
- When the form is shown, the focus should be inside the `<input>` for the user.
|
||||||
- Keys `key:Tab`/`key:Shift+Tab` should shift the focus between form fields, don't allow it to leave for other page elements.
|
- Keys `key:Tab`/`key:Shift+Tab` should shift the focus between form fields, don't allow it to leave for other page elements.
|
||||||
|
|
||||||
Пример использования:
|
Usage example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
showPrompt("Enter something<br>...smart :)", function(value) {
|
showPrompt("Enter something<br>...smart :)", function(value) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue