Skip to content

Commit 28cc5c8

Browse files
committed
minor
1 parent cdf6156 commit 28cc5c8

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

1-js/04-object-basics/03-symbol/article.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,19 @@ alert(id.description); // id
7474

7575
Symbols allow us to create "hidden" properties of an object, that no other part of code can occasionally access or overwrite.
7676

77-
For instance, if we're working with `user` objects, that belong to a third-party code and don't have any `id` field. We'd like to add identifiers to them.
77+
For instance, if we're working with `user` objects, that belong to a third-party code. We'd like to add identifiers to them.
7878

7979
Let's use a symbol key for it:
8080

8181
```js run
82-
let user = { name: "John" };
82+
let user = { // belongs to another code
83+
name: "John"
84+
};
85+
8386
let id = Symbol("id");
8487

85-
user[id] = "ID Value";
88+
user[id] = 1;
89+
8690
alert( user[id] ); // we can access the data using the symbol as the key
8791
```
8892

@@ -108,13 +112,13 @@ There will be no conflict between our and their identifiers, because symbols are
108112
```js run
109113
let user = { name: "John" };
110114

111-
// our script uses "id" property
112-
user.id = "ID Value";
115+
// Our script uses "id" property
116+
user.id = "Our id value";
113117

114-
// ...if later another script the uses "id" for its purposes...
118+
// ...Another script also wants "id" for its purposes...
115119

116120
user.id = "Their id value"
117-
// boom! overwritten! it did not mean to harm the colleague, but did it!
121+
// Boom! overwritten by another script!
118122
```
119123

120124
### Symbols in a literal

2-ui/3-event-details/4-mouse-drag-and-drop/article.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@ In the modern HTML standard there's a [section about Drag and Drop](https://html
66

77
They are interesting because they allow to solve simple tasks easily, and also allow to handle drag'n'drop of "external" files into the browser. So we can take a file in the OS file-manager and drop it into the browser window. Then JavaScript gains access to its contents.
88

9-
But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be implemented using that API.
9+
But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API.
1010

11-
So here we'll see how to implement Drag'n'Drop using mouse events. Not that hard either.
11+
Here we'll see how to implement Drag'n'Drop using mouse events.
1212

1313
## Drag'n'Drop algorithm
1414

1515
The basic Drag'n'Drop algorithm looks like this:
1616

17-
1. Catch `mousedown` on a draggable element.
18-
2. Prepare the element for moving (maybe create a copy of it or whatever).
19-
3. Then on `mousemove` move it by changing `left/top` and `position:absolute`.
20-
4. On `mouseup` (button release) -- perform all actions related to a finished Drag'n'Drop.
17+
1. On `mousedown` - prepare the element for moving, if needed (maybe create a copy of it).
18+
2. Then on `mousemove` move it by changing `left/top` and `position:absolute`.
19+
3. On `mouseup` - perform all actions related to a finished Drag'n'Drop.
2120

22-
These are the basics. We can extend it, for instance, by highlighting droppable (available for the drop) elements when hovering over them.
21+
These are the basics. Later we can extend it, for instance, by highlighting droppable (available for the drop) elements when hovering over them.
2322

2423
Here's the algorithm for drag'n'drop of a ball:
2524

@@ -32,7 +31,7 @@ ball.onmousedown = function(event) { // (1) start the process
3231
// move it out of any current parents directly into body
3332
// to make it positioned relative to the body
3433
document.body.append(ball);
35-
// ...and put that absolutely positioned ball under the cursor
34+
// ...and put that absolutely positioned ball under the pointer
3635

3736
moveAt(event.pageX, event.pageY);
3837

@@ -65,7 +64,7 @@ Here's an example in action:
6564
6665
[iframe src="ball" height=230]
6766
68-
Try to drag'n'drop the mouse and you'll see the strange behavior.
67+
Try to drag'n'drop the mouse and you'll see such behavior.
6968
```
7069

7170
That's because the browser has its own Drag'n'Drop for images and some other elements that runs automatically and conflicts with ours.
@@ -88,7 +87,7 @@ In action:
8887

8988
Another important aspect -- we track `mousemove` on `document`, not on `ball`. From the first sight it may seem that the mouse is always over the ball, and we can put `mousemove` on it.
9089

91-
But as we remember, `mousemove` triggers often, but not for every pixel. So after swift move the cursor can jump from the ball somewhere in the middle of document (or even outside of the window).
90+
But as we remember, `mousemove` triggers often, but not for every pixel. So after swift move the pointer can jump from the ball somewhere in the middle of document (or even outside of the window).
9291

9392
So we should listen on `document` to catch it.
9493

@@ -101,15 +100,17 @@ ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
101100
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
102101
```
103102

104-
Not bad, but there's a side-effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if do it at the edge, then the ball suddenly "jumps" to become centered.
103+
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.
105104

106105
It would be better if we keep the initial shift of the element relative to the pointer.
107106

108-
For instance, if we start dragging by the edge of the ball, then the cursor should remain over the edge while dragging.
107+
For instance, if we start dragging by the edge of the ball, then the pointer should remain over the edge while dragging.
109108

110109
![](ball_shift.svg)
111110

112-
1. When a visitor presses the button (`mousedown`) -- we can remember the distance from the cursor to the left-upper corner of the ball in variables `shiftX/shiftY`. We should keep that distance while dragging.
111+
Let's update our algorithm:
112+
113+
1. When a visitor presses the button (`mousedown`) - remember the distance from the pointer to the left-upper corner of the ball in variables `shiftX/shiftY`. We'll keep that distance while dragging.
113114

114115
To get these shifts we can substract the coordinates:
115116

@@ -123,7 +124,7 @@ For instance, if we start dragging by the edge of the ball, then the cursor shou
123124

124125
```js
125126
// onmousemove
126-
// ball has position:absoute
127+
// у мяча ball стоит position:absoute
127128
ball.style.left = event.pageX - *!*shiftX*/!* + 'px';
128129
ball.style.top = event.pageY - *!*shiftY*/!* + 'px';
129130
```
@@ -177,25 +178,27 @@ In action (inside `<iframe>`):
177178
[iframe src="ball3" height=230]
178179
```
179180

180-
The difference is especially noticeable if we drag the ball by its right-bottom corner. In the previous example the ball "jumps" under the pointer. Now it fluently follows the cursor from the current position.
181+
The difference is especially noticeable if we drag the ball by its right-bottom corner. In the previous example the ball "jumps" under the pointer. Now it fluently follows the pointer from the current position.
181182

182183
## Potential drop targets (droppables)
183184

184-
In previous examples the ball could be dropped just "anywhere" to stay. In real-life we usually take one element and drop it onto another. For instance, a file into a folder, or a user into a trash can or whatever.
185+
In previous examples the ball could be dropped just "anywhere" to stay. In real-life we usually take one element and drop it onto another. For instance, a "file" into a "folder" or something else.
185186

186-
In other words, we take a "draggable" element and drop it onto "droppable" element.
187+
Speaking abstract, we take a "draggable" element and drop it onto "droppable" element.
187188

188-
We need to know where the element was dropped at the end of Drag'n'Drop -- to do the corresponding action, and, preferably, know the droppable we're dragging over, to highlight it.
189+
We need to know:
190+
- where the element was dropped at the end of Drag'n'Drop -- to do the corresponding action,
191+
- and, preferably, know the droppable we're dragging over, to highlight it.
189192
190193
The solution is kind-of interesting and just a little bit tricky, so let's cover it here.
191194

192-
What may be the first idea? Probably to set `mouseover/mouseup` handlers on potential droppables and detect when the mouse pointer appears over them. And then we know that we are dragging over/dropping on that element.
195+
What may be the first idea? Probably to set `mouseover/mouseup` handlers on potential droppables?
193196

194197
But that doesn't work.
195198
196199
The problem is that, while we're dragging, the draggable element is always above other elements. And mouse events only happen on the top element, not on those below it.
197200

198-
For instance, below are two `<div>` elements, red on top of blue. There's no way to catch an event on the blue one, because the red is on top:
201+
For instance, below are two `<div>` elements, red one on top of the blue one (fully covers). There's no way to catch an event on the blue one, because the red is on top:
199202
200203
```html run autorun height=60
201204
<style>
@@ -218,24 +221,27 @@ So, what to do?
218221
219222
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).
220223

221-
So in any of our mouse event handlers we can detect the potential droppable under the pointer like this:
224+
We can use it in any of our mouse event handlers to detect the potential droppable under the pointer, like this:
222225

223226
```js
224227
// in a mouse event handler
225-
ball.hidden = true; // (*)
228+
ball.hidden = true; // (*) hide the element that we drag
229+
226230
let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
227-
ball.hidden = false;
228231
// elemBelow is the element below the ball, may be droppable
232+
233+
ball.hidden = false;
229234
```
230235

231-
Please note: we need to hide the ball before the call `(*)`. Otherwise we'll usually have a ball on these coordinates, as it's the top element under the pointer: `elemBelow=ball`.
236+
Please note: we need to hide the ball before the call `(*)`. Otherwise we'll usually have a ball on these coordinates, as it's the top element under the pointer: `elemBelow=ball`. So we hide it and immediately show again.
232237

233238
We can use that code to check what element we're "flying over" at any time. And handle the drop when it happens.
234239
235240
An extended code of `onMouseMove` to find "droppable" elements:
236241
237242
```js
238-
let currentDroppable = null; // potential droppable that we're flying over right now
243+
// potential droppable that we're flying over right now
244+
let currentDroppable = null;
239245

240246
function onMouseMove(event) {
241247
moveAt(event.pageX, event.pageY);

0 commit comments

Comments
 (0)