This commit is contained in:
Ilya Kantor 2019-08-18 09:44:30 +03:00
parent 28cc5c82c0
commit 5d1037cbd0
5 changed files with 15 additions and 14 deletions

View file

@ -52,7 +52,7 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string
That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another. That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another.
If we really want to show a symbol, we need to call `.toString()` on it, like here: If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here:
```js run ```js run
let id = Symbol("id"); let id = Symbol("id");
*!* *!*
@ -60,7 +60,7 @@ alert(id.toString()); // Symbol(id), now it works
*/!* */!*
``` ```
Or get `symbol.description` property to get the description only: Or get `symbol.description` property to show the description only:
```js run ```js run
let id = Symbol("id"); let id = Symbol("id");
*!* *!*
@ -133,7 +133,7 @@ let id = Symbol("id");
let user = { let user = {
name: "John", name: "John",
*!* *!*
[id]: 123 // not just "id: 123" [id]: 123 // not "id: 123"
*/!* */!*
}; };
``` ```

View file

@ -1,4 +1,5 @@
As we can see from HTML/CSS, the slider is a `<div>` with a colored background, that contains a runner -- another `<div>` with `position:relative`.
We have a horizontal Drag'n'Drop here. To position the runner we use `position:relative`, to provide the coordinates relative to its parent, here it's more convenient here than `position:absolute`.
To position the element we use `position:relative` and slider-relative coordinates for the thumb. Here it's more convenient here than `position:absolute`. Then we implement horizontal-only Drag'n'Drop with limitation by width.

View file

@ -1,5 +1,5 @@
To drag the element we can use `position:fixed`, it makes coordinates easier to manage. At the end we should switch it back to `position:absolute`. To drag the element we can use `position:fixed`, it makes coordinates easier to manage. At the end we should switch it back to `position:absolute` to lay the element into the document.
Then, when coordinates are at window top/bottom, we use `window.scrollTo` to scroll it. When coordinates are at window top/bottom, we use `window.scrollTo` to scroll it.
More details in the code, in comments. More details in the code, in comments.

View file

@ -12,8 +12,8 @@ Requirements:
- Use event delegation to track drag start: a single event handler on `document` for `mousedown`. - Use event delegation to track drag start: a single event handler on `document` for `mousedown`.
- If elements are dragged to top/bottom window edges -- the page scrolls up/down to allow further dragging. - If elements are dragged to top/bottom window edges -- the page scrolls up/down to allow further dragging.
- There is no horizontal scroll. - There is no horizontal scroll (this makes the task a bit simpler, adding it is easy).
- Draggable elements should never leave the window, even after swift mouse moves. - Draggable elements or their parts should never leave the window, even after swift mouse moves.
The demo is too big to fit it here, so here's the link. The demo is too big to fit it here, so here's the link.

View file

@ -241,7 +241,7 @@ An extended code of `onMouseMove` to find "droppable" elements:
```js ```js
// potential droppable that we're flying over right now // potential droppable that we're flying over right now
let currentDroppable = null; let currentDroppable = null;
function onMouseMove(event) { function onMouseMove(event) {
moveAt(event.pageX, event.pageY); moveAt(event.pageX, event.pageY);
@ -251,13 +251,13 @@ function onMouseMove(event) {
ball.hidden = false; ball.hidden = false;
// mousemove events may trigger out of the window (when the ball is dragged off-screen) // mousemove events may trigger out of the window (when the ball is dragged off-screen)
// if clientX/clientY are out of the window, then elementfromPoint returns null // if clientX/clientY are out of the window, then elementFromPoint returns null
if (!elemBelow) return; if (!elemBelow) return;
// potential droppables are labeled with the class "droppable" (can be other logic) // potential droppables are labeled with the class "droppable" (can be other logic)
let droppableBelow = elemBelow.closest('.droppable'); let droppableBelow = elemBelow.closest('.droppable');
if (currentDroppable != droppableBelow) { // if there are any changes if (currentDroppable != droppableBelow) {
// we're flying in or out... // we're flying in or out...
// note: both values can be null // note: both values can be null
// currentDroppable=null if we were not over a droppable before this event (e.g over an empty space) // currentDroppable=null if we were not over a droppable before this event (e.g over an empty space)
@ -288,13 +288,13 @@ We considered a basic Drag'n'Drop algorithm.
The key components: The key components:
1. Events flow: `ball.mousedown` -> `document.mousemove` -> `ball.mouseup` (cancel native `ondragstart`). 1. Events flow: `ball.mousedown` -> `document.mousemove` -> `ball.mouseup` (don't forget to cancel native `ondragstart`).
2. At the drag start -- remember the initial shift of the pointer relative to the element: `shiftX/shiftY` and keep it during the dragging. 2. At the drag start -- remember the initial shift of the pointer relative to the element: `shiftX/shiftY` and keep it during the dragging.
3. Detect droppable elements under the pointer using `document.elementFromPoint`. 3. Detect droppable elements under the pointer using `document.elementFromPoint`.
We can lay a lot on this foundation. We can lay a lot on this foundation.
- On `mouseup` we can finalize the drop: change data, move elements around. - On `mouseup` we can intellectually finalize the drop: change data, move elements around.
- We can highlight the elements we're flying over. - We can highlight the elements we're flying over.
- We can limit dragging by a certain area or direction. - We can limit dragging by a certain area or direction.
- We can use event delegation for `mousedown/up`. A large-area event handler that checks `event.target` can manage Drag'n'Drop for hundreds of elements. - We can use event delegation for `mousedown/up`. A large-area event handler that checks `event.target` can manage Drag'n'Drop for hundreds of elements.