fixes
This commit is contained in:
parent
9a7deaeab9
commit
a17282b510
3 changed files with 23 additions and 21 deletions
|
@ -342,7 +342,7 @@ Just remember: `if (~str.indexOf(...))` reads as "if found".
|
|||
|
||||
Technically speaking, numbers are truncated to 32 bits by `~` operator, so there exist other big numbers that give `0`, the smallest is `~4294967295=0`. That makes such check is correct only if a string is not that long.
|
||||
|
||||
Right now we can see it only in the old code, as modern JavaScript provides `.includes` method (see below).
|
||||
Right now we can see this trick only in the old code, as modern JavaScript provides `.includes` method (see below).
|
||||
|
||||
### includes, startsWith, endsWith
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Drag'n'Drop is a great interface solution. Taking something, dragging and dropping is a clear and simple way to do many things, from copying and moving (see file managers) to ordering (drop into cart).
|
||||
|
||||
In the modern HTML standard there's a [section about Drag Events](https://html.spec.whatwg.org/multipage/interaction.html#dnd).
|
||||
In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend` and so on.
|
||||
|
||||
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.
|
||||
|
||||
|
@ -94,7 +94,7 @@ So we should listen on `document` to catch it.
|
|||
|
||||
## Correct positioning
|
||||
|
||||
In the examples above the ball is always centered 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';
|
||||
|
@ -119,8 +119,6 @@ For instance, if we start dragging by the edge of the ball, then the cursor shou
|
|||
let shiftY = event.clientY - ball.getBoundingClientRect().top;
|
||||
```
|
||||
|
||||
Please note that there's no method to get document-relative coordinates in JavaScript, so we use window-relative coordinates here.
|
||||
|
||||
2. Then while dragging we position the ball on the same shift relative to the pointer, like this:
|
||||
|
||||
```js
|
||||
|
@ -146,7 +144,8 @@ ball.onmousedown = function(event) {
|
|||
|
||||
moveAt(event.pageX, event.pageY);
|
||||
|
||||
// centers the ball at (pageX, pageY) coordinates
|
||||
// moves the ball at (pageX, pageY) coordinates
|
||||
// taking initial shifts into account
|
||||
function moveAt(pageX, pageY) {
|
||||
ball.style.left = pageX - *!*shiftX*/!* + 'px';
|
||||
ball.style.top = pageY - *!*shiftY*/!* + 'px';
|
||||
|
@ -180,17 +179,17 @@ In action (inside `<iframe>`):
|
|||
|
||||
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.
|
||||
|
||||
## Detecting droppables
|
||||
## Potential drop targets (droppables)
|
||||
|
||||
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.
|
||||
|
||||
In other words, we take a "draggable" element and drop it onto "droppable" element.
|
||||
|
||||
We need to know the target droppable at the end of Drag'n'Drop -- to do the corresponding action, and, preferably, during the dragging process, to highlight it.
|
||||
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.
|
||||
|
||||
The solution is kind-of interesting and just a little bit tricky, so let's cover it here.
|
||||
|
||||
What's the first idea? Probably to put `onmouseover/mouseup` handlers on potential droppables and detect when the mouse pointer appears over them. And then we know that we are dragging/dropping on that element.
|
||||
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.
|
||||
|
||||
But that doesn't work.
|
||||
|
||||
|
@ -217,7 +216,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 coordinates are out of the window).
|
||||
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).
|
||||
|
||||
So in any of our mouse event handlers we can detect the potential droppable under the pointer like this:
|
||||
|
||||
|
@ -226,12 +225,12 @@ So in any of our mouse event handlers we can detect the potential droppable unde
|
|||
ball.hidden = true; // (*)
|
||||
let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
|
||||
ball.hidden = false;
|
||||
// elemBelow is the element below the ball. If it's droppable, we can handle it.
|
||||
// elemBelow is the element below the ball, may be droppable
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
We can use that code to check what we're "flying over" at any time. And handle the drop when it happens.
|
||||
We can use that code to check what element we're "flying over" at any time. And handle the drop when it happens.
|
||||
|
||||
An extended code of `onMouseMove` to find "droppable" elements:
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ We leave it as an exercise for the reader. Also, at the end of the chapter you'l
|
|||
|
||||
## Writing to document.cookie
|
||||
|
||||
We can write to `document.cookie`. But it's not a data property, it's an accessor.
|
||||
We can write to `document.cookie`. But it's not a data property, it's an accessor. An assignment to it is treated specially.
|
||||
|
||||
**A write operation to `document.cookie` passes through the browser that updates cookies mentioned in it, but doesn't touch other cookies.**
|
||||
|
||||
|
@ -84,11 +84,11 @@ document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
|
|||
|
||||
- **`path=/mypath`**
|
||||
|
||||
The url path prefix, where the cookie is accessible. Must be absolute. By default, it's the current path.
|
||||
The url path prefix, the cookie will be accessible for pages under that path. Must be absolute. By default, it's the current path.
|
||||
|
||||
If a cookie is set with `path=/admin`, it's visible at pages `/admin` and `/admin/something`, but not at `/home` or `/adminpage`.
|
||||
|
||||
Usually, we set `path=/` to make the cookie accessible from all website pages.
|
||||
Usually, we should set `path` to the root: `path=/` to make the cookie accessible from all website pages.
|
||||
|
||||
## domain
|
||||
|
||||
|
@ -110,19 +110,22 @@ alert(document.cookie); // no user
|
|||
|
||||
**There's no way to let a cookie be accessible from another 2nd-level domain, so `other.com` will never receive a cookie set at `site.com`.**
|
||||
|
||||
It's a safety restriction, to allow us to store sensitive data in cookies.
|
||||
It's a safety restriction, to allow us to store sensitive data in cookies, that should be available only on one site.
|
||||
|
||||
...But if we'd like to grant access to subdomains like `forum.site.com`, that's possible. We should explicitly set `domain` option to the root domain: `domain=site.com`:
|
||||
...But if we'd like to allow subdomains like `forum.site.com` get a cookie, that's possible. When setting a cookie at `site.com`, we should explicitly set `domain` option to the root domain: `domain=site.com`:
|
||||
|
||||
```js
|
||||
// at site.com, make the cookie accessible on any subdomain:
|
||||
// at site.com
|
||||
// make the cookie accessible on any subdomain *.site.com:
|
||||
document.cookie = "user=John; domain=site.com"
|
||||
|
||||
// later
|
||||
|
||||
// at forum.site.com
|
||||
alert(document.cookie); // with user
|
||||
alert(document.cookie); // has cookie user=John
|
||||
```
|
||||
|
||||
For historical reasons, `domain=.site.com` (a dot at the start) also works this way, it might better to add the dot to support very old browsers.
|
||||
For historical reasons, `domain=.site.com` (a dot before `site.com`) also works the same way, allowing access to the cookie from subdomains. That's an old notation, should be used if we need to support very old browsers.
|
||||
|
||||
So, `domain` option allows to make a cookie accessible at subdomains.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue