diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md
index 99dde5bc..fc3bf652 100644
--- a/2-ui/1-document/05-basic-dom-node-properties/article.md
+++ b/2-ui/1-document/05-basic-dom-node-properties/article.md
@@ -10,7 +10,7 @@ Different DOM nodes may have different properties. For instance, an element node
Each DOM node belongs to the corresponding built-in class.
-The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by [Node](https://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it.
+The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by [Node](http://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it.
Here's the picture, explanations to follow:
@@ -18,39 +18,16 @@ Here's the picture, explanations to follow:
The classes are:
-- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class for everything.
-
- Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later.
-
-- [Node](https://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base for DOM nodes.
-
- It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are other classes that inherit from it (and so inherit the `Node` functionality).
-
-- [Document](https://dom.spec.whatwg.org/#interface-document), for historical reasons often inherited by `HTMLDocument` (though the latest spec doesn't dictate it) -- is a document as a whole.
-
- The `document` global object belongs exactly to this class. It serves as an entry point to the DOM.
-
-- [CharacterData](https://dom.spec.whatwg.org/#interface-characterdata) -- an "abstract" class, inherited by:
- - [Text](https://dom.spec.whatwg.org/#interface-text) -- the class corresponding to a text inside elements, e.g. `Hello` in `
Once upon a time there was a mother pig who had three little pigs.
-
The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+
The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
The three little pigs set off. "We will take care that the wolf does not catch us," they said.
Once upon a time there was a mother pig who had three little pigs.
-
The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+
The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
The three little pigs set off. "We will take care that the wolf does not catch us," they said.
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
index 7503ca9c..4e6e2a3e 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
@@ -88,7 +88,7 @@ class HoverIntent {
if (speed < this.sensitivity) {
clearInterval(this.checkSpeedInterval);
this.isHover = true;
- this.over.call(this.elem);
+ this.over.call(this.elem, event);
} else {
// speed fast, remember new coordinates as the previous ones
this.prevX = this.lastX;
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg
index 6044eff1..07830295 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-bubble-nested.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg
index 22335b52..07176ba2 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-from-outside.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg
index 437f03b1..262ddf59 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout-over-elems.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg
index 1277ddff..784f435d 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-mouseout.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg
index 78210845..b38d76fb 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseover-to-child.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
index 5752e83a..6d87199c 100755
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
@@ -3,7 +3,7 @@ parent.onmouseover = parent.onmouseout = parent.onmousemove = handler;
function handler(event) {
let type = event.type;
- while (type.length < 11) type += ' ';
+ while (type < 11) type += ' ';
log(type + " target=" + event.target.id)
return false;
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
index f5bd9f4f..ca8bbc3b 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
index 4c928eef..49ab88be 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
@@ -18,19 +18,19 @@ The basic Drag'n'Drop algorithm looks like this:
2. Then on `mousemove` move it by changing `left/top` with `position:absolute`.
3. On `mouseup` - perform all actions related to finishing the drag'n'drop.
-These are the basics. Later we'll see how to add other features, such as highlighting current underlying elements while we drag over them.
+These are the basics. Later we'll see how to other features, such as highlighting current underlying elements while we drag over them.
Here's the implementation of dragging a ball:
```js
-ball.onmousedown = function(event) {
+ball.onmousedown = function(event) {
// (1) prepare to moving: make absolute and on top by z-index
ball.style.position = 'absolute';
ball.style.zIndex = 1000;
// move it out of any current parents directly into body
// to make it positioned relative to the body
- document.body.append(ball);
+ document.body.append(ball);
// centers the ball at (pageX, pageY) coordinates
function moveAt(pageX, pageY) {
@@ -93,14 +93,14 @@ So we should listen on `document` to catch it.
## Correct positioning
-In the examples above the ball is always moved so that its center is under the pointer:
+In the examples above the ball is always moved so, that it's center is under the pointer:
```js
ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
```
-Not bad, but there's a side effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer.
+Not bad, but there's a side-effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer.
It would be better if we keep the initial shift of the element relative to the pointer.
@@ -219,7 +219,7 @@ That's why the initial idea to put handlers on potential droppables doesn't work
So, what to do?
-There's a method called `document.elementFromPoint(clientX, clientY)`. It returns the most nested element on given window-relative coordinates (or `null` if given coordinates are out of the window). If there are multiple overlapping elements on the same coordinates, then the topmost one is returned.
+There's a method called `document.elementFromPoint(clientX, clientY)`. It returns the most nested element on given window-relative coordinates (or `null` if given coordinates are out of the window).
We can use it in any of our mouse event handlers to detect the potential droppable under the pointer, like this:
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/ball_shift.svg b/2-ui/3-event-details/4-mouse-drag-and-drop/ball_shift.svg
index 29fdb31e..3aa2541d 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/ball_shift.svg
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/ball_shift.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/6-pointer-events/article.md b/2-ui/3-event-details/6-pointer-events/article.md
index b8873e9d..3e751a4a 100644
--- a/2-ui/3-event-details/6-pointer-events/article.md
+++ b/2-ui/3-event-details/6-pointer-events/article.md
@@ -9,16 +9,16 @@ Let's make a small overview, so that you understand the general picture and the
- Long ago, in the past, there were only mouse events.
Then touch devices became widespread, phones and tablets in particular. For the existing scripts to work, they generated (and still generate) mouse events. For instance, tapping a touchscreen generates `mousedown`. So touch devices worked well with web pages.
-
+
But touch devices have more capabilities than a mouse. For example, it's possible to touch multiple points at once ("multi-touch"). Although, mouse events don't have necessary properties to handle such multi-touches.
- So touch events were introduced, such as `touchstart`, `touchend`, `touchmove`, that have touch-specific properties (we don't cover them in detail here, because pointer events are even better).
- Still, it wasn't enough, as there are many other devices, such as pens, that have their own features. Also, writing code that listens for both touch and mouse events was cumbersome.
+ Still, it wasn't enough, as there are many other devices, such as pens, that have their own features. Also, writing code that listens for both touch and mouse events was cumbersome.
- To solve these issues, the new standard Pointer Events was introduced. It provides a single set of events for all kinds of pointing devices.
-As of now, [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) specification is supported in all major browsers, while the newer [Pointer Events Level 3](https://w3c.github.io/pointerevents/) is in the works and is mostly compatible with Pointer Events level 2.
+As of now, [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) specification is supported in all major browsers, while the newer [Pointer Events Level 3](https://w3c.github.io/pointerevents/) is in the works and is mostly compartible with Pointer Events level 2.
Unless you develop for old browsers, such as Internet Explorer 10, or for Safari 12 or below, there's no point in using mouse or touch events any more -- we can switch to pointer events.
@@ -43,12 +43,12 @@ Pointer events are named similarly to mouse events:
| `gotpointercapture` | - |
| `lostpointercapture` | - |
-As we can see, for every `mouse`, there's a `pointer` that plays a similar role. Also there are 3 additional pointer events that don't have a corresponding `mouse...` counterpart, we'll explain them soon.
+As we can see, for every `mouse`, there's a `pointer` that plays a similar role. Also there are 3 additional pointer events that don't have a corresponding `mouse...` counterpart, we'll explain them soon.
```smart header="Replacing `mouse` with `pointer` in our code"
We can replace `mouse` events with `pointer` in our code and expect things to continue working fine with mouse.
-The support for touch devices will also "magically" improve. Although, we may need to add `touch-action: none` in some places in CSS. We'll cover it below in the section about `pointercancel`.
+The support for touch devices will also "magically" improve. Although, we may need to add `touch-action: none` in some places in CSS. We'll cover it below in the section about `pointercancel`.
```
## Pointer event properties
@@ -56,16 +56,16 @@ The support for touch devices will also "magically" improve. Although, we may ne
Pointer events have the same properties as mouse events, such as `clientX/Y`, `target`, etc., plus some others:
- `pointerId` - the unique identifier of the pointer causing the event.
-
+
Browser-generated. Allows us to handle multiple pointers, such as a touchscreen with stylus and multi-touch (examples will follow).
-- `pointerType` - the pointing device type. Must be a string, one of: "mouse", "pen" or "touch".
+- `pointerType` - the pointing device type. Must be a string, one of: "mouse", "pen" or "touch".
We can use this property to react differently on various pointer types.
- `isPrimary` - is `true` for the primary pointer (the first finger in multi-touch).
Some pointer devices measure contact area and pressure, e.g. for a finger on the touchscreen, there are additional properties for that:
-- `width` - the width of the area where the pointer (e.g. a finger) touches the device. Where unsupported, e.g. for a mouse, it's always `1`.
+- `width` - the width of the area where the pointer (e.g. a finger) touches the device. Where unsupported, e.g. for a mouse, it's always `1`.
- `height` - the height of the area where the pointer touches the device. Where unsupported, it's always `1`.
- `pressure` - the pressure of the pointer tip, in range from 0 to 1. For devices that don't support pressure must be either `0.5` (pressed) or `0`.
- `tangentialPressure` - the normalized tangential pressure.
@@ -102,16 +102,16 @@ Please note: you must be using a touchscreen device, such as a phone or a tablet
## Event: pointercancel
-The `pointercancel` event fires when there's an ongoing pointer interaction, and then something happens that causes it to be aborted, so that no more pointer events are generated.
+The `pointercancel` event fires when there's an ongoing pointer interaction, and then something happens that causes it to be aborted, so that no more pointer events are generated.
-Such causes are:
+Such causes are:
- The pointer device hardware was physically disabled.
-- The device orientation changed (tablet rotated).
+- The device orientation changed (tablet rotated).
- The browser decided to handle the interaction on its own, considering it a mouse gesture or zoom-and-pan action or something else.
We'll demonstrate `pointercancel` on a practical example to see how it affects us.
-Let's say we're implementing drag'n'drop for a ball, just as in the beginning of the article .
+Let's say we're impelementing drag'n'drop for a ball, just as in the beginning of the article .
Here is the flow of user actions and the corresponding events:
@@ -126,7 +126,7 @@ Here is the flow of user actions and the corresponding events:
So the issue is that the browser "hijacks" the interaction: `pointercancel` fires in the beginning of the "drag-and-drop" process, and no more `pointermove` events are generated.
```online
-Here's the drag'n'drop demo with loggin of pointer events (only `up/down`, `move` and `cancel`) in the `textarea`:
+Here's the drag'n'drop demo with loggin of pointer events (only `up/down`, `move` and `cancel`) in the `textarea`:
[iframe src="ball" height=240 edit]
```
@@ -141,7 +141,7 @@ We need to do two things:
- We can do this by setting `ball.ondragstart = () => false`, just as described in the article .
- That works well for mouse events.
2. For touch devices, there are other touch-related browser actions (besides drag'n'drop). To avoid problems with them too:
- - Prevent them by setting `#ball { touch-action: none }` in CSS.
+ - Prevent them by setting `#ball { touch-action: none }` in CSS.
- Then our code will start working on touch devices.
After we do that, the events will work as intended, the browser won't hijack the process and doesn't emit `pointercancel`.
@@ -163,7 +163,7 @@ Pointer capturing is a special feature of pointer events.
The idea is very simple, but may seem quite odd at first, as nothing like that exists for any other event type.
The main method is:
-- `elem.setPointerCapture(pointerId)` -- binds events with the given `pointerId` to `elem`. After the call all pointer events with the same `pointerId` will have `elem` as the target (as if happened on `elem`), no matter where in document they really happened.
+- `elem.setPointerCapture(pointerId)` - binds events with the given `pointerId` to `elem`. After the call all pointer events with the same `pointerId` will have `elem` as the target (as if happened on `elem`), no matter where in document they really happened.
In other words, `elem.setPointerCapture(pointerId)` retargets all subsequent events with the given `pointerId` to `elem`.
@@ -172,43 +172,29 @@ The binding is removed:
- automatically when `elem` is removed from the document,
- when `elem.releasePointerCapture(pointerId)` is called.
-Now what is it good for? It's time to see a real-life example.
-
**Pointer capturing can be used to simplify drag'n'drop kind of interactions.**
-Let's recall how one can implement a custom slider, described in the .
+As an example, let's recall how one can implement a custom slider, described in the .
-We can make a `slider` element to represent the strip and the "runner" (`thumb`) inside it:
+We make a slider element with the strip and the "runner" (`thumb`) inside it.
-```html
-
-
-
-```
+Then it works like this:
-With styles, it looks like this:
+1. The user presses on the slider `thumb` - `pointerdown` triggers.
+2. Then they move the pointer - `pointermove` triggers, and we move the `thumb` along.
+ - ...As the pointer moves, it may leave the slider `thumb`: go above or below it. The `thumb` should move strictly horizontally, remaining aligned with the pointer.
-[iframe src="slider-html" height=40 edit]
+So, to track all pointer movements, including when it goes above/below the `thumb`, we had to assign `pointermove` event handler on the whole `document`.
-
+That solution looks a bit "dirty". One of the problems is that pointer movements around the document may cause side effects, trigger other event handlers, totally not related to the slider.
-And here's the working logic, as it was described, after replacing mouse events with similar pointer events:
-
-1. The user presses on the slider `thumb` -- `pointerdown` triggers.
-2. Then they move the pointer -- `pointermove` triggers, and our code moves the `thumb` element along.
- - ...As the pointer moves, it may leave the slider `thumb` element, go above or below it. The `thumb` should move strictly horizontally, remaining aligned with the pointer.
-
-In the mouse event based solution, to track all pointer movements, including when it goes above/below the `thumb`, we had to assign `mousemove` event handler on the whole `document`.
-
-That's not a cleanest solution, though. One of the problems is that when a user moves the pointer around the document, it may trigger event handlers (such as `mouseover`) on some other elements, invoke totally unrelated UI functionality, and we don't want that.
-
-This is the place where `setPointerCapture` comes into play.
+Pointer capturing provides a means to bind `pointermove` to `thumb` and avoid any such problems:
- We can call `thumb.setPointerCapture(event.pointerId)` in `pointerdown` handler,
-- Then future pointer events until `pointerup/cancel` will be retargeted to `thumb`.
+- Then future pointer events until `pointerup/cancel` will be retargeted to `thumb`.
- When `pointerup` happens (dragging complete), the binding is removed automatically, we don't need to care about it.
-So, even if the user moves the pointer around the whole document, events handlers will be called on `thumb`. Nevertheless, coordinate properties of the event objects, such as `clientX/clientY` will still be correct - the capturing only affects `target/currentTarget`.
+So, even if the user moves the pointer around the whole document, events handlers will be called on `thumb`. Besides, coordinate properties of the event objects, such as `clientX/clientY` will still be correct - the capturing only affects `target/currentTarget`.
Here's the essential code:
@@ -216,23 +202,15 @@ Here's the essential code:
thumb.onpointerdown = function(event) {
// retarget all pointer events (until pointerup) to thumb
thumb.setPointerCapture(event.pointerId);
-
- // start tracking pointer moves
- thumb.onpointermove = function(event) {
- // moving the slider: listen on the thumb, as all pointer events are retargeted to it
- let newLeft = event.clientX - slider.getBoundingClientRect().left;
- thumb.style.left = newLeft + 'px';
- };
-
- // on pointer up finish tracking pointer moves
- thumb.onpointerup = function(event) {
- thumb.onpointermove = null;
- thumb.onpointerup = null;
- // ...also process the "drag end" if needed
- };
};
-// note: no need to call thumb.releasePointerCapture,
+thumb.onpointermove = function(event) {
+ // moving the slider: listen on the thumb, as all pointer events are retargeted to it
+ let newLeft = event.clientX - slider.getBoundingClientRect().left;
+ thumb.style.left = newLeft + 'px';
+};
+
+// note: no need to call thumb.releasePointerCapture,
// it happens on pointerup automatically
```
@@ -240,27 +218,15 @@ thumb.onpointerdown = function(event) {
The full demo:
[iframe src="slider" height=100 edit]
-
-
-
-In the demo, there's also an additional element with `onmouseover` handler showing the current date.
-
-Please note: while you're dragging the thumb, you may hover over this element, and its handler *does not* trigger.
-
-So the dragging is now free of side effects, thanks to `setPointerCapture`.
```
-
-
At the end, pointer capturing gives us two benefits:
1. The code becomes cleaner as we don't need to add/remove handlers on the whole `document` any more. The binding is released automatically.
-2. If there are other pointer event handlers in the document, they won't be accidentally triggered by the pointer while the user is dragging the slider.
+2. If there are any `pointermove` handlers in the document, they won't be accidentally triggered by the pointer while the user is dragging the slider.
### Pointer capturing events
-There's one more thing to mention here, for the sake of completeness.
-
-There are two events associated with pointer capturing:
+There are two associated pointer events:
- `gotpointercapture` fires when an element uses `setPointerCapture` to enable capturing.
- `lostpointercapture` fires when the capture is released: either explicitly with `releasePointerCapture` call, or automatically on `pointerup`/`pointercancel`.
@@ -271,7 +237,7 @@ Pointer events allow handling mouse, touch and pen events simultaneously, with a
Pointer events extend mouse events. We can replace `mouse` with `pointer` in event names and expect our code to continue working for mouse, with better support for other device types.
-For drag'n'drops and complex touch interactions that the browser may decide to hijack and handle on its own - remember to cancel the default action on events and set `touch-action: none` in CSS for elements that we engage.
+For drag'n'drops and complex touch interactions that the browser may decide to hijack and handle on its own - remember to cancel the default action on events and set `touch-events: none` in CSS for elements that we engage.
Additional abilities of pointer events are:
diff --git a/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html b/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html
deleted file mode 100644
index 781016f5..00000000
--- a/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/2-ui/3-event-details/6-pointer-events/slider.view/style.css b/2-ui/3-event-details/6-pointer-events/slider.view/style.css
index a84cd5e7..9b3d3b82 100644
--- a/2-ui/3-event-details/6-pointer-events/slider.view/style.css
+++ b/2-ui/3-event-details/6-pointer-events/slider.view/style.css
@@ -8,7 +8,6 @@
}
.thumb {
- touch-action: none;
width: 10px;
height: 25px;
border-radius: 3px;
diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md
index 12fe6320..54bde42b 100644
--- a/2-ui/3-event-details/7-keyboard-events/article.md
+++ b/2-ui/3-event-details/7-keyboard-events/article.md
@@ -107,7 +107,7 @@ So, `event.code` may match a wrong character for unexpected layout. Same letters
To reliably track layout-dependent characters, `event.key` may be a better way.
-On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location. So hotkeys that rely on it work well even in case of a language switch.
+On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location, even if the visitor changes languages. So hotkeys that rely on it work well even in case of a language switch.
Do we want to handle layout-dependant keys? Then `event.key` is the way to go.
@@ -139,25 +139,22 @@ For instance, the `` below expects a phone number, so it does not accept
```html autorun height=60 run
```
-The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. If it's valid (from `0..9` or one of `+-()`), then it returns `true`, otherwise `false`.
+Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`.
-As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters)
+Let's relax it a little bit:
-Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side effect of the strict filter `checkPhoneKey`. These keys make it return `false`.
-
-Let's relax the filter a little bit by allowing arrow keys `key:Left`, `key:Right` and `key:Delete`, `key:Backspace`:
```html autorun height=60 run
@@ -165,9 +162,7 @@ function checkPhoneKey(key) {
Now arrows and deletion works well.
-Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. Mobile devices provide other means to enter values. So the filter is not 100% reliable.
-
-The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and modify it/highlight the `` when it's invalid. Or we can use both event handlers together.
+...But we still can enter anything by using a mouse and right-click + Paste. So the filter is not 100% reliable. We can just let it be like that, because most of time it works. Or an alternative approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid.
## Legacy
diff --git a/2-ui/3-event-details/7-keyboard-events/german-layout.svg b/2-ui/3-event-details/7-keyboard-events/german-layout.svg
index 7ac9a400..8a880e8e 100644
--- a/2-ui/3-event-details/7-keyboard-events/german-layout.svg
+++ b/2-ui/3-event-details/7-keyboard-events/german-layout.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
index a0d5a4f4..40106283 100644
--- a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
+++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
@@ -28,7 +28,7 @@
-
+
diff --git a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
index d97f7a7b..5eba24c7 100644
--- a/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
+++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
@@ -5,8 +5,6 @@ let lastTime = Date.now();
function handle(e) {
if (form.elements[e.type + 'Ignore'].checked) return;
- area.scrollTop = 1e6;
-
let text = e.type +
' key=' + e.key +
' code=' + e.code +
diff --git a/2-ui/3-event-details/7-keyboard-events/us-layout.svg b/2-ui/3-event-details/7-keyboard-events/us-layout.svg
index 353f225f..699277e0 100644
--- a/2-ui/3-event-details/7-keyboard-events/us-layout.svg
+++ b/2-ui/3-event-details/7-keyboard-events/us-layout.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md
index f22518d9..689301e4 100644
--- a/2-ui/4-forms-controls/1-form-elements/article.md
+++ b/2-ui/4-forms-controls/1-form-elements/article.md
@@ -155,7 +155,7 @@ Let's talk about form controls.
### input and textarea
-We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes and radio buttons.
+We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes.
Like this:
diff --git a/2-ui/4-forms-controls/1-form-elements/form-navigation.svg b/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
index 2c908070..b112e250 100644
--- a/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
+++ b/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md b/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
index 378bd1f5..2cccea02 100644
--- a/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
+++ b/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
@@ -6,7 +6,7 @@ importance: 5
Make table cells editable on click.
-- On click -- the cell should become "editable" (textarea appears inside), we can change HTML. There should be no resize, all geometry should remain the same.
+- On click -- the cell should became "editable" (textarea appears inside), we can change HTML. There should be no resize, all geometry should remain the same.
- Buttons OK and CANCEL appear below the cell to finish/cancel the editing.
- Only one cell may be editable at a moment. While a `
` is in "edit mode", clicks on other cells are ignored.
- The table may have many cells. Use event delegation.
diff --git a/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md b/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
index 644d814d..fc48c21f 100644
--- a/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
+++ b/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
@@ -9,5 +9,4 @@ Focus on the mouse. Then use arrow keys to move it:
[demo src="solution"]
P.S. Don't put event handlers anywhere except the `#mouse` element.
-
P.P.S. Don't modify HTML/CSS, the approach should be generic and work with any element.
diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md
index c253dc11..d4348d25 100644
--- a/2-ui/4-forms-controls/2-focus-blur/article.md
+++ b/2-ui/4-forms-controls/2-focus-blur/article.md
@@ -90,8 +90,6 @@ If we enter something into the input and then try to use `key:Tab` or click away
Please note that we can't "prevent losing focus" by calling `event.preventDefault()` in `onblur`, because `onblur` works *after* the element lost the focus.
-In practice though, one should think well, before implementing something like this, because we generally *should show errors* to the user, but *should not prevent their progress* in filling our form. They may want to fill other fields first.
-
```warn header="JavaScript-initiated focus loss"
A focus loss can occur for many reasons.
@@ -106,7 +104,7 @@ The best recipe is to be careful when using these events. If we want to track us
```
## Allow focusing on any element: tabindex
-By default, many elements do not support focusing.
+By default many elements do not support focusing.
The list varies a bit between browsers, but one thing is always correct: `focus/blur` support is guaranteed for elements that a visitor can interact with: `