From caede8fe18c1d0d1f4543936e3ddb753421097c5 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 25 Feb 2017 19:53:02 +0300 Subject: [PATCH] up --- .../1-get-scroll-height-bottom/solution.md | 6 ++- .../1-get-scroll-height-bottom/task.md | 8 +-- .../2-scrollbar-width/solution.md | 22 ++++---- .../2-scrollbar-width/task.md | 8 +-- .../3-div-placeholder/solution.md | 29 ----------- .../solution.view/index.html | 50 ------------------- .../3-div-placeholder/source.view/index.html | 37 -------------- .../3-div-placeholder/task.md | 50 ------------------- .../4-put-ball-in-center/solution.md | 33 ++++++------ .../4-put-ball-in-center/task.md | 17 +++---- 2-ui/1-document/15-size-and-scroll/article.md | 34 ++++++------- .../cssWidthScroll.view/index.html | 20 ++------ 12 files changed, 70 insertions(+), 244 deletions(-) delete mode 100644 2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.md delete mode 100755 2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.view/index.html delete mode 100755 2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html delete mode 100644 2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md diff --git a/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/solution.md b/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/solution.md index 4d84cf8f..f6971382 100644 --- a/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/solution.md +++ b/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/solution.md @@ -1 +1,5 @@ -Решение: `elem.scrollHeight - elem.scrollTop - elem.clientHeight`. \ No newline at end of file +The solution is: + +```js +let scrollBottom = elem.scrollHeight - elem.scrollTop - elem.clientHeight; +``` diff --git a/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/task.md b/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/task.md index 3dcecb38..b0f1f221 100644 --- a/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/task.md +++ b/2-ui/1-document/15-size-and-scroll/1-get-scroll-height-bottom/task.md @@ -2,10 +2,10 @@ importance: 5 --- -# Найти размер прокрутки снизу +# What's the scroll from the bottom? -Свойство `elem.scrollTop` содержит размер прокрученной области при отсчете сверху. А как подсчитать размер прокрутки снизу? +The `elem.scrollTop` property is the size of the scrolled out part from the top. How to get "`scrollBottom`" -- the size from the bottom? -Напишите соответствующее выражение для произвольного элемента `elem`. +Write the code that works for an arbitrary `elem`. -Проверьте: если прокрутки нет вообще или элемент полностью прокручен -- оно должно давать ноль. \ No newline at end of file +P.S. Please check your code: if there's no scroll or the element is fully scrolled down, then it should return `0`. diff --git a/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/solution.md b/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/solution.md index f675783d..1ba1e5e5 100644 --- a/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/solution.md +++ b/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/solution.md @@ -1,22 +1,20 @@ -Создадим элемент с прокруткой, но без `border` и `padding`. Тогда разница между его полной шириной `offsetWidth` и внутренней `clientWidth` будет равна как раз прокрутке: +To get the scrollbar width, we can create an element with the scroll, but without borders and paddings. + +Then the difference between its full width `offsetWidth` and the inner content area width `clientWidth` will be exactly the scrollbar: ```js run -// создадим элемент с прокруткой -var div = document.createElement('div'); +// create a div with the scroll +let div = document.createElement('div'); div.style.overflowY = 'scroll'; div.style.width = '50px'; div.style.height = '50px'; -// при display:none размеры нельзя узнать -// нужно, чтобы элемент был видим, -// visibility:hidden - можно, т.к. сохраняет геометрию -div.style.visibility = 'hidden'; +// must put it in the document, otherwise sizes will be 0 +document.body.append(div); +let scrollWidth = div.offsetWidth - div.clientWidth; -document.body.appendChild(div); -var scrollWidth = div.offsetWidth - div.clientWidth; -document.body.removeChild(div); +div.remove(); -alert( scrollWidth ); +alert(scrollWidth); ``` - diff --git a/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/task.md b/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/task.md index 4bd47896..392404c8 100644 --- a/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/task.md +++ b/2-ui/1-document/15-size-and-scroll/2-scrollbar-width/task.md @@ -2,8 +2,10 @@ importance: 3 --- -# Узнать ширину полосы прокрутки +# What is the scrollbar width? -Напишите код, который возвращает ширину стандартной полосы прокрутки. Именно самой полосы, где ползунок. Обычно она равна `16px`, в редких и мобильных браузерах может колебаться от `14px` до `18px`, а кое-где даже равна `0px`. +Write the code that returns the width of a standard scrollbar. -P.S. Ваш код должен работать на любом HTML-документе, независимо от его содержимого. \ No newline at end of file +For Windows it usually varies between `12px` and `20px`, but if the browser reserves no space for it, then it may be `0px`. + +P.S. The code should work in any HTML document, do not depend on its content. diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.md b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.md deleted file mode 100644 index 9e6fe838..00000000 --- a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.md +++ /dev/null @@ -1,29 +0,0 @@ -Нам нужно создать `div` с такими же размерами и вставить его на место "переезжающего". - -Один из вариантов -- это просто клонировать элемент. - -Если делать это при помощи `div.cloneNode(true)`, то склонируется все содержимое, которого может быть много. Обычно нам это не нужно, поэтому можно использовать `div.cloneNode(false)` для клонирования элемента со стилями, и потом поправить его `width/height`. - -Можно и просто создать новый `div` и поставить ему нужные размеры. - -**Всё, кроме `margin`, можно получить из свойств DOM-элемента, а `margin` -- только через `getComputedStyle`.** - -Причём `margin` мы обязаны поставить, так как иначе наш элемент при вставке будет вести себя иначе, чем исходный. - -Код: - -```js -var div = document.getElementById('moving-div'); - -var placeHolder = document.createElement('div'); -placeHolder.style.height = div.offsetHeight + 'px'; -// можно и width, но в этом примере это не обязательно - -// IE || другой браузер -var computedStyle = div.currentStyle || getComputedStyle(div, ''); - -placeHolder.style.marginTop = computedStyle.marginTop; // (1) -placeHolder.style.marginBottom = computedStyle.marginBottom; -``` - -В строке `(1)` использование полного название свойства `"marginTop"` гарантирует, что полученное значение будет корректным. \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.view/index.html b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.view/index.html deleted file mode 100755 index fd8f91f0..00000000 --- a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/solution.view/index.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - Before Before Before - -
- Text Text Text -
Text Text Text -
-
- - After After After - - - - - - - \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html deleted file mode 100755 index 69e3e504..00000000 --- a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/source.view/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - Before Before Before - -
- Text Text Text -
Text Text Text -
-
- - After After After - - - - - - \ No newline at end of file diff --git a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md b/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md deleted file mode 100644 index 23861dd6..00000000 --- a/2-ui/1-document/15-size-and-scroll/3-div-placeholder/task.md +++ /dev/null @@ -1,50 +0,0 @@ -importance: 3 - ---- - -# Подменить div на другой с таким же размером - -Посмотрим следующий случай из жизни. Был текст, который, в частности, содержал `div` с зелеными границами: - -```html run no-beautify - - -Before Before Before - -
-Text Text Text
-Text Text Text
-
- -After After After -``` - -Программист Валера из вашей команды написал код, который позиционирует его абсолютно и смещает в правый верхний угол. Вот этот код: - -```js -var div = document.getElementById('moving-div'); -div.style.position = 'absolute'; -div.style.right = div.style.top = 0; -``` - -Побочным результатом явилось смещение текста, который раньше шел после `DIV`. Теперь он поднялся вверх: - -[iframe height=90 src="source"] - -**Допишите код Валеры, сделав так, чтобы текст оставался на своем месте после того, как `DIV` будет смещен.** - -Сделайте это путем создания вспомогательного `DIV` с теми же `width`, `height`, `border`, `margin`, `padding`, что и у желтого `DIV`. - -Используйте только JavaScript, без CSS. - -Должно быть так (новому блоку задан фоновый цвет для демонстрации): - -[iframe height=140 src="solution"] - diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md index 10b1219e..b09c9340 100644 --- a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/solution.md @@ -1,42 +1,42 @@ -При абсолютном позиционировании мяча внутри поля его координаты `left/top` отсчитываются от **внутреннего** угла поля, например верхнего-левого: +The ball has `position:absolute`. It means that its `left/top` coordinates are measured from the nearest positioned element, that is `#field` (because it has `position:relative`). + +The coordinates start from the inner left-upper corner of the field: ![](field.png) -Метрики для внутренней зоны поля -- это `clientWidth/Height`. +The inner field width/height is `clientWidth/clientHeight`. So the field center has coordinates `(clientWidth/2, clientHeight/2)`. -Центр - это `(clientWidth/2, clientHeight/2)`. - -Но если мы установим мячу такие значения `ball.style.left/top`, то в центре будет не сам мяч, а его левый верхний угол: +...But if we set such values to `ball.style.left/top`, then not the ball as a whole, but the left-upper edge of the ball is in the center: ```js -var ball = document.getElementById('ball'); -var field = document.getElementById('field'); - ball.style.left = Math.round(field.clientWidth / 2) + 'px'; ball.style.top = Math.round(field.clientHeight / 2) + 'px'; ``` -[iframe hide="Нажмите, чтобы посмотреть текущий результат" height=180 src="ball-half"] +Here's how it looks: -Для того, чтобы центр мяча находился в центре поля, нам нужно сместить мяч на половину его ширины влево и на половину его высоты вверх. +[iframe height=180 src="ball-half"] + +To align the ball center with the center of the field, we should move the ball to the half of its width to the left and to the half of its height to the top: ```js -var ball = document.getElementById('ball'); -var field = document.getElementById('field'); - ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px'; ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px'; ``` -**Внимание, подводный камень!** +**Attention: the pitfall!** -Код выше стабильно работать не будет, потому что `IMG` идет без ширины/высоты: +The code won't work reliably while `` width/height is not given to the browser: ```html ``` -**Высота и ширина изображения неизвестны браузеру до тех пор, пока оно не загрузится, если размер не указан явно.** +When the browser meets such a tag, it tries to figure out its width/height. Either from the `` attributes or (if not given) from CSS. + +If none is given, then the sizes are assumed to be `0` until the image loads. + +TODO После первой загрузки изображение уже будет в кеше браузера, и его размеры будут известны. Но когда браузер впервые видит документ -- он ничего не знает о картинке, поэтому значение `ball.offsetWidth` равно `0`. Вычислить координаты невозможно. @@ -47,4 +47,3 @@ ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'p ``` Теперь браузер всегда знает ширину и высоту, так что все работает. Тот же эффект дало бы указание размеров в CSS. - diff --git a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md index 2ccca698..57746d92 100644 --- a/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md +++ b/2-ui/1-document/15-size-and-scroll/4-put-ball-in-center/task.md @@ -2,20 +2,19 @@ importance: 5 --- -# Поместите мяч в центр поля +# Place the ball in the field center -Поместите мяч в центр поля. - -Исходный документ выглядит так: +Here's how the source document looks: [iframe src="source" edit link height=180] -**Используйте JavaScript, чтобы поместить мяч в центр:** +What are coordinates of the field center? + +Calculate them and use to place the ball into the center of the field: [iframe src="solution" height=180] -- Менять CSS нельзя, мяч должен переносить в центр ваш скрипт, через установку нужных стилей элемента. -- JavaScript-код должен работать при разных размерах мяча (`10`, `20`, `30` пикселей) без изменений. -- JavaScript-код должен работать при различных размерах и местоположениях поля на странице без изменений. Также он не должен зависеть от ширины рамки поля `border`. +- The element should be moved by JavaScript, not CSS. +- The code should work with any ball size (`10`, `20`, `30` pixels) and any field size, not be bound to the given values. -P.S. Да, центрирование можно сделать при помощи чистого CSS, но задача именно на JavaScript. Далее будут другие темы и более сложные ситуации, когда JavaScript будет уже точно необходим, это -- своего рода "разминка". +P.S. Sure, centering could be done with CSS, but here we want exactly JavaScript. Further we'll meet other topics and more complex situations when JavaScript must be used. Here we do a "warm-up". diff --git a/2-ui/1-document/15-size-and-scroll/article.md b/2-ui/1-document/15-size-and-scroll/article.md index a3dca58f..d75c0cba 100644 --- a/2-ui/1-document/15-size-and-scroll/article.md +++ b/2-ui/1-document/15-size-and-scroll/article.md @@ -3,7 +3,7 @@ To show elements at arbitrary places in the page we should: 1. First, know CSS positioning. -2. Second, know how to handle "geometrical" properties in Javascript. +2. Second, know how to handle "geometry" properties in Javascript. [cut] @@ -204,6 +204,8 @@ If you click the element below, the code `elem.scrollTop += 10` executes. That m
Click
Me
1
2
3
4
5
6
7
8
9
``` + +Setting `scrollTop` to `0` or `Infinity` will make the element scroll to the top/bottom respectively. ```` ## Don't take width/height from CSS @@ -246,29 +248,27 @@ As we've seen a scrollbar takes the space from the content in some browsers. So ...But some browsers also take that into account in `getComputedStyle(elem).width`. That is: some of them return real inner width and some of them -- CSS width. Such cross-browser differences is a reason not to use `getComputedStyle`, but rather rely on geometry propeties. ```online -Если ваш браузер показывает полосу прокрутки (например, под Windows почти все браузеры так делают), то вы можете протестировать это сами, нажав на кнопку в ифрейме ниже. +If your browser reserves the space for a scrollbar (most browsers for Windows do), then you can test it below. [iframe src="cssWidthScroll" link border=1] -У элемента с текстом в стилях указано `width:300px`. +The element with text has CSS `width:300px`. -На момент написания этой главы при тестировании в Chrome под Windows `alert` выводил `283px`, а в Firefox -- `300px`. При этом оба браузера показывали прокрутку. Это из-за того, что Firefox возвращал именно CSS-ширину, а Chrome -- реальную ширину, за вычетом прокрутки. +Desktop Windows Firefox, Chrome, Edge all reserve the space for the scrollbar. But Firefox shows `300px`, while Chrome and Edge show less. That's because Firefox returns the CSS width and other browsers return the "real" width. ``` -Описанные разночтения касаются только чтения свойства `getComputedStyle(...).width` из JavaScript, визуальное отображение корректно в обоих случаях. +Please note that the described difference are only about reading `getComputedStyle(...).width` from JavaScript, visually everything is correct. -## Итого +## Summary -У элементов есть следующие метрики: +Elements have the following geometry properties: -- `offsetParent` -- "родитель по дереву рендеринга" -- ближайшая ячейка таблицы, body для статического позиционирования или ближайший позиционированный элемент для других типов позиционирования. -- `offsetLeft/offsetTop` -- позиция в пикселях левого верхнего угла блока, относительно его `offsetParent`. -- `offsetWidth/offsetHeight` -- "внешняя" ширина/высота блока, включая рамки. -- `clientLeft/clientTop` -- отступ области содержимого от левого-верхнего угла элемента. Если операционная система располагает вертикальную прокрутку справа, то равны ширинам левой/верхней рамки, если же слева (ОС на иврите, арабском), то `clientLeft` включает в себя прокрутку. -- `clientWidth/clientHeight` -- ширина/высота содержимого вместе с полями `padding`, но без полосы прокрутки. -- `scrollWidth/scrollHeight` -- ширина/высота содержимого, включая прокручиваемую область. Включает в себя `padding` и не включает полосы прокрутки. -- `scrollLeft/scrollTop` -- ширина/высота прокрученной части документа, считается от верхнего левого угла. +- `offsetParent` -- is the nearest positioned ancestor or `td`, `th`, `table`, `body`. +- `offsetLeft/offsetTop` -- coordinates relative to the left-upper edge of `offsetParent`. +- `offsetWidth/offsetHeight` -- "outer" width/height of an element including borders. +- `clientLeft/clientTop` -- the distance from the left-upper outer corner to its left-upper inner corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too. +- `clientWidth/clientHeight` -- the width/height of the content including paddings, but without the scrollbar. +- `scrollWidth/scrollHeight` -- the width/height of the content including the scrolled out part. Also includes paddings, but not the scrollbar. +- `scrollLeft/scrollTop` -- width/height of the scrolled out part of the element, starting from its left-upper corner. -Все свойства, доступны только для чтения, кроме `scrollLeft/scrollTop`. Изменение этих свойств заставляет браузер прокручивать элемент. - -В этой главе мы считали, что страница находится в режиме соответствия стандартам. В режиме совместимости -- некоторые старые браузеры требуют `document.body` вместо `documentElement`, в остальном всё так же. Конечно, по возможности, стоит использовать только режим соответствия стандарту. +All properties are read-only except `scrollLeft/scrollTop`. They make the browser scroll the element if changed. diff --git a/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html b/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html index a29f8a3a..2869c7ed 100755 --- a/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html +++ b/2-ui/1-document/15-size-and-scroll/cssWidthScroll.view/index.html @@ -1,26 +1,16 @@ - - - - -
- текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст - текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст - текст текст текст текст текст текст текст текст текст текст текст текст текст текст + text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text + text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text + text text text text text text text text text text text text text text text text text text text text text text text text text text
- - - У элемента стоит style="width:300px" + The element has style="width:300px"
- - \ No newline at end of file +