Merge branch 'master' into patch-1

This commit is contained in:
Ilya Kantor 2018-12-24 12:40:16 +03:00 committed by GitHub
commit 744f3fc9b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 44 additions and 40 deletions

View file

@ -1,14 +1,14 @@
# Developer console
Code is prone to errors. You are quite likely to make errors... Oh, what am I talking about? You are *absolutely* going to make errors, at least if you're a human, not a [robot](https://en.wikipedia.org/wiki/Bender_(Futurama)).
Code is prone to errors. You will quite likely make errors... Oh, what am I talking about? You are *absolutely* going to make errors, at least if you're a human, not a [robot](https://en.wikipedia.org/wiki/Bender_(Futurama)).
But in the browser, a user doesn't see the errors by default. So, if something goes wrong in the script, we won't see what's broken and can't fix it.
But in the browser, users doesn't see errors by default. So, if something goes wrong in the script, we won't see what's broken and can't fix it.
To see errors and get a lot of other useful information about scripts, "developer tools" have been embedded in browsers.
Most often developers lean towards Chrome or Firefox for development because those browsers have the best developer tools. Other browsers also provide developer tools, sometimes with special features, but are usually playing "catch-up" to Chrome or Firefox. So most people have a "favorite" browser and switch to others if a problem is browser-specific.
Most developers lean towards Chrome or Firefox for development because those browsers have the best developer tools. Other browsers also provide developer tools, sometimes with special features, but are usually playing "catch-up" to Chrome or Firefox. So most developers have a "favorite" browser and switch to others if a problem is browser-specific.
Developer tools are potent; there are many features. To start, we'll learn how to open them, look at errors and run JavaScript commands.
Developer tools are potent; they have many features. To start, we'll learn how to open them, look at errors, and run JavaScript commands.
## Google Chrome
@ -31,20 +31,20 @@ The exact look of developer tools depends on your version of Chrome. It changes
Below the error message, there is a blue `>` symbol. It marks a "command line" where we can type JavaScript commands. Press `key:Enter` to run them (`key:Shift+Enter` to input multi-line commands).
Now we can see errors, and that's enough for a start. We'll be back to developer tools later and cover debugging more in-depth in the chapter <info:debugging-chrome>.
Now we can see errors, and that's enough for a start. We'll come back to developer tools later and cover debugging more in-depth in the chapter <info:debugging-chrome>.
## Firefox, Edge, and others
Most other browsers use `key:F12` to open developer tools.
The look & feel of them is quite similar. Once you know how to use one of those tools (you can start with Chrome), you can easily switch to another.
The look & feel of them is quite similar. Once you know how to use one of these tools (you can start with Chrome), you can easily switch to another.
## Safari
Safari (Mac browser, not supported by Windows/Linux) is a little bit special here. We need to enable the "Develop menu" first.
Open Preferences and go to "Advanced" pane. There's a checkbox at the bottom:
Open Preferences and go to the "Advanced" pane. There's a checkbox at the bottom:
![safari](safari.png)
@ -52,7 +52,7 @@ Now `key:Cmd+Opt+C` can toggle the console. Also, note that the new top menu ite
## Summary
- Developer tools allow us to see errors, run commands, examine variables and much more.
- They can be opened with `key:F12` for most browsers under Windows. Chrome for Mac needs `key:Cmd+Opt+J`, Safari: `key:Cmd+Opt+C` (need to enable first).
- Developer tools allow us to see errors, run commands, examine variables, and much more.
- They can be opened with `key:F12` for most browsers on Windows. Chrome for Mac needs `key:Cmd+Opt+J`, Safari: `key:Cmd+Opt+C` (need to enable first).
Now we have the environment ready. In the next section, we'll get down to JavaScript.

View file

@ -205,7 +205,7 @@ function showMessage(from, text = anotherFunction()) {
```
```smart header="Evaluation of default parameters"
In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. In the example above, `anotherFunctions()` is called everytime `someMessage()` is called without the `text` parameter. This is in contrast to some other languages like Python, where any default parameters are evaluated only once during the initial interpretation.
In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. In the example above, `anotherFunction()` is called everytime `someMessage()` is called without the `text` parameter. This is in contrast to some other languages like Python, where any default parameters are evaluated only once during the initial interpretation.
```

View file

@ -56,7 +56,7 @@ A *breakpoint* is a point of code where the debugger will automatically pause th
While the code is paused, we can examine current variables, execute commands in the console etc. In other words, we can debug it.
We can always find a list of breakpoints in the right pane. That's useful when we have many breakpoints in various files. It allows to:
We can always find a list of breakpoints in the right pane. That's useful when we have many breakpoints in various files. It allows us to:
- Quickly jump to the breakpoint in the code (by clicking on it in the right pane).
- Temporarily disable the breakpoint by unchecking it.
- Remove the breakpoint by right-clicking and selecting Remove.

View file

@ -233,7 +233,7 @@ Grouping is done with a nested `describe`:
describe("pow", function() {
*!*
describe("raises x to power n", function() {
describe("raises x to power 3", function() {
*/!*
function makeTest(x) {

View file

@ -1,6 +1,6 @@
describe("pow", function() {
describe("raises x to power n", function() {
describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;

View file

@ -1,6 +1,6 @@
describe("pow", function() {
describe("raises x to power n", function() {
describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;

View file

@ -1,6 +1,6 @@
describe("pow", function() {
describe("raises x to power n", function() {
describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;

View file

@ -1 +1,5 @@
```js run
function extractCurrencyValue(str) {
return +str.slice(1);
}
```

View file

@ -1,6 +1,6 @@
```js run no-beautify
function sortByName(arr) {
arr.sort((a, b) => a.name > b.name);
arr.sort((a, b) => b.name > a.name ? 1 : -1);
}
let john = { name: "John", age: 25 };

View file

@ -329,7 +329,7 @@ It calls the function for each element of the array and returns the array of res
For instance, here we transform each element into its length:
```js run
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length)
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
```

View file

@ -45,7 +45,7 @@ let user = {
};
```
- `Object.keys(user) = [name, age]`
- `Object.keys(user) = ["name", "age"]`
- `Object.values(user) = ["John", 30]`
- `Object.entries(user) = [ ["name","John"], ["age",30] ]`

View file

@ -2,7 +2,7 @@
Let's meet a new built-in object: [Date](mdn:js/Date). It stores the date, time and provides methods for date/time management.
For instance, we can use it to store creation/modification times, or to measure time, or just to print out the current date.
For instance, we can use it to store creation/modification times, to measure time, or just to print out the current date.
## Creation
@ -108,7 +108,7 @@ alert( date.getHours() );
alert( date.getUTCHours() );
```
Besides the given methods, there are two special ones, that do not have a UTC-variant:
Besides the given methods, there are two special ones that do not have a UTC-variant:
[getTime()](mdn:js/Date/getTime)
: Returns the timestamp for the date -- a number of milliseconds passed from the January 1st of 1970 UTC+0.

View file

@ -62,7 +62,7 @@ showName("Julius", "Caesar", "Consul", "Imperator");
```
````warn header="The rest parameters must be at the end"
The rest parameters gather all remaining arguments, so the following has no sense:
The rest parameters gather all remaining arguments, so the following does not make sense and causes an error:
```js
function f(arg1, ...rest, arg2) { // arg2 after ...rest ?!

View file

@ -475,7 +475,7 @@ They look like this:
Here a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
The Function Expression is wrapped with brackets `(function {...})`, because when JavaScript meets `"function"` in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so there will be an error:
The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript meets `"function"` in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so there will be an error:
```js run
// Error: Unexpected token (
@ -497,7 +497,7 @@ function go() {
}(); // <-- can't call Function Declaration immediately
```
So, round brackets are needed to show JavaScript that the function is created in the context of another expression, and hence it's a Function Expression. It needs no name and can be called immediately.
So, parenthesis are needed to show JavaScript that the function is created in the context of another expression, and hence it's a Function Expression. It needs no name and can be called immediately.
There are other ways to tell JavaScript that we mean Function Expression:

View file

@ -8,7 +8,7 @@ Modify the code of `makeCounter()` so that the counter can also decrease and set
- `counter()` should return the next number (as before).
- `counter.set(value)` should set the `count` to `value`.
- `counter.decrease(value)` should decrease the `count` by 1.
- `counter.decrease()` should decrease the `count` by 1.
See the sandbox code for the complete usage example.

View file

@ -27,4 +27,4 @@ for (let args of work.calls) {
}
```
P.S. That decorator is sometimes useful for unit-testing, it's advanced form is `sinon.spy` in [Sinon.JS](http://sinonjs.org/) library.
P.S. That decorator is sometimes useful for unit-testing. Its advanced form is `sinon.spy` in [Sinon.JS](http://sinonjs.org/) library.

View file

@ -33,7 +33,7 @@ We have `event.clientX/clientY` -- window-relative coordinates of the click.
To get field-relative `left` coordinate of the click, we can substract the field left edge and the border width:
```js
let left = event.clientX - fieldInnerCoords.left - field.clientLeft;
let left = event.clientX - fieldCoords.left - field.clientLeft;
```
Normally, `ball.style.position.left` means the "left edge of the element" (the ball). So if we assign that `left`, then the ball edge would be under the mouse cursor.
@ -43,7 +43,7 @@ We need to move the ball half-width left and half-height up to make it center.
So the final `left` would be:
```js
let left = event.clientX - fieldInnerCoords.left - field.clientLeft - ball.offsetWidth/2;
let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;
```
The vertical coordinate is calculated using the same logic.

View file

@ -2,9 +2,9 @@
# HTML/CSS
First let's create HTML/CSS.
A menu is a standalone graphical component on the page, so its better to put it into a single DOM element.
A menu is a standalone graphical component on the page, so it's better to put it into a single DOM element.
A list of menu items can be layed out as a list `ul/li`.
A list of menu items can be laid out as a list `ul/li`.
Here's the example structure:

View file

@ -2,7 +2,7 @@ importance: 5
---
# Create a menu sliding menu
# Create a sliding menu
Create a menu that opens/collapses on click:

View file

@ -4,7 +4,7 @@ importance: 4
# Load images with a callback
Normally, images are loaded when they are created. So i when we add `<img>` to the page, the user does not see the picture immediately. The browser needs to load it first.
Normally, images are loaded when they are created. So when we add `<img>` to the page, the user does not see the picture immediately. The browser needs to load it first.
To show an image immediately, we can create it "in advance", like this:

View file

@ -96,7 +96,7 @@ Try entering the blue element and then moving the mouse on the red one -- and wa
So, for a handler that does not take `target` into account, it looks like we left the parent in `mouseout` in `(2)` and returned back to it by `mouseover` in `(3)`.
If we perform some actions on entering/leaving the element, then we'll get a lot of extra "false" runs. For simple stuff may be unnoticeable. For complex things that may bring unwanted side-effects.
If we perform some actions on entering/leaving the element, then we'll get a lot of extra "false" runs. For simple stuff that may be unnoticeable. For complex things that may bring unwanted side-effects.
We can fix it by using `mouseenter/mouseleave` events instead.

View file

@ -15,7 +15,7 @@ So here we'll see how to implement Drag'n'Drop using mouse events. Not that hard
The basic Drag'n'Drop algorithm looks like this:
1. Catch `mousedown` on a draggable element.
2. Prepare the element to moving (maybe create a copy of it or whatever).
2. Prepare the element for moving (maybe create a copy of it or whatever).
3. Then on `mousemove` move it by changing `left/top` and `position:absolute`.
4. On `mouseup` (button release) -- perform all actions related to a finished Drag'n'Drop.
@ -58,7 +58,7 @@ ball.onmousedown = function(event) { // (1) start the process
};
```
If we run the code, we can notice something strange. On the beginning of the drag'n'drop, the ball "forks": we start to dragging it's "clone".
If we run the code, we can notice something strange. On the beginning of the drag'n'drop, the ball "forks": we start dragging its "clone".
```online
Here's an example in action:
@ -178,7 +178,7 @@ In action (inside `<iframe>`):
[iframe src="ball3" height=230]
```
The difference is especially noticeable if we drag the ball by it's right-bottom corner. In the previous example the ball "jumps" under the pointer. Now it fluently follows the cursor from the current position.
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

View file

@ -49,7 +49,7 @@ Your email please: <input type="email" id="input">
</script>
```
Modern HTML allows to do many validations using input attributes: `required`, `pattern` and so on. And sometimes they are just what we need. JavaScript can be used when we want more flexibility. Also we could automatically send the changed value on the server if it's correct.
Modern HTML allows to do many validations using input attributes: `required`, `pattern` and so on. And sometimes they are just what we need. JavaScript can be used when we want more flexibility. Also we could automatically send the changed value to the server if it's correct.
## Methods focus/blur
@ -100,7 +100,7 @@ One of them is when the visitor clicks somewhere else. But also JavaScript itsel
These features sometimes cause `focus/blur` handlers to misbehave -- to trigger when they are not needed.
The best recipe is to be careful when using these events. If we want to track user-initiated focus-loss, then we should evade causing it by ourselves.
The best recipe is to be careful when using these events. If we want to track user-initiated focus-loss, then we should avoid causing it ourselves.
```
## Allow focusing on any element: tabindex

View file

@ -6,7 +6,7 @@ Let's discuss various events that accompany data updates.
The [change](http://www.w3.org/TR/html5/forms.html#event-input-change) event triggers when the element has finished changing.
For text inputs that means that the event occurs when it looses focus.
For text inputs that means that the event occurs when it loses focus.
For instance, while we are typing in the text field below -- there's no event. But when we move the focus somewhere else, for instance, click on a button -- there will be a `change` event:
@ -62,7 +62,7 @@ For instance, the code below prevents all such events and shows what we are tryi
</script>
```
Technically, we can copy/paste everything. For instance, we can copy and file in the OS file manager, and paste it.
Technically, we can copy/paste everything. For instance, we can copy a file in the OS file manager, and paste it.
There's a list of methods [in the specification](https://www.w3.org/TR/clipboard-apis/#dfn-datatransfer) to work with different data types, read/write to the clipboard.