# Въведение в програмните езици и инструменти за разработка
Този урок обхваща основите на програмните езици. Темите, разгледани тук, се отнасят за повечето съвременни програмни езици. В секцията „Инструменти за разработка“ ще научите за полезен софтуер, който помага на разработчиците.
Този урок обхваща основите на програмните езици. Темите, разгледани тук, са приложими за повечето съвременни програмни езици. В секцията "Инструменти за разработка" ще научите за полезен софтуер, който помага на разработчиците.
Програмирането (известно още като кодиране) е процесът на писане на инструкции за устройство, като компютър или мобилно устройство. Пишем тези инструкции с помощта на програмен език, който след това се интерпретира от устройството. Тези набори от инструкции могат да бъдат наричани с различни имена, но *програма*, *компютърна програма*, *приложение (app)* и *изпълним файл*са някои от популярните термини.
Програмирането (известно още като кодиране) е процесът на писане на инструкции за устройство като компютър или мобилно устройство. Пишем тези инструкции с помощта на програмен език, който след това се интерпретира от устройството. Тези набори от инструкции могат да бъдат наричани с различни имена, но *програма*, *компютърна програма*, *приложение (app)* и *изпълним файл*са някои от популярните термини.
*Програма* може да бъде всичко, което е написано с код: уебсайтове, игри и приложения за телефони са програми. Въпреки че е възможно да се създаде програма без писане на код, основната логика се интерпретира от устройството и тази логика най-вероятно е написана с код. Програма, която *работи* или *изпълнява* код, изпълнява инструкции. Устройството, с което четете този урок, изпълнява програма, за да го покаже на екрана ви.
✅ Направете малко проучване: кой сесмята за първия програмист в света?
✅ Направете малко проучване: кой сесчита за първия програмист в света?
## Програмни езици
@ -85,17 +85,17 @@ back add r0,r1
Повярвайте или не, *и двата правят едно и също*: отпечатват последователност на Фибоначи до 10.
✅ Последователността на Фибоначи е [дефинирана](https://en.wikipedia.org/wiki/Fibonacci_number) като набор от числа, при които всяко число е сумата от двете предходни, започвайки от 0 и 1. Първите 10 числа в последователността на Фибоначи са 0, 1, 1, 2, 3, 5, 8, 13, 21 и 34.
✅ Последователността на Фибоначи е [дефинирана](https://en.wikipedia.org/wiki/Fibonacci_number) като набор от числа, при които всяко число е сумата от предходните две, започвайки от 0 и 1. Първите 10 числа в последователността на Фибоначи са 0, 1, 1, 2, 3, 5, 8, 13, 21 и 34.
## Елементи на програмата
Една инструкция в програмата се нарича *израз* и обикновено има символ или разстояние, което маркира къде инструкцията приключва или *се прекратява*. Начинът, по който програмата се прекратява, варира за всеки език.
Една инструкция в програмата се нарича *израз* и обикновено има символ или интервал, който маркира къде инструкцията приключва или *се прекратява*. Начинът, по който програмата се прекратява, варира за всеки език.
Изразите в програмата могат да разчитат на данни, предоставени от потребител или друг източник, за да изпълнят инструкции. Данните могат да променят поведението на програмата, затова програмните езици предлагат начин за временно съхранение на данни, за да могат да бъдат използвани по-късно. Това се нарича *променливи*. Променливите са изрази, които инструктират устройството да запази данни в паметта си. Променливите в програмите са подобни на променливите в алгебрата, където имат уникално име и стойността им може да се променя с времето.
Изразите в програмата могат да разчитат на данни, предоставени от потребителя или от друго място, за да изпълнят инструкции. Данните могат да променят поведението на програмата, затова програмните езици предлагат начин за временно съхранение на данни, за да могат да бъдат използвани по-късно. Това се нарича *променливи*. Променливите са изрази, които инструктират устройството да запази данни в паметта си. Променливите в програмите са подобни на променливите в алгебрата, където имат уникално име и стойността им може да се променя с времето.
Има вероятност някои изрази да не бъдат изпълнени от устройството. Това обикновено е по дизайн, когато е написано от разработчика, или случайно, когато възникне неочаквана грешка. Този тип контрол върху приложението го прави по-устойчиво и лесно за поддръжка. Обикновено тези промени в контрола се случват, когато са изпълнени определени условия. Често използван израз в съвременното програмиране за контрол на изпълнението на програмата е`if..else`.
✅ Ще научите повече за този тип израз в следващите уроци.
✅ Ще научите повече за този тип изрази в следващите уроци.
## Инструменти за разработка
@ -103,7 +103,7 @@ back add r0,r1
> 🎥 Кликнете върху изображението по-горе за видео за инструментите
В тази секция ще научите за някои софтуери, които може да ви бъдат много полезни, когато започнете професионалния си път като разработчик.
В тази секция ще научите за някои софтуери, които може да намерите за много полезни, когато започнете професионалния си път като разработчик.
**Среда за разработка** е уникален набор от инструменти и функции, които разработчикът използва често при писане на софтуер. Някои от тези инструменти са персонализирани според специфичните нужди на разработчика и могат да се променят с времето, ако разработчикът промени приоритетите си в работата, личните проекти или когато използва различен програмен език. Средите за разработка са толкова уникални, колкото и разработчиците, които ги използват.
@ -135,9 +135,9 @@ back add r0,r1
### Браузъри
Друг важен инструмент е браузърът. Уеб разработчиците разчитат на браузъра, за да видят как техният код работи в уеб пространството. Той също така се използва за показване на визуалните елементи на уеб страница, написани в редактора, като HTML.
Друг важен инструмент е браузърът. Уеб разработчиците разчитат на браузъра, за да видят как техният код работи в уеб пространството. Той също така се използва за показване на визуалните елементи на уеб страница, които санаписани в редактора, като HTML.
Много браузъри идват с*инструменти за разработчици* (DevTools), които съдържат набор от полезни функции и информация, за да помогнат на разработчиците да събират и улавят важна информация за своето приложение. Например: Ако уеб страница има грешки, понякога е полезно да знаете кога са възникнали. DevTools в браузъра могат да бъдат конфигурирани да улавят тази информация.
Много браузъри идват с*инструменти за разработчици* (DevTools), които съдържат набор от полезни функции и информация, за да помогнат на разработчиците да събират и улавят важна информация за своето приложение. Например: Ако уеб страница има грешки, понякога е полезно да сезнае кога са възникнали. DevTools в браузъра могат да бъдат конфигурирани да улавят тази информация.
#### Популярни браузъри и DevTools
@ -147,11 +147,11 @@ back add r0,r1
### Инструменти за команден ред
Някои разработчици предпочитат по-малко графичен изглед за ежедневните си задачи и разчитат на командния ред, за да го постигнат. Писането на код изисква значително количество въвеждане, и някои разработчици предпочитат да не прекъсват потока си на клавиатурата. Те използват клавишни комбинации, за да превключват между прозорци на работния плот, да работят върху различни файлове и да използват инструменти. Повечето задачи могат да бъдат изпълнени с мишка, но едно от предимствата на командния ред е, че много неща могат да бъдат направени с инструменти за команден ред, без да се налага превключване между мишката и клавиатурата. Друго предимство на командния ред е, че той е конфигурируем и можете да запазите персонализирана конфигурация, да я промените по-късно и да я импортирате на други машини за разработка. Тъй като средите за разработка са толкова уникални за всеки разработчик, някои ще избягват използването на командния ред, други ще разчитат изцяло на него, а трети предпочитат комбинация от двете.
Някои разработчици предпочитат по-малко графичен изглед за ежедневните си задачи и разчитат на командния ред, за да ги изпълнят. Писането на код изисква значително количество писане, и някои разработчици предпочитат да не прекъсват потока си на клавиатурата. Те използват клавишни комбинации, за да превключват между прозорци на работния плот, работят върху различни файлове и използват инструменти. Повечето задачи могат да бъдат изпълнени с мишка, но едно от предимствата на командния ред е, че много неща могат да бъдат направени с инструменти за команден ред, без да се налага да сепревключва между мишката и клавиатурата. Друго предимство на командния ред е, че той е конфигурируем и можете да запазите персонализирана конфигурация, да я промените по-късно и да я импортирате на други машини за разработка. Тъй като средите за разработка са толкова уникални за всеки разработчик, някои избягват използването на командния ред, други разчитат изцяло на него, а трети предпочитат комбинация от двете.
### Популярни опции за команден ред
Опциите за команден ред ще се различават в зависимост от операционната система, която използвате.
Опциите за команден ред се различават в зависимост от операционната система, която използвате.
*💻 = предварително инсталиран на операционната система.*
@ -182,7 +182,7 @@ back add r0,r1
### Документация
Когато разработчик иска да научи нещо ново, най-вероятно ще се обърне към документацията, за да разбере как да го използва. Разработчиците често разчитат на документацията, за да ги насочи как правилно да използват инструменти и езици, както и за да придобият по-дълбоки знания за тях.
Когато разработчик иска да научи нещо ново, той най-вероятно ще се обърне към документацията, за да разбере как да го използва. Разработчиците често разчитат на документацията, за да ги насочи как да използват инструменти и езици правилно, както и за да придобият по-дълбоки знания за това как работят.
#### Популярна документация за уеб разработка
@ -200,12 +200,12 @@ back add r0,r1
Сравнете някои програмни езици. Какви са уникалните характеристики на JavaScript спрямо Java? А какво ще кажете за COBOL спрямо Go?
## Тест след лекцията
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/2)
## Тест след урока
[Тест след урока](https://ff-quizzes.netlify.app/web/)
## Преглед и самостоятелно обучение
Проучете различните езици, достъпни за програмиста. Опитайте да напишете един ред код на един език, а след това го пренапишете на два други. Какво научихте?
Проучете различните езици, достъпни за програмиста. Опитайте да напишете един ред код на един език и след това го пренапишете на два други. Какво научихте?
- проследяване на работата, която вършите на вашия компютър
- проследяване на работата, която вършите на вашата машина
- работа по проекти с други хора
- как да допринасяте за софтуер с отворен код
### Предварителни изисквания
Преди да започнете, трябва да проверите дали Git е инсталиран. В терминала напишете:
Преди да започнете, трябва да проверите дали Git е инсталиран. В терминала въведете:
`git --version`
Ако Git не е инсталиран, [изтеглете Git](https://git-scm.com/downloads). След това настройте локалния си Git профил в терминала:
Ако Git не е инсталиран, [изтеглете Git](https://git-scm.com/downloads). След това настройте вашия локален Git профил в терминала:
* `git config --global user.name "вашето-име"`
* `git config --global user.email "вашият-имейл"`
За да проверите дали Git вече е конфигуриран, можете да напишете:
За да проверите дали Git вече е конфигуриран, можете да въведете:
`git config --list`
Ще ви е необходим и акаунт в GitHub, редактор за код (като Visual Studio Code) и трябва да отворите терминала си (или командния ред).
Ще ви е необходим и акаунт в GitHub, текстов редактор за код (като Visual Studio Code) и ще трябва да отворите вашия терминал (или команден прозорец).
Отидете на [github.com](https://github.com/) и създайте акаунт, ако все още нямате такъв, или влезте и попълнете профила си.
Посетете [github.com](https://github.com/) и създайте акаунт, ако все още нямате такъв, или влезте и попълнете вашия профил.
✅ GitHub не е единственото хранилище за код в света; има и други, но GitHub е най-известното.
### Подготовка
Ще ви трябва папка с проект за код на вашия локален компютър (лаптоп или PC) и публично хранилище в GitHub, което ще служи като пример за това как да допринасяте за проектите на други хора.
Ще ви е необходима папка с проект на код на вашата локална машина (лаптоп или компютър) и публично хранилище в GitHub, което ще служи като пример за това как да допринасяте за проекти на други хора.
---
## Управление на кода
Да кажем, че имате локална папка с проект за код и искате да започнете да проследявате напредъка си с помощта на git - системата за контрол на версиите. Някои хора сравняват използването на git с писане на любовно писмо до бъдещото си аз. Четейки съобщенията за комит дни, седмици или месеци по-късно, ще можете да си припомните защо сте взели дадено решение или да "върнете" промяна - стига да пишете добри "съобщения за комит".
Да кажем, че имате папка локално с някакъв проект на код и искате да започнете да проследявате вашия напредък, използвайки git - системата за контрол на версиите. Някои хора сравняват използването на git с писане на любовно писмо до бъдещото ви аз. Четейки вашите съобщения за комити дни, седмици или месеци по-късно, ще можете да си припомните защо сте взели дадено решение или да "върнете" промяна - стига да пишете добри "съобщения за комити".
### Задача: Създайте хранилище и комитнете код
@ -59,25 +59,24 @@ CO_OP_TRANSLATOR_METADATA:
>
> [](https://www.youtube.com/watch?v=9R31OUPpxU4)
1. **Създайте хранилище в GitHub**. На GitHub.com, в раздела за хранилища или от навигационната лента горе вдясно, намерете бутона **new repo**.
1. **Създайте хранилище в GitHub**. В GitHub.com, в раздела с хранилища или от навигационната лента горе вдясно, намерете бутона **new repo**.
1. Дайте име на вашето хранилище (папка).
1. Изберете **create repository**.
1. **Навигирайте до работната си папка**. В терминала си преминете към папката (известна още като директория), която искате да започнете да проследявате. Напишете:
1. **Навигирайте до вашата работна папка**. В терминала преминете към папката (известна също като директория), която искате да започнете да проследявате. Въведете:
```bash
cd [name of your folder]
```
1. **Инициализирайте git хранилище**. В проекта си напишете:
1. **Инициализирайте git хранилище**. Във вашия проект въведете:
```bash
git init
```
1. **Проверете статуса**. За да проверите статуса на вашето хранилище, напишете:
1. **Проверете статуса**. За да проверите статуса на вашето хранилище, въведете:
```bash
git status
@ -96,14 +95,14 @@ CO_OP_TRANSLATOR_METADATA:
Обикновено командата `git status` ви казва неща като кои файлове са готови за _записване_ в хранилището или имат промени, които може да искате да запазите.
1. **Добавете всички файлове за проследяване**
Това се нарича също "стейджване" на файлове/ добавяне на файлове към зоната за стейджинг.
1. **Добавете всички файлове за проследяване**
Това също се нарича поставяне на файлове в зоната за подготовка.
```bash
git add .
```
Аргументът `git add` плюс `.`показва, че всички ваши файлове и промени са готови за проследяване.
Аргументът `git add` плюс `.`означава, че всички ваши файлове и промени ще бъдат проследявани.
1. **Добавете избрани файлове за проследяване**
@ -111,51 +110,51 @@ CO_OP_TRANSLATOR_METADATA:
git add [file or folder name]
```
Това ни помага да добавим само избрани файлове към зоната за стейджинг, когато не искаме да комитнем всички файлове наведнъж.
Това ни помага да добавим само избрани файлове в зоната за подготовка, когато не искаме да комитнем всички файлове наведнъж.
1. **Премахнете всички файлове от стейджинг**
1. **Премахнете всички файлове от зоната за подготовка**
```bash
git reset
```
Тази команда ни помага да премахнем всички файлове от зоната за стейджинг наведнъж.
Тази команда ни помага да премахнем всички файлове от зоната за подготовка наведнъж.
1. **Премахнете конкретен файл от стейджинг**
1. **Премахнете конкретен файл от зоната за подготовка**
```bash
git reset [file or folder name]
```
Тази команда ни помага да премахнем само конкретен файл от зоната за стейджинг, който не искаме да включим в следващия комит.
Тази команда ни помага да премахнем само конкретен файл от зоната за подготовка, който не искаме да включим в следващия комит.
1. **Запазване на работата ви**. На този етап сте добавили файловете към така наречената _зона за стейджинг_. Място, където Git проследява вашите файлове. За да направите промяната постоянна, трябва да _комитнете_ файловете. За да направите това, създайте _комит_с командата `git commit`. _Комит_ представлява точка за запазване в историята на вашето хранилище. Напишете следното, за да създадете _комит_:
1. **Запазване на вашата работа**. На този етап сте добавили файловете в така наречената _зона за подготовка_. Това е място, където Git проследява вашите файлове. За да направите промяната постоянна, трябва да _комитнете_ файловете. За да създадете _комит_, въведете следното:
```bash
git commit -m "first commit"
```
Това комитва всички ваши файлове, добавяйки съобщението "first commit". За бъдещи съобщения за комит ще искате да бъдете по-описателни, за да предадете какъв тип промяна сте направили.
Това комитва всички ваши файлове, добавяйки съобщението "first commit". За бъдещи съобщения за комити ще искате да бъдете по-описателни, за да предадете какъв тип промяна сте направили.
1. **Свържете локалното си Git хранилище с GitHub**. Git хранилище е полезно на вашия компютър, но в даден момент ще искате да имате резервно копие на вашите файлове някъде и също така да поканите други хора да работят с вас върху вашето хранилище. Едно такова страхотно място за това е GitHub. Помнете, че вече създадохме хранилище в GitHub, така че единственото, което трябва да направим, е да свържем локалното Git хранилище с GitHub. Командата `git remote add` ще направи точно това. Напишете следната команда:
1. **Свържете вашето локално Git хранилище с GitHub**. Git хранилище е полезно на вашата машина, но в даден момент ще искате да имате резервно копие на вашите файлове някъде и също така да поканите други хора да работят с вас върху вашето хранилище. Едно такова чудесно място е GitHub. Помните, че вече създадохме хранилище в GitHub, така че единственото, което трябва да направим, е да свържем нашето локално Git хранилище с GitHub. Командата `git remote add` ще направи точно това. Въведете следната команда:
> Забележка: преди да напишете командата, отидете на страницата на вашето GitHub хранилище, за да намерите URL адреса на хранилището. Ще го използвате в командата по-долу. Заменете ```https://github.com/username/repository_name.git``` с вашия GitHub URL.
> Забележка: преди да въведете командата, отидете на страницата на вашето GitHub хранилище, за да намерите URL адреса на хранилището. Ще го използвате в командата по-долу. Заменете ```https://github.com/username/repository_name.git``` с вашия GitHub URL.
Това създава _remote_, или връзка, наречена "origin", сочеща към GitHub хранилището, което създадохте по-рано.
Това създава _remote_ или връзка, наречена "origin", сочеща към GitHub хранилището, което създадохте по-рано.
1. **Изпратете локалните файлове в GitHub**. Досега сте създали _връзка_ между локалното хранилище и GitHub хранилището. Нека изпратим тези файлове в GitHub със следната команда `git push`, както следва:
1. **Изпратете локалните файлове в GitHub**. Досега сте създали _връзка_ между локалното хранилище и GitHub хранилището. Нека изпратим тези файлове в GitHub с командата `git push`, както следва:
> Забележка: името на вашия branch може да е различно по подразбиране от ```main```.
> Забележка: името на вашия клон може да е различно по подразбиране от ```main```.
```bash
git push -u origin main
```
Това изпраща вашите комити в "main" branch в GitHub.
Това изпраща вашите комити в клона "main" в GitHub.
2. **Добавяне на още промени**. Ако искате да продължите да правите промени и да ги изпращате в GitHub, ще трябва да използвате следните три команди:
@ -165,21 +164,21 @@ CO_OP_TRANSLATOR_METADATA:
git push
```
> Съвет: Може също да искате да използвате файл `.gitignore`, за да предотвратите появата на файлове, които не искате да проследявате, в GitHub - например файл с бележки, който съхранявате в същата папка, но няма място в публично хранилище. Можете да намерите шаблони за `.gitignore` файлове на [.gitignore templates](https://github.com/github/gitignore).
> Съвет: Може също да искате да използвате файл `.gitignore`, за да предотвратите появата на файлове, които не искате да проследявате, в GitHub - например файл с бележки, който съхранявате в същата папка, но няма място в публично хранилище. Можете да намерите шаблони за файлове `.gitignore` на [.gitignore templates](https://github.com/github/gitignore).
#### Съобщения за комит
#### Съобщения за комити
Добро заглавие на съобщение за Git комит завършва следното изречение:
Ако бъде приложено, този комит ще <вашето заглавие тук>
Чудесно заглавие на съобщение за Git комит завършва следното изречение:
Ако бъде приложено, този комит ще <вашето заглавие тук>.
За заглавието използвайте императивно, сегашно време: "променя" вместо "променено" или "промени".
Както в заглавието, така и в тялото (по избор) използвайте императивно, сегашно време. Тялото трябва да включва мотивацията за промяната и да я сравнис предишното поведение. Обяснявате `защо`, а не `как`.
За заглавието използвайте повелително наклонение в сегашно време: "променя" вместо "променено" или "променя се".
Както в заглавието, така и в тялото (по избор) използвайте повелително наклонение в сегашно време. Тялото трябва да включва мотивацията за промяната и да я сравнявас предишното поведение. Обяснявате `защо`, а не `как`.
✅ Отделете няколко минути, за да разгледате GitHub. Можете ли да намерите наистина добро съобщение за комит? Можете ли да намерите наистина минимално? Каква информация смятате, чее най-важна и полезна за предаване в съобщение за комит?
✅ Отделете няколко минути, за да разгледате GitHub. Можете ли да намерите наистина страхотно съобщение за комит? А минимално такова? Каква информация според васе най-важна и полезна за предаване в съобщение за комит?
### Задача: Сътрудничество
Основната причина за качването на неща в GitHub беше да се направи възможно сътрудничеството с други разработчици.
Основната причина за качването на неща в GitHub е да се направи възможно сътрудничеството с други разработчици.
## Работа по проекти с други хора
@ -187,89 +186,91 @@ CO_OP_TRANSLATOR_METADATA:
>
> [](https://www.youtube.com/watch?v=bFCM-PC3cu8)
Във вашето хранилище навигирайте до `Insights > Community`, за да видите как вашият проект се сравнява с препоръчаните стандарти за общността.
Във вашето хранилище навигирайте до `Insights > Community`, за да видите как вашият проект се сравнява с препоръчаните стандарти на общността.
Ето някои неща, които могат да подобрят вашето GitHub хранилище:
- **Описание**. Добавихте ли описание за вашия проект?
- **README**. Добавихте ли README? GitHub предоставя насоки за писане на [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
- **Насоки за допринасяне**. Има ли вашият проект [насоки за допринасяне](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)?
- **Кодекс на поведение**. [Кодекс на поведение](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/).
- **Лиценз**. Може би най-важното, [лиценз](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
Ето някои неща, които могат да подобрят вашето GitHub хранилище:
- **Описание**. Добавихте ли описание на вашия проект?
- **README**. Добавихте ли README? GitHub предоставя насоки за писане на [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
- **Насоки за принос**. Има ли вашият проект [насоки за принос](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)?
- **Кодекс на поведение**. Има ли [Кодекс на поведение](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/)?
- **Лиценз**. Може би най-важното, има ли [лиценз](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
Всички тези ресурси ще бъдат от полза за въвеждането на нови членове на екипа. Това са обикновено нещата, които новите сътрудници разглеждат, преди дори да погледнат вашия код, за да разберат дали вашият проект е правилното място, където да инвестират времето си.
Всички тези ресурси ще бъдат от полза за въвеждането на нови членове на екипа. Това са обикновено нещата, които новите сътрудници разглеждат, преди дори да погледнат вашия код, за да разберат дали вашият проект е подходящото място за тях да инвестират времето си.
✅ README файловете, въпреки че отнемат време за подготовка, често се пренебрегват от заети поддържащи. Можете ли да намерите пример за особено описателен README? Забележка: има някои [инструменти за създаване на добри README файлове](https://www.makeareadme.com/), които може да искате да опитате.
### Задача: Слейте код
Документите за допринасяне помагат на хората да допринасят за проекта. Те обясняват какви типове допринасяния търсите и как работи процесът. Сътрудниците ще трябва да преминат през серия от стъпки, за да могат да допринесат за вашето хранилище в GitHub:
### Задача: Сливане на код
Документите за принос помагат на хората да допринасят за проекта. Те обясняват какви видове приноси търсите и как работи процесът. Сътрудниците ще трябва да преминат през серия от стъпки, за да могат да допринесат за вашето хранилище в GitHub:
1. **Форкване на вашето хранилище**. Вероятно ще искате хората да _форкнат_ вашия проект. Форкването означава създаване на копие на вашето хранилище в техния GitHub профил.
1. **Клониране**. Оттам те ще клонират проекта на своя локален компютър.
1. **Създаване на branch**. Ще искате да ги помолите да създадат _branch_ за своята работа.
1. **Фокусиране на промяната върху една област**. Помолете сътрудниците да концентрират своите допринасяния върху едно нещо наведнъж - така шансовете да можете да _слеете_ тяхната работа са по-големи. Представете си, че те пишат поправка на бъг, добавят нова функция и актуализират няколко теста - какво ако искате или можете да приложите само 2 от 3, или 1 от 3 промени?
1. **Клониране**. Оттам те ще клонират проекта на своята локална машина.
1. **Създаване на клон**. Ще искате да ги помолите да създадат _клон_ за своята работа.
1. **Фокусиране върху една област**. Помолете сътрудниците да концентрират своите приноси върху едно нещо наведнъж - така шансовете да можете да _слеете_ тяхната работа са по-големи. Представете си, че те пишат поправка на грешка, добавят нова функция и актуализират няколко теста - какво ако искате или можете да приложите само 2 от 3, или 1 от 3 промени?
✅ Представете си ситуация, в която branch-овете са особено критични за писането и доставянето на добър код. Какви случаи на употреба можете да си представите?
✅ Представете си ситуация, в която клоновете са особено критични за писането и доставянето на добър код. Какви случаи на употреба можете да си представите?
> Забележка: бъдете промяната, която искате да видите в света, и създавайте branch-ове за вашата собствена работа също. Всички комити, които правите, ще бъдат направени в branch-а, на който сте "чекнати". Използвайте `git status`, за да видите кой branch е това.
> Забележка: бъдете промяната, която искате да видите в света, и създавайте клонове и за вашата собствена работа. Всички комити, които правите, ще бъдат направени в клона, в който в момента сте "чекнати". Използвайте `git status`, за да видите в кой клон се намирате.
Нека преминем през работния процес на сътрудник. Приемете, че сътрудникът вече е_форкнал_ и _клонирал_ хранилището, така че има готово Git хранилище за работа на своя локален компютър:
Нека преминем през работния процес на сътрудник. Да предположим, че сътрудникът вече е_форкнал_ и _клонирал_ хранилището, така че има готово Git хранилище на своята локална машина:
1. **Създаване на branch**. Използвайте командата `git branch`, за да създадете branch, който ще съдържа промените, които искат да допринесат:
1. **Създаване на клон**. Използвайте командата `git branch`, за да създадете клон, който ще съдържа промените, които възнамеряват да допринесат:
```bash
git branch [branch-name]
```
1. **Превключване към работния branch**. Превключете към посочения branch и актуализирайте работната директория с`git switch`:
1. **Превключване към работния клон**. Превключете към посочения клон и актуализирайте работната директория с`git switch`:
```bash
git switch [branch-name]
```
1. **Работа**. На този етап искате да добавите вашите промени. Не забравяйте да кажете на Git за тях със следните команди:
1. **Работа**. На този етап искате да добавите вашите промени. Не забравяйте да уведомите Git за това със следните команди:
```bash
git add .
git commit -m "my changes"
```
Уверете се, че давате на вашия комит добро име, за ваше удобство, както и за поддържащия на хранилището, на което помагате.
Уверете се, че давате добро име на вашия комит, както за вас, така и за поддържащия на хранилището, на което помагате.
1. **Сливане на вашата работа с`main` branch**. В даден момент сте готови с работата си и искате да я слеете с тази на `main` branch. Междувременно `main` branch може да сее променил, така че се уверете, че първо го актуализирате до последната версия със следните команди:
1. **Комбиниране на вашата работа с клона `main`**. В даден момент сте готови с работата си и искате да я комбинирате с тази на клона `main`. Клонът `main` може да сее променил междувременно, така че се уверете, че първо го актуализирате до последната версия със следните команди:
```bash
git switch main
git pull
```
На този етап искате да се уверите, че всички _конфликти_, ситуации, в които Git не може лесно да _комбинира_ промените, се случват във вашия работен branch. Затова изпълнете следните команди:
На този етап искате да се уверите, че всички _конфликти_, ситуации, в които Git не може лесно да _комбинира_ промените, се случват във вашия работен клон. Затова изпълнете следните команди:
```bash
git switch [branch_name]
git merge main
```
Това ще доведе всички промени от `main` във вашия branch и се надяваме, че можете просто да продължите. Ако не, VS Code ще ви покаже къде Git е_объркан_ и просто променяте засегнатите файлове, за да посочите кое съдържание е най-точно.
Това ще внесе всички промени от `main` във вашия клон и, надяваме се, ще можете просто да продължите. Ако не, VS Code ще ви покаже къде Git е_объркан_ и просто ще промените засегнатите файлове, за да посочите кое съдържание е най-точно.
1. **Изпращане на вашата работа в GitHub**. Изпращането на вашата работа в GitHub означава две неща. Пушване на вашия branch към вашето хранилище и след това отваряне на PR (Pull Request).
1. **Изпращане на вашата работа в GitHub**. Изпращането на вашата работа в GitHub означава две неща. Пушване на вашия клон във вашето хранилище и след това отваряне на PR (Pull Request).
```bash
git push --set-upstream origin [branch-name]
```
Горната команда създава branch във вашето форкнато хранилище.
Горната команда създава клона във вашето форкнато хранилище.
1. **Отваряне на PR**. След това искате да отворите PR. Това става, като навигирате до форкнатото хранилище в GitHub. Ще видите индикация в GitHub, където се пита дали искате да създадете нов PR, кликвате върху това и сте отведени до интерфейс, където можете да промените заглавието на съобщението за комит, да му дадете по-подходящо описание. Сега поддържащият на хранилището, което сте форкнали, ще види този PR и _да се надяваме_ ще оцени и _слее_ вашия PR. Вече сте сътрудник, ура :)
1. **Отваряне на PR**. След това искате да отворите PR. Това става, като навигирате до форкнатото хранилище в GitHub. Ще видите индикация в GitHub, където се пита дали искате да създадете нов PR, кликнете върху това и ще бъдете отведени до интерфейс, където можете да промените заглавието на съобщението за комит, да му дадете по-подходящо описание. Сега поддържащият на хранилището, което сте форкнали, ще види този PR и _с кръстени пръсти_ ще оцени и _слее_ вашия PR. Вече сте сътрудник, ура :)
1. **Почистване**. Счита се за добра практика да _почистите_ след успешно сливане на PR. Искате да почистите както локалния си branch, така и branch-а, който сте пушнали в GitHub. Първо, нека го из
Уверете се, че отидете на страницата на GitHub за форкнатото хранилище и премахнете отдалечения клон, който току-що сте качили.
1. **Почистване**. Счита се за добра практика да _почистите_ след успешно сливане на PR. Искате да изчистите както вашия локален клон, така и клона, който сте пушнали в GitHub. Първо, нека го изтрием локално със следната команда:
```bash
git branch -d [branch-name]
```
`Pull request` изглежда като странен термин, защото всъщност искате да качите вашите промени в проекта. Но поддръжникът (собственикът на проекта) или основният екип трябва да разгледат вашите промени, преди да ги обединят с "главния" клон на проекта, така че всъщност искате решение за промяна от поддръжника.
Уверете се, че отивате на страницата на GitHub за форкнатото хранилище и премахнете отдалечения клон, който току-
`Pull request` изглежда като странен термин, защото всъщност искате да "пушнете" вашите промени към проекта. Но поддръжникът (собственикът на проекта) или основният екип трябва да разгледат вашите промени, преди да ги обединят с "главния" клон на проекта, така че всъщност искате решение за промяна от поддръжника.
Pull request е мястото, където се сравняват и обсъждат разликите, въведени в даден клон, с ревюта, коментари, интегрирани тестове и други. Един добър pull request следва приблизително същите правила като съобщение за commit. Можете да добавите препратка към проблем в тракера за проблеми, например когато вашата работа решава даден проблем. Това се прави с`#`, последвано от номера на проблема. Например `#97`.
`Pull request`е мястото, където се сравняват и обсъждат разликите, въведени в даден клон, с ревюта, коментари, интегрирани тестове и други. Един добър `pull request` следва приблизително същите правила като съобщение за commit. Можете да добавите препратка към проблем в тракера за проблеми, например когато вашата работа решава даден проблем. Това се прави с помощта на`#`, последвано от номера на проблема. Например `#97`.
🤞Стискайте палци всички проверки да преминат успешно и собствениците на проекта да обединят вашите промени в проекта🤞
@ -279,9 +280,9 @@ Pull request е мястото, където се сравняват и обсъ
## Как да допринесете за отворен код
Първо, нека намерим хранилище (или **repo**) в GitHub, което ви интересува и към което искате да допринесете с промяна. Ще искате да копирате съдържанието му на вашата машина.
Първо, намерете хранилище (или **repo**) в GitHub, което ви интересува и към което искате да допринесете с промяна. Ще искате да копирате съдържанието му на вашата машина.
✅ Добър начин да намерите хранилища, подходящи за начинаещи, еда [търсите по етикета 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/).
✅ Добър начин да намерите хранилища, подходящи за начинаещи, екато [търсите по етикета 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/).

@ -297,24 +298,24 @@ Pull request е мястото, където се сравняват и обсъ
Накрая, можете да изтеглите кода в компресиран файл.
### Няколко интересни неща за GitHub
### Още няколко интересни неща за GitHub
Можете да добавите звезда, да наблюдавате и/или да "форкнете" всяко публично хранилище в GitHub. Можете да намерите вашите хранилища със звезда в падащото меню в горния десен ъгъл. Това е като да запазите отметка, но за код.
Можете да добавите звезда, да следите или да "форкнете" всяко публично хранилище в GitHub. Можете да намерите вашите хранилища със звезди в падащото меню горе вдясно. Това е като да запазите отметка, но за код.
Проектите имат тракер за проблеми, най-често в раздела "Issues" в GitHub, освен ако не е посочено друго, където хората обсъждат проблеми, свързани с проекта. А разделът Pull Requests е мястото, където хората обсъждат и преглеждат промени, които са в процес на работа.
Проектите имат тракер за проблеми, обикновено в раздела "Issues" в GitHub, освен ако не е посочено друго, където хората обсъждат проблеми, свързани с проекта. А разделът "Pull Requests"е мястото, където хората обсъждат и преглеждат промени, които са в процес на работа.
Проектите може също да имат дискусии във форуми, пощенски списъци или чат канали като Slack, Discord или IRC.
✅ Разгледайте новото си хранилище в GitHub и опитайте няколко неща, като редактиране на настройки, добавяне на информация към вашето хранилище и създаване на проект (като Канбан дъска). Има много неща, които можете да направите!
✅ Разгледайте вашето ново хранилище в GitHub и опитайте няколко неща, като редактиране на настройки, добавяне на информация към вашето хранилище и създаване на проект (като Канбан дъска). Има много неща, които можете да направите!
---
## 🚀 Предизвикателство
Работете в екип с приятел, за да работите върху кода на другия. Създайте проект съвместно, форкнете код, създайте клонове и обединете промените.
Работете в екип с приятел върху кода на другия. Създайте проект съвместно, форкнете код, създайте клонове и обединете промените.
## Тест след лекцията
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/4)
[Тест след лекцията](https://ff-quizzes.netlify.app/web/en/)
## Преглед и самостоятелно обучение
@ -322,17 +323,17 @@ Pull request е мястото, където се сравняват и обсъ
Практикувайте, практикувайте, практикувайте. GitHub предлага страхотни учебни пътеки чрез [skills.github.com](https://skills.github.com):
Практика, практика, практика. GitHub предлага страхотни учебни пътеки чрез [skills.github.com](https://skills.github.com):
- [Първата седмица в GitHub](https://skills.github.com/#first-week-on-github)
Ще намерите и по-напреднали курсове.
## Задача
## Задание
Завършете [курса "Първата седмица в GitHub"](https://skills.github.com/#first-week-on-github)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
> Силата на уебе в неговата универсалност. Достъпът за всеки, независимо от уврежданията, е съществен аспект.
> Силата на уебае в неговата универсалност. Достъпът за всички, независимо от уврежданията, е съществен аспект.
>
> \- Сър Тимъти Бърнърс-Лий, директор на W3C и изобретател на Световната мрежа
Този цитат перфектно подчертава важността на създаването на достъпни уебсайтове. Приложение, което не може да бъде достъпно за всички, по дефиниция е изключващо. Като уеб разработчици, винаги трябва да имаме предвид достъпността. Ако се фокусираме върху това от самото начало, ще сме на правилния път да гарантираме, че всеки може да достъпи страниците, които създаваме. В този урок ще научите за инструментите, които могат да ви помогнат да гарантирате, че вашите уеб ресурси са достъпни, и как да изграждате с мисъл за достъпността.
Този цитат перфектно подчертава важността на създаването на достъпни уебсайтове. Приложение, което не може да бъде достъпно за всички, по дефиниция е изключващо. Като уеб разработчици, винаги трябва да имаме предвид достъпността. Ако се фокусираме върху това от самото начало, ще сме на прав път да гарантираме, че всички могат да достъпят страниците, които създаваме. В този урок ще научите за инструментите, които могат да ви помогнат да гарантирате, че вашите уеб ресурси са достъпни, и как да изграждате с мисъл за достъпността.
> Можете да вземете този урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)!
> Можете да преминете този урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)!
## Инструменти за използване
### Четци на екрана
### Четеци на екрана
Един от най-известните инструменти за достъпност са четците на екрана.
[Четците на екрана](https://en.wikipedia.org/wiki/Screen_reader) са често използвани клиенти от хорас увредено зрение. Докато отделяме време, за да гарантираме, че браузърът правилно предава информацията, която искаме да споделим, трябва също така да гарантираме, че четецът на екрана прави същото.
[Четците на екрана](https://en.wikipedia.org/wiki/Screen_reader) са често използвани от хорас увредено зрение. Докато отделяме време, за да гарантираме, че браузърът правилно предава информацията, която искаме да споделим, трябва също така да се уверим, че четецът на екрана прави същото.
В най-основния си вид, четецът на екрана ще чете страницата отгоре надолу на глас. Ако страницата ви е изцяло текстова, четецът ще предаде информацията по подобен начин на браузъра. Разбира се, уеб страниците рядко са само текст; те съдържат връзки, графики, цветове и други визуални компоненти. Трябва да се внимава, за да се гарантира, че тази информация се чете правилно от четеца на екрана.
В най-основната си форма, четецът на екрана ще чете страницата отгоре надолу на глас. Ако страницата ви е изцяло текстова, четецът ще предаде информацията по подобен начин на браузъра. Разбира се, уеб страниците рядко са само текст; те съдържат връзки, графики, цветове и други визуални компоненти. Трябва да се внимава, за да се гарантира, че тази информация се чете правилно от четеца на екрана.
Всеки уеб разработчик трябва да се запознае с четец на екрана. Както беше подчертано по-горе, това е клиентът, който вашите потребители ще използват. По същия начин, по който сте запознати сначина, по който работи браузърът, трябва да научите как работи четецът на екрана. За щастие, четци на екрана са вградени в повечето операционни системи.
Всеки уеб разработчик трябва да се запознае с четец на екрана. Както беше подчертано по-горе, това е клиентът, който вашите потребители ще използват. По същия начин, по който сте запознати сработата на браузър, трябва да научите как работи четецът на екрана. За щастие, четци на екрана са вградени в повечето операционни системи.
Някои браузъри също имат вградени инструменти и разширения, които могат да четат текст на глас или дори да предоставят някои основни навигационни функции, като [тези инструменти за достъпност в браузъра Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Те също са важни инструменти за достъпност, но функционират много различно от четците на екрана и не трябва да се бъркат с инструменти за тестване на четци на екрана.
Някои браузъри също имат вградени инструменти и разширения, които могат да четат текст на глас или дори да предоставят някои основни навигационни функции, като например [тези инструменти за достъпност в браузъра Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Те също са важни инструменти за достъпност, но функционират много различно от четците на екрана и не трябва да се бъркат с инструменти за тестване на четци на екрана.
✅ Опитайте четец на екрана и браузър за четене на текст. В Windows [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) е включен по подразбиране, а [JAWS](https://webaim.org/articles/jaws/) и [NVDA](https://www.nvaccess.org/about-nvda/) могат също да бъдат инсталирани. В macOS и iOS [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) е инсталиран по подразбиране.
✅ Изпробвайте четец на екрана и текстов четец в браузър. В Windows [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) е включен по подразбиране, а [JAWS](https://webaim.org/articles/jaws/) и [NVDA](https://www.nvaccess.org/about-nvda/) също могат да бъдат инсталирани. В macOS и iOS [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) е инсталиран по подразбиране.
### Увеличение
Друг инструмент, който честосе използва от хорас увредено зрение, е увеличението. Най-основният тип увеличение е статично увеличение, контролирано чрез `Control + плюс (+)` или чрез намаляване на резолюцията на екрана. Този тип увеличение кара цялата страница да се преоразмери, така че използването на [отзивчив дизайн](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) е важно за предоставяне на добро потребителско изживяване при увеличени нива.
Друг инструмент, често използван от хорас увредено зрение, е увеличението. Най-основният тип увеличение е статичното увеличение, контролирано чрез `Control + плюс (+)` или чрез намаляване на резолюцията на екрана. Този тип увеличение кара цялата страница да се преоразмери, така че използването на [отзивчив дизайн](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) е важно за осигуряване на добро потребителско изживяване при увеличени нива на мащабиране.
Друг тип увеличение разчита на специализиран софтуер за увеличаване на една област от екрана и панорамно движение, подобно на използването на истинска лупа. В Windows [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) е вграден, а [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) е софтуер за увеличаване от трета странас повече функции и по-голяма потребителска база. И macOS, и iOS имат вграден софтуер за увеличаване, наречен [Zoom](https://www.apple.com/accessibility/mac/vision/).
Друг тип увеличение разчита на специализиран софтуер за увеличаване на една област от екрана и панорамиране, подобно на използването на истинска лупа. В Windows [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) е вграден, а [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) е софтуер на трета страна за увеличениес повече функции и по-голяма потребителска база. И macOS, и iOS имат вграден софтуер за увеличение, наречен [Zoom](https://www.apple.com/accessibility/mac/vision/).
### Проверка на контраста
Цветовете на уебсайтовете трябва да бъдат внимателно избрани, за да отговорят на нуждите на потребители с цветна слепота или хора, които имат затруднения с виждането на цветове с нисък контраст.
Цветовете на уебсайтовете трябва да бъдат внимателно подбрани, за да отговорят на нуждите на потребители с цветна слепота или хора, които имат затруднения с виждането на цветове с нисък контраст.
✅ Тествайте уебсайт, който харесвате, за използване на цветове с разширение за браузър като [WCAG проверка на цветовия контраст](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Какво научавате?
✅ Тествайте уебсайт, който харесвате, за използване на цветове с разширение за браузър като [проверка на цветовия контраст на WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Какво научавате?
### Lighthouse
Впанела с инструменти за разработчици на вашия браузър ще намерите инструмента Lighthouse. Този инструмент е важен за получаване на първоначален поглед върху достъпността (както и други анализи) на уебсайт. Въпреки че е важно да не разчитате изключително на Lighthouse, 100% резултат е много полезен като базова линия.
Всекцията за инструменти за разработчици на вашия браузър ще намерите инструмента Lighthouse. Този инструмент е важен за получаване на първоначален поглед върху достъпността (както и други анализи) на уебсайт. Въпреки че е важно да не разчитате изключително на Lighthouse, 100% резултат е много полезен като основа.
✅ Намерете Lighthouse в панела с инструменти за разработчици на вашия браузър и направете анализ на който и да е сайт. Какво откривате?
✅ Намерете Lighthouse в панела с инструменти за разработчици на вашия браузър и направете анализ на произволен сайт. Какво откривате?
## Дизайн с мисъл за достъпността
Достъпността е сравнително голяма тема. За да ви помогнем, има множество налични ресурси.
- [Accessible U - Университетът на Минесота](https://accessibility.umn.edu/your-role/web-developers)
- [Accessible U - Университет на Минесота](https://accessibility.umn.edu/your-role/web-developers)
Докато няма да можем да обхванем всеки аспект на създаването на достъпни сайтове, по-долу са някои от основните принципи, които ще искате да приложите. Дизайнът на достъпна страница от самото начало е**винаги** по-лесен, отколкото връщането към съществуваща страница, за да я направите достъпна.
Въпреки че няма да можем да обхванем всеки аспект на създаването на достъпни сайтове, по-долу са някои от основните принципи, които ще искате да приложите. Дизайнът на достъпна страница от самото начало е**винаги** по-лесен, отколкото да се върнете към съществуваща страница, за да я направите достъпна.
## Добри принципи за визуално представяне
## Добри принципи за визуализация
### Палитри с безопасни цветове
Хората виждат света по различни начини, включително цветовете. Когато избирате цветова схема за вашия сайт, трябва да се уверите, че тя е достъпна за всички. Един страхотен [инструмент за генериране на цветови палитри е Color Safe](http://colorsafe.co/).
Хората виждат света по различни начини, включително и цветовете. Когато избирате цветова схема за вашия сайт, трябва да се уверите, че тя е достъпна за всички. Един чудесен [инструмент за генериране на цветови палитри е Color Safe](http://colorsafe.co/).
✅ Идентифицирайте уебсайт, който е много проблематичен в използването на цветове. Защо?
@ -77,7 +77,7 @@ CO_OP_TRANSLATOR_METADATA:
С CSS и JavaScript е възможно да направите всеки елемент да изглежда като всякакъв тип контрол. `<span>` може да се използва за създаване на `<button>`, а`<b>` може да стане хипервръзка. Въпреки че това може да се счита за по-лесно за стилизиране, то не предава нищо на четец на екрана. Използвайте подходящия HTML, когато създавате контроли на страница. Ако искате хипервръзка, използвайте `<a>`. Използването на правилния HTML за правилния контрол се нарича използване на семантичен HTML.
✅ Отидете на който и да е уебсайт и вижте дали дизайнерите и разработчиците използват HTML правилно. Можете ли да намерите бутон, който трябва да бъде връзка? Подсказка: щракнете с десния бутон и изберете 'View Page Source' в браузъра си, за да видите основния код.
✅ Отидете на произволен уебсайт и вижте дали дизайнерите и разработчиците използват HTML правилно. Можете ли да намерите бутон, който трябва да бъде връзка? Подсказка: щракнете с десния бутон и изберете „Преглед на изходния код на страницата“ в браузъра си, за да разгледате основния код.
### Създайте описателна йерархия на заглавията
@ -85,43 +85,43 @@ CO_OP_TRANSLATOR_METADATA:
### Използвайте добри визуални подсказки
CSS предлага пълен контрол върху външния вид на всеки елемент на страница. Можете да създадете текстови полета без контур или хипервръзки без подчертаване. За съжаление, премахването на тези подсказки може да направи по-трудно за някой, който разчита на тях, да разпознае типа контрол.
CSS предлага пълен контрол върху външния вид на всеки елемент на страница. Можете да създадете текстови полета без контур или хипервръзки без подчертаване. За съжаление, премахването на тези подсказки може да направи по-трудно за някого, който разчита на тях, да разпознае типа на контрола.
## Важността на текста на връзките
## Значението на текста на връзките
Хипервръзките са основни за навигацията в уеб. Затова е важно четецът на екрана да може правилно да чете връзките, за да позволи на всички потребители да навигират вашия сайт.
Хипервръзките са основни за навигацията в уеба. Следователно, гарантирането, че четец на екрана може правилно да чете връзките, позволява на всички потребители да навигират във вашия сайт.
### Четци на екрана и връзки
Както бихте очаквали, четците на екрана четат текста на връзките по същия начин, както биха прочели всеки друг текст на страницата. С това предвид, текстът, показан по-долу, може да изглежда напълно приемлив.
Както бихте очаквали, четците на екрана четат текста на връзките по същия начин, по който четат всеки друг текст на страницата. С това наум, текстът, демонстриран по-долу, може да изглежда напълно приемлив.
> Малкият пингвин, понякога известен като феен пингвин, е най-малкият пингвин в света. [Щракнете тук](https://en.wikipedia.org/wiki/Little_penguin) за повече информация.
> Малкият пингвин, понякога наричан феен пингвин, е най-малкият пингвин в света. [Кликнете тук](https://en.wikipedia.org/wiki/Little_penguin) за повече информация.
> Малкият пингвин, понякога известен като феен пингвин, е най-малкият пингвин в света. Посетете https://en.wikipedia.org/wiki/Little_penguin за повече информация.
> Малкият пингвин, понякога наричан феен пингвин, е най-малкият пингвин в света. Посетете https://en.wikipedia.org/wiki/Little_penguin за повече информация.
> **NOTE** Както ще прочетете, никога не трябва да създавате връзки, които изглеждат като горните примери.
> **NOTE** Както ще прочетете по-долу, никога не трябва да създавате връзки, които изглеждат като горните.
Запомнете, четците на екрана са различен интерфейс от браузърите с различен набор от функции.
### Проблемът с използването на URL
Четците на екрана четат текста. Ако URL се появи в текста, четецът на екрана ще прочете URL. Като цяло, URL не предава значима информация и може да звучи досадно. Може би сте изпитали това, ако телефонът ви някога е прочел на глас текстово съобщение с URL.
Четците на екрана четат текста. Ако URL се появи в текста, четецът на екрана ще прочете URL. Обикновено URL не предава смислена информация и може да звучи досадно. Може би сте изпитвали това, ако телефонът ви някога е прочел на глас текстово съобщение с URL.
### Проблемът с "щракнете тук"
### Проблемът с "кликнете тук"
Четците на екрана също имат способността да четат само хипервръзките на страница, подобно на начина, по който човек с добро зрение би сканирал страница за връзки. Ако текстът на връзката винаги е "щракнете тук", потребителят ще чуе само "щракнете тук, щракнете тук, щракнете тук, щракнете тук, щракнете тук, ..." Всички връзки стават неразличими една от друга.
Четците на екрана също имат способността да четат само хипервръзките на страница, по същия начин, по който зрящ човек би сканирал страница за връзки. Ако текстът на връзката винаги е "кликнете тук", всичко, което потребителят ще чуе, е "кликнете тук, кликнете тук, кликнете тук, кликнете тук, кликнете тук, ..." Всички връзки сегаса неразличими една от друга.
### Добър текст на връзките
Добър текст на връзките накратко описва какво има от другата страна на връзката. В горния пример за малките пингвини, връзката е към страницата в Wikipedia за вида. Фразата *малки пингвини* би била перфектен текст за връзка, тъй като ясно показва какво ще научи някой, ако щракне върху връзката - малки пингвини.
Добър текст на връзките накратко описва какво има от другата страна на връзката. В горния пример за малките пингвини, връзката е към страницата в Wikipedia за вида. Фразата *малки пингвини* би била перфектен текст на връзката, тъй като ясно показва какво ще научи някой, ако кликне върху връзката - малки пингвини.
> [Малкият пингвин](https://en.wikipedia.org/wiki/Little_penguin), понякога известен като феен пингвин, е най-малкият пингвин в света.
> Малкият пингвин, понякога наричан феен пингвин, е най-малкият пингвин в света. [Малки пингвини](https://en.wikipedia.org/wiki/Little_penguin).
✅ Сърфирайте в интернет за няколко минути, за да намерите страници, които използват неясни стратегии за връзки. Сравнете ги с други, по-добре свързани сайтове. Какво научавате?
#### Бележки за търсачките
Като допълнителен бонус за гарантиране, че вашият сайт е достъпен за всички, ще помогнете на търсачките да навигират вашия сайт. Търсачките използват текста на връзките, за да научат темите на страниците. Така че използването на добър текст на връзките помага на всички!
Като допълнителен бонус за гарантиране, че вашият сайт е достъпен за всички, ще помогнете на търсачките да навигират във вашия сайт. Търсачките използват текста на връзките, за да научат темите на страниците. Така че използването на добър текст на връзките помага на всички!
### ARIA
@ -132,11 +132,11 @@ CSS предлага пълен контрол върху външния вид
В този пример дублирането на текста за описание и поръчка има смисъл за някой, който използва браузър. Въпреки това, някой, който използва четец на екрана, би чул само думите *описание* и *поръчка* повторени без контекст.
В този пример дублирането на текста на описание и поръчка има смисъл за някой, който използва браузър. Въпреки това, някой, който използва четец на екрана, ще чуе само думите *описание* и *поръчка*, повторени без контекст.
За да поддържате тези типове сценарии, HTML поддържа набор от атрибути, известни като [Достъпни богати интернет приложения (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Тези атрибути ви позволяват да предоставите допълнителна информация на четците на екрана.
> **NOTE**: Както много аспекти на HTML, поддръжката от браузъри и четци на екрана може да варира. Въпреки това, повечето основни клиенти поддържат ARIA атрибути.
> **NOTE**: Както при много аспекти на HTML, поддръжката от браузъри и четци на екрана може да варира. Въпреки това, повечето основни клиенти поддържат ARIA атрибути.
Можете да използвате `aria-label`, за да опишете връзката, когато форматът на страницата не ви позволява. Описанието за джаджа може да бъде зададено като
@ -144,7 +144,7 @@ CSS предлага пълен контрол върху външния вид
✅ Като цяло, използването на семантичен маркъп, както е описано по-горе, превъзхожда използването на ARIA, но понякога няма семантичен еквивалент за различни HTML елементи. Добър пример е дърво. Няма HTML еквивалент за дърво, така че идентифицирате общия `<div>` за този елемент с подходяща роля и ARIA стойности. [Документацията на MDN за ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) съдържа повече полезна информация.
✅ По принцип използването на семантичен HTML, както е описано по-горе, има предимство пред използването на ARIA, но понякога няма семантичен еквивалент за различни HTML елементи. Добър пример е дърво. Няма HTML еквивалент за дърво, така че идентифицирате общия `<div>` за този елемент с подходяща роля и ARIA стойности. [Документацията на MDN за ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) съдържа повече полезна информация.
```html
<h2id="tree-label">File Viewer</h2>
@ -155,14 +155,14 @@ CSS предлага пълен контрол върху външния вид
## Изображения
Очевидно е, че четците на екрана не могат автоматично да прочетат какво има в изображение. Гарантирането, че изображенията са достъпни, не изисква много работа - това е целта на атрибута `alt`. Всички значими изображения трябва да имат `alt`, за да опишат какво представляват.
Изображения, които са чисто декоративни, трябва да имат атрибута`alt`, зададен на празен низ: `alt=""`. Това предотвратява ненужното обявяване на декоративното изображение от четците на екрана.
Очевидно е, че четците на екрана не могат автоматично да четат какво има в изображение. Осигуряването на достъпност на изображенията не изисква много работа - това е целта на атрибута `alt`. Всички значими изображения трябва да имат `alt`, за да опишат какво представляват.
Изображенията, които са чисто декоративни, трябва да имат атрибут `alt`, зададен на празен низ: `alt=""`. Това предотвратява ненужното обявяване на декоративното изображение от четците на екрана.
✅ Както можете да очаквате, търсачките също не могат да разберат какво има в изображение. Те също използват alt текст. Така че отново, гарантирането, че вашата страница е достъпна, предоставя допълнителни бонуси!
✅ Както може дасе очаква, търсачките също не могат да разберат какво има в изображение. Те също използват alt текста. Така че, отново, осигуряването на достъпност на вашата страница носи допълнителни бонуси!
## Клавиатурата
Някои потребители не могат да използват мишка или тракпад, вместо това разчитат на взаимодействия с клавиатурата, за да преминават от един елемент към следващия. Важно е вашият уебсайт да представя съдържанието си в логичен ред, така че потребителят на клавиатурата да може да достъпи всеки интерактивен елемент, докато се движи надолу по документа. Ако изграждате вашите уеб страници със семанти
Някои потребители не могат да използват мишка или тъчпад, вместо това разчитат на взаимодействия с клавиатурата, за да преминават от един елемент към друг. Важно е вашият уебсайт да представя съдържанието си в логичен ред, така че потребителят на клавиатура да може да достъпи всеки интерактивен елемент, докато се движи надолу по документа. Ако изграждате вашите у
Много правителства имат закони, свързани с изискванията за достъпност. Проучете законите за достъпност във вашата страна. Какво е обхванато и какво не е? Пример за това е [този правителствен уебсайт](https://accessibility.blog.gov.uk/).
> Скица от [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест преди лекцията
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/7)
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/)
Тази лекция обхваща основите на JavaScript, езикът, който осигурява интерактивност в уеб.
Този урок обхваща основите на JavaScript, езикът, който осигурява интерактивност в уеб.
> Можете да преминете тази лекция на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)!
> Можете да преминете този урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)!
[](https://youtube.com/watch?v=JNIXfGiDWM8 "Променливи в JavaScript")
@ -35,7 +35,7 @@ CO_OP_TRANSLATOR_METADATA:
- **Ключова дума**. Ключовите думи могат да бъдат `let` или `var`.
✅ Ключовата дума `let`е въведена в ES6 и дава на променливата така наречения _блоков обхват_. Препоръчително е да използвате `let` вместо `var`. Ще разгледаме блоковите обхвати по-подробно в следващите части.
✅ Ключовата дума `let`беше въведена в ES6 и дава на променливата така наречения _блоков обхват_. Препоръчително е да използвате `let` вместо `var`. Ще разгледаме блоковите обхвати по-подробно в следващите части.
- **Името на променливата**, това е име, което избирате сами.
### Задача - работа с променливи
@ -54,7 +54,7 @@ CO_OP_TRANSLATOR_METADATA:
myVariable = 123;
```
> Забележка: използването на `=` в този урок означава, че използваме "оператор за присвояване", който задава стойност на променлива. Необозначава равенство.
> Забележка: използването на `=` в този урок означава, че използваме "оператор за присвояване", който задава стойност на променлива. Това не означава равенство.
`myVariable` вече е*инициализирана* със стойност 123.
@ -78,7 +78,7 @@ CO_OP_TRANSLATOR_METADATA:
## Константи
Декларирането и инициализацията на константа следва същите концепции като променлива, с изключение на ключовата дума `const`. Константите обикновено се декларират с главни букви.
Декларирането и инициализирането на константа следва същите концепции като променлива, с изключение на ключовата дума `const`. Константите обикновено се декларират с главни букви.
```javascript
const MY_VARIABLE = 123;
@ -102,7 +102,7 @@ const MY_VARIABLE = 123;
obj = { b: 5 } // not allowed
```
- **Стойността на обект не е защитена**. Следното Е позволено:
- **Стойността на обекта не е защитена**. Следното Е позволено:
```javascript
const obj = { a: 3 };
@ -111,13 +111,13 @@ const MY_VARIABLE = 123;
В горния пример променяте стойността на обекта, но не и самата референция, което го прави позволено.
> Забележка: `const` означава, че референцията е защитена от повторно присвояване. Стойността обаче не е_непроменяема_ и може да се промени, особено ако е сложна структура като обект.
> Забележка: `const` означава, че референцията е защитена от преназначаване. Стойността обаче не е_непроменяема_ и може да се промени, особено ако е сложна структура като обект.
## Типове данни
Променливите могат да съхраняват различни типове стойности, като числа и текст. Тези различни типове стойности са известни като **типове данни**. Типовете данни са важна част от разработката на софтуер, защото помагат на разработчиците да вземат решения как да пишат кода и как да работи софтуерът. Освен това, някои типове данни имат уникални характеристики, които помагат за трансформиране или извличане на допълнителна информация от стойност.
✅ Типовете данни също се наричат примитиви на JavaScript, тъй като са най-ниското ниво типове данни, предоставени от езика. Съществуват 7 примитивни типа данни: string, number, bigint, boolean, undefined, null и symbol. Отделете минута, за да си представите какво представлява всеки от тези примитиви. Какво е`zebra`? А`0`? `true`?
✅ Типовете данни също се наричат примитиви на JavaScript, тъй като са най-ниското ниво типове данни, предоставени от езика. Има 7 примитивни типа данни: string, number, bigint, boolean, undefined, null и symbol. Отделете минута, за да си представите какво представлява всеки от тези примитиви. Какво е`zebra`? А`0`? `true`?
### Числа
@ -129,15 +129,15 @@ const MY_VARIABLE = 123;
### Аритметични оператори
Съществуват няколко типа оператори за извършване на аритметични функции, като някои от тях са изброени тук:
Има няколко типа оператори за използване при извършване на аритметични функции, като някои от тях са изброени тук:
| `+` | **Събиране**: Изчислява сумата на две числа | `1 + 2 //очакван отговор е 3` |
| `-` | **Изваждане**: Изчислява разликата между две числа | `1 - 2 //очакван отговор е -1` |
| `*` | **Умножение**: Изчислява произведението на две числа | `1 * 2 //очакван отговор е 2` |
| `/` | **Деление**: Изчислява частното на две числа | `1 / 2 //очакван отговор е 0.5` |
| `%` | **Остатък**: Изчислява остатъка от делението на две числа | `1 % 2 //очакван отговор е 1` |
| `*` | **Умножение**: Изчислява произведението на две числа | `1 * 2 //очакван отговор е 2` |
| `/` | **Деление**: Изчислява частното на две числа | `1 / 2 //очакван отговор е 0.5` |
| `%` | **Остатък**: Изчислява остатъка от делението на две числа | `1 % 2 //очакван отговор е 1` |
✅ Опитайте! Опитайте аритметична операция в конзолата на браузъра си. Изненадват ли ви резултатите?
@ -185,7 +185,7 @@ let myString2 = "World";
### Булеви стойности
Булевите стойности могат да бъдат само две: `true` или `false`. Булевите стойности могат да помогнат за вземане на решения кои редове от кода да се изпълнят, когато са изпълнени определени условия. В много случаи [операторите](../../../../2-js-basics/1-data-types) помагат за задаване на стойността на булева променлива и често ще забелязвате и пишете променливи, които се инициализират или чиито стойности се актуализират с оператор.
Булевите стойности могат да бъдат само две: `true` или `false`. Булевите стойности помагат за вземане на решения кои редове от кода да се изпълнят, когато са изпълнени определени условия. В много случаи [операторите](../../../../2-js-basics/1-data-types) помагат за задаване на стойността на булева променлива и често ще забележите и пишете променливи, които се инициализират или чиито стойности се актуализират с оператор.
- `let myTrueBool = true`
- `let myFalseBool = false`
@ -199,7 +199,7 @@ let myString2 = "World";
JavaScript е известен със своите изненадващи начини за обработка на типове данни понякога. Направете малко проучване за тези 'изненади'. Например: чувствителността към главни и малки букви може да ви изненада! Опитайте това в конзолата си: `let age = 1; let Age = 2; age == Age` (резултатът е`false` -- защо?). Какви други изненади можете да откриете?
## Тест след лекцията
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/8)
[Тест след лекцията](https://ff-quizzes.netlify.app)
## Преглед и самостоятелно обучение
@ -212,4 +212,4 @@ JavaScript е известен със своите изненадващи нач
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Когато мислим за писане на код, винаги трябва да се стремим кодът ни да бъде четим. Макар това да звучи противоречиво, кодът се чете много повече пъти, отколкото се пише. Един от основните инструменти в арсенала на разработчика за създаване на поддържаем код е**функцията**.
Когато мислим за писане на код, винаги искаме да се уверим, че кодът ни е четим. Макар това да звучи контраинтуитивно, кодът се чете много повече пъти, отколкото се пише. Един от основните инструменти в арсенала на разработчика за осигуряване на поддържаем код е**функцията**.
[](https://youtube.com/watch?v=XgKsD6Zwvlc "Методи и функции")
> 🎥 Кликнете върху изображението по-горе за видео за методи и функции.
> 🎥 Кликнете върху изображението по-горе за видео относно методи и функции.
> Можете да вземете този урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)!
> Можете да преминете този урок на [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)!
## Функции
В основата си функцията е блок от код, който можем да изпълним при поискване. Това е идеално за ситуации, в които трябва да извършим една и съща задача многократно; вместо да дублираме логиката на различни места (което би затруднило актуализацията, когато дойде време), можем да я централизиране на едно място и да я извикваме, когато е необходимо - дори можете да извиквате функции от други функции!
В основата си функцията е блок от код, който можем да изпълним при поискване. Това е идеално за сценарии, в които трябва да извършим една и съща задача многократно; вместо да дублираме логиката на различни места (което би затруднило актуализациите), можем да я централизиране на едно място и да я извикваме, когато е необходимо - дори можете да извиквате функции от други функции!
Също толкова важно е възможността да дадем име на функцията. Макар това да изглежда тривиално, името предоставя бърз начин за документиране на част от кода. Можете да го сравните с етикет на бутон. Ако кликна върху бутон с надпис "Отмени таймера", знам, че той ще спре часовника.
Също толкова важно еи възможността да дадем име на функция. Макар това да изглежда тривиално, името предоставя бърз начин за документиране на част от кода. Можете да го сравните с етикет на бутон. Ако кликна върху бутон с надпис "Отмяна на таймера", знам, че ще спре да работи таймерът.
## Създаване и извикване на функция
@ -47,28 +47,28 @@ function displayGreeting() {
}
```
Когато искаме да извикаме (или изпълним) нашата функция, използваме името на функцията, последвано от `()`. Струва си да отбележим, че функцията ни може да бъде дефинирана преди или след като решим да я извикаме; компилаторът на JavaScript ще я намери вместо нас.
Когато искаме да извикаме (или изпълним) нашата функция, използваме името на функцията, последвано от `()`. Струва си да сеотбележи, че функцията ни може да бъде дефинирана преди или след като решим да я извикаме; JavaScript компилаторът ще я намери вместо вас.
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** Съществува специален тип функция, известен като **метод**, който вече сте използвали! Всъщност, видяхме това в нашия пример по-горе, когато използвахме `console.log`. Това, което прави метода различен от функцията, е, че методът е прикрепен към обект (`console` в нашия пример), докато функцията е свободно плаваща. Ще чуете много разработчици да използват тези термини взаимозаменяемо.
> **NOTE:** Съществува специален тип функция, известен като **метод**, който вече сте използвали! Всъщност видяхме това в нашия пример по-горе, когато използвахме `console.log`. Това, което прави метода различен от функцията, е, че методът е прикрепен към обект (`console` в нашия пример), докато функцията е свободно плаваща. Много разработчици използват тези термини взаимозаменяемо.
### Най-добри практики за функции
Има няколко добри практики, които трябва да имате предвид при създаването на функции:
- Както винаги, използвайте описателни имена, за да знаете какво ще прави функцията
- Използвайте **camelCasing**, за да комбинирате думи
- Дръжте функциите си фокусирани върху конкретна задача
- Както винаги, използвайте описателни имена, за да знаете какво ще прави функцията.
- Използвайте **camelCasing**, за да комбинирате думи.
- Дръжте функциите си фокусирани върху конкретна задача.
## Предаване на информация на функция
За да направите функцията по-универсална, често ще искате да предавате информация на нея. Ако разгледаме нашия пример `displayGreeting` по-горе, той ще показва само **Hello, world!**. Нее най-полезната функция, която бихме могли да създадем. Ако искаме да я направим малко по-гъвкава, например да позволим на някого да посочи името на човека, който да поздравим, можем да добавим **параметър**. Параметърът (понякога наричан и **аргумент**) е допълнителна информация, изпратена на функцията.
За да направите функцията по-универсална, често ще искате да ѝ предавате информация. Ако разгледаме примерас`displayGreeting` по-горе, той ще показва само **Hello, world!**. Нее най-полезната функция, която бихме могли да създадем. Ако искаме да я направим малко по-гъвкава, например да позволим на някого да посочи името на човека, когото поздравяваме, можем да добавим **параметър**. Параметърът (понякога наричан и **аргумент**) е допълнителна информация, изпратена на функцията.
Параметрите се изброяват в частта за дефиниция в скоби и са разделени със запетаи, както следва:
Параметрите се изброяват в дефиницията в скоби и са разделени със запетаи, както следва:
```javascript
function name(param, param2, param3) {
@ -76,7 +76,7 @@ function name(param, param2, param3) {
}
```
Можем да актуализираме нашия `displayGreeting`, за да приема име и да го показва.
Можем да актуализираме `displayGreeting`, за да приема име и да го показва.
```javascript
function displayGreeting(name) {
@ -85,7 +85,7 @@ function displayGreeting(name) {
}
```
Когато искаме да извикаме нашата функция и да предадем параметъра, го посочваме в скобите.
Когато искаме да извикаме функцията и да предадем параметъра, го посочваме в скобите.
```javascript
displayGreeting('Christopher');
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## Стойности по подразбиране
Можем да направим функцията си още по-гъвкава, като добавим повече параметри. Но какво, ако не искаме да изискваме всяка стойност да бъде посочена? В съответствие с нашия пример за поздрав, можем да оставим името като задължително (трябва да знаем кого поздравяваме), но искаме да позволим поздравът да бъде персонализиран, ако желаем. Ако някой не иска да го персонализира, предоставяме стойност по подразбиране. За да зададем стойност по подразбиране на параметър, го задаваме по същия начин, както задаваме стойност на променлива - `parameterName = 'defaultValue'`. За да видите пълен пример:
Можем да направим функцията си още по-гъвкава, като добавим повече параметри. Но какво, ако не искаме да изискваме всяка стойност да бъде зададена? В примера с поздравите можем да оставим името като задължително (трябва да знаем кого поздравяваме), но искаме да позволим поздравът да бъде персонализиран по желание. Ако някой не иска да го персонализира, предоставяме стойност по подразбиране. За да зададем стойност по подразбиране на параметър, го задаваме по същия начин, по който задаваме стойност на променлива - `parameterName = 'defaultValue'`. Ето пълен пример:
```javascript
function displayGreeting(name, salutation='Hello') {
Досега функцията, която създадохме, винаги ще извежда резултата в [конзолата](https://developer.mozilla.org/docs/Web/API/console). Понякога това може да е точно това, което търсим, особено когато създаваме функции, които ще извикват други услуги. Но какво, ако искам да създам помощна функция за извършване на изчисление и да върна стойността обратно, за да мога да я използвам другаде?
Досега създадените от нас функции винаги извеждаха резултата в [конзолата](https://developer.mozilla.org/docs/Web/API/console). Понякога това може да е точно това, което търсим, особено когато създаваме функции, които ще извикват други услуги. Но какво, ако искам да създам помощна функция за извършване на изчисление и да върна стойността, за да я използвам другаде?
Можем да направим това, като използваме **връщана стойност**. Връщаната стойност се връща от функцията и може да бъде съхранена в променлива, точно както бихме могли да съхраним буквална стойност като низ или число.
Можем да направим това, като използваме **върната стойност**. Върнатата стойност се връща от функцията и може да бъде съхранена в променлива по същия начин, по който бихме съхранили буквална стойност като низ или число.
Ако функцията връща нещо, тогава се използва ключовата дума `return`. Ключовата дума `return` очаква стойност или референция на това, което се връща, както следва:
Можем да създадем функция за създаване на поздравително съобщение и да върнем стойността обратно на извикващия.
Можем да създадем функция за създаване на поздравително съобщение и да върнем стойността на извикващия.
```javascript
function createGreetingMessage(name) {
@ -133,7 +133,7 @@ function createGreetingMessage(name) {
}
```
Когато извикваме тази функция, ще съхраним стойността в променлива. Това емного подобно на начина, по който бихме задали променлива на статична стойност (като `const name = 'Christopher'`).
Когато извикваме тази функция, ще съхраним стойността в променлива. Това есъщото, както бихме задали променлива на статична стойност (като `const name = 'Christopher'`).
С напредването на вашата програмистка кариера ще срещнете функции, които приемат функции като параметри. Този интересен трик често се използва, когато не знаем кога нещо ще се случи или завърши, но знаем, че трябва да извършим операция в отговор.
С напредването в програмирането ще срещнете функции, които приемат други функции като параметри. Този удобен трик често се използва, когато не знаем кога нещо ще се случи или завърши, но знаем, че трябва да извършим операция в отговор.
Като пример, разгледайте [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), който започва таймер и ще изпълни код, когато завърши. Трябва да му кажем какъв код искаме да изпълни. Звучи като идеална работа за функция!
Например, разгледайте [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), който стартира таймер и изпълнява код, когато той приключи. Трябва да му кажем какъв код искаме да изпълни. Звучи като перфектна работа за функция!
Ако изпълните кода по-долу, след 3 секунди ще видите съобщението **3 секунди изминаха**.
Ако изпълните кода по-долу, след 3 секунди ще видите съобщението **3 секунди изтекоха**.
```javascript
function displayDone() {
@ -157,9 +157,9 @@ setTimeout(displayDone, 3000);
### Анонимни функции
Нека разгледаме още веднъж това, което създадохме. Създаваме функция с име, която ще бъде използвана само веднъж. С усложняването на нашето приложение можем да видим как създаваме много функции, които ще бъдат извикани само веднъж. Това не е идеално. Оказва се, че не винаги трябва да предоставяме име!
Нека разгледаме отново това, което създадохме. Създаваме функция с име, която ще бъде използвана само веднъж. С усложняването на приложението можем да се окажем с много функции, които ще бъдат извикани само веднъж. Това не е идеално. Оказва се, че не винаги е необходимо да предоставяме име!
Когато предаваме функция като параметър, можем да пропуснем създаването ѝ предварително и вместо това да я изградим като част от параметъра. Използваме същата ключова дума `function`, но вместо това я изграждаме като параметър.
Когато предаваме функция като параметър, можем да пропуснем предварителното ѝ създаване и вместо това да я изградим като част от параметъра. Използваме същата ключова дума `function`, но я изграждаме като параметър.
Нека пренапишем кода по-горе, за да използваме анонимна функция:
@ -173,9 +173,9 @@ setTimeout(function() {
### Функции със стрелки
Един от съкратените начини, често срещан в много програмни езици (включително JavaScript), е възможността да използваме така наречената **стрелка** или **дебела стрелка** функция. Тя използва специален индикатор `=>`, който изглежда като стрелка - оттук и името! С използването на `=>` можем да пропуснем ключовата дума `function`.
Един от съкратените начини, често срещани в много програмни езици (включително JavaScript), е възможността да използваме така наречената **стрелкова** или **дебела стрелкова** функция. Тя използва специален индикатор `=>`, който изглежда като стрелка - оттук и името! С използването на `=>` можем да пропуснем ключовата дума `function`.
Нека пренапишем кода още веднъж, за да използваме функция със стрелка:
Нека пренапишем кода си още веднъж, за да използваме стрелкова функция:
```javascript
setTimeout(() => {
@ -185,7 +185,7 @@ setTimeout(() => {
### Кога да използваме всяка стратегия
Вече видяхте, че имаме три начина да предадем функция като параметър и може би се чудите кога да използвате всеки от тях. Ако знаете, че ще използвате функцията повече от веднъж, създайте я по нормалния начин. Ако ще я използвате само за едно място, обикновено е най-добре да използвате анонимна функция. Дали ще използвате функция със стрелка или по-традиционния синтаксис с`function` зависи от вас, но ще забележите, че повечето съвременни разработчици предпочитат `=>`.
Вече видяхте, че имаме три начина да предадем функция като параметър и може би се чудите кога да използвате всеки от тях. Ако знаете, че ще използвате функцията повече от веднъж, създайте я по обичайния начин. Ако ще я използвате само на едно място, обикновено е най-добре да използвате анонимна функция. Дали ще използвате стрелкова функция или по-традиционния синтаксис с`function`, зависи от вас, но ще забележите, че повечето съвременни разработчици предпочитат `=>`.
---
@ -194,13 +194,13 @@ setTimeout(() => {
Можете ли да обясните с едно изречение разликата между функции и методи? Опитайте!
## Тест след лекцията
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/10)
[Тест след лекцията](https://ff-quizzes.netlify.app)
## Преглед и самостоятелно обучение
Струва си [да прочетете малко повече за функциите със стрелки](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), тъй като те все повече се използват в кодовите бази. Практикувайте писането на функция, а след това я пренапишете с този синтаксис.
Струва си да [прочетете малко повече за стрелковите функции](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), тъй като те все повече се използват в кодовите бази. Практикувайте писането на функция и след това я пренапишете с този синтаксис.

> Скица от [Tomomi Imura](https://twitter.com/girlie_mac)
> Скетч от [Tomomi Imura](https://twitter.com/girlie_mac)
## Тест преди лекцията
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/11)
Вземането на решения и контролирането на реда, в който се изпълнява кодът ви, прави вашия код по-гъвкав и надежден. Тази секция обхваща синтаксиса за контролиране на потока от данни в JavaScript и неговото значение, когато се използва с булеви типове данни.
Вземането на решения и контролирането на реда, в който се изпълнява кодът ви, прави вашия код по-гъвкав и надежден. Тази секция обхваща синтаксиса за контролиране на потока от данни в JavaScript и значението му, когато се използва с булеви типове данни.
[](https://youtube.com/watch?v=SxTp8j-fMMY "Вземане на решения")
@ -27,7 +27,7 @@ CO_OP_TRANSLATOR_METADATA:
## Кратко припомняне за булевите стойности
Булевите стойности могат да имат само две стойности: `true` или `false`. Те помагат при вземането на решения кои редове от кода да се изпълнят, когато са изпълнени определени условия.
Булевите стойности могат да имат само две стойности: `true` или `false`. Те помагат да се вземат решения кои редове от кода да се изпълнят, когато са изпълнени определени условия.
Задайте булева стойност като `true` или `false` по следния начин:
@ -47,7 +47,7 @@ CO_OP_TRANSLATOR_METADATA:
| `>` | **По-голямо от**: Сравнява две стойности и връща булева стойност `true`, ако стойността отляво е по-голяма от тази отдясно | `5 > 6 // false` |
| `>=` | **По-голямо или равно на**: Сравнява две стойности и връща булева стойност `true`, ако стойността отляво е по-голяма или равна на тази отдясно | `5 >= 6 // false` |
| `===` | **Строго равенство**: Сравнява две стойности и връща булева стойност `true`, ако стойностите отляво и отдясно са равни И са от един и същ тип данни | `5 === 6 // false` |
| `!==` | **Неравенство**: Сравнява две стойности и връща противоположната булева стойност на това, което би върнал операторът за строго равенство | `5 !== 6 // true` |
| `!==` | **Неравенство**: Сравнява две стойности и връща обратната булева стойност на това, което би върнал операторът за строго равенство | `5 !== 6 // true` |
✅ Проверете знанията си, като напишете няколко сравнения в конзолата на браузъра си. Изненадва ли ви някой от върнатите резултати?
@ -137,7 +137,7 @@ console.log(`The value is ${a}`);
| `&&` | **Логическо И**: Сравнява две булеви израза. Връща `true`**само** ако и двете страни са верни | `(5 > 6) && (5 < 6 ) // Едната страна е невярна, другата е вярна. Връща false` |
| `\|\|` | **Логическо ИЛИ**: Сравнява две булеви израза. Връща `true`, ако поне едната страна е вярна | `(5 > 6) \|\| (5 < 6) // Едната страна е невярна, другата е вярна. Връща true` |
| `!` | **Логическо НЕ**: Връща противоположната стойност на булев израз | `!(5 > 6) // 5 не е по-голямо от 6, но "!" ще върне true` |
| `!` | **Логическо НЕ**: Връща обратната стойност на булев израз | `!(5 > 6) // 5 не е по-голямо от 6, но "!" ще върне true` |
## Условия и решения с логически оператори
@ -218,7 +218,7 @@ if (firstNumber > secondNumber) {
## Преглед и самостоятелно обучение
Прочетете повече за многото оператори, достъпни за потребителя, [в MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators).
Прочетете повече за многото оператори, достъпни за потребителя, [на MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators).
Разгледайте чудесния [справочник за оператори](https://joshwcomeau.com/operator-lookup/) на Джош Комо!
@ -229,4 +229,4 @@ if (firstNumber > secondNumber) {
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.

> Скетч от [Tomomi Imura](https://twitter.com/girlie_mac)
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/13)
Този урок обхваща основите на JavaScript, езикът, който осигурява интерактивност в уеб. В този урок ще научите за масиви и цикли, които се използват за манипулиране на данни.
Тази лекция обхваща основите на JavaScript - езикът, който осигурява интерактивност в уеб. В този урок ще научите за масивите и циклите, които се използват за манипулиране на данни.
Работата с данни е често срещана задача за всеки език, и тя става много по-лесна, когато данните са организирани в структурен формат, като масиви. С масиви данните се съхраняват в структура, подобна на списък. Едно от основните предимства на масивите е, че можете да съхранявате различни типове данни в един масив.
Работата с данни е често срещана задача за всеки програмен език, а тя става много по-лесна, когато данните са организирани в структурен формат, като например масиви. С масивите данните се съхраняват в структура, подобна на списък. Едно от основните предимства на масивите е, че можете да съхранявате различни типове данни в един масив.
✅ Масивите са навсякъде около нас! Можете ли да измислите пример от реалния живот за масив, като например масив от слънчеви панели?
✅ Масивите са навсякъде около нас! Можете ли да се сетите за реален пример за масив, като например масив от слънчеви панели?
Синтаксисът за масив е чифт квадратни скоби.
@ -43,28 +43,28 @@ let myArray = [];
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
Стойностите в масива получават уникална стойност, наречена **индекс**, цяло число, което се определя въз основа на разстоянието му от началото на масива. Вгорния пример стринговата стойност "Chocolate" има индекс 0, а индексът на "Rocky Road" е 4. Използвайте индекса с квадратни скоби, за да извлечете, промените или добавите стойности в масива.
Стойностите в масива получават уникална стойност, наречена **индекс**, която е цяло число, определено въз основа на разстоянието му от началото на масива. Впримера по-горе, стринговата стойност "Chocolate" има индекс 0, а индексът на "Rocky Road" е 4. Използвайте индекса с квадратни скоби, за да извличате, променяте или добавяте стойности в масива.
✅ Изненадва ли ви, че масивите започват от индекс нула? В някои програмни езици индексите започват от 1. Има интересна история за това, която можете да [прочетете в Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering).
✅ Изненадва ли ви, че индексите на масивите започват от нула? В някои програмни езици индексите започват от 1. Има интересна история за това, която можете да [прочетете в Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering).
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors[2]; //"Vanilla"
```
Можете да използвате индекса, за да промените стойност, като това:
Можете да използвате индекса, за да промените стойност, като например:
```javascript
iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan"
```
И можете да добавите нова стойност на даден индекс, като това:
И можете да добавите нова стойност на даден индекс по следния начин:
✅ По-често срещан начин за добавяне на стойности в масив е чрез оператори като array.push().
✅ По-често срещан начин за добавяне на стойности към масив е чрез използване на оператори като array.push().
За да разберете колко елемента има в масива, използвайте свойството `length`.
@ -77,14 +77,14 @@ iceCreamFlavors.length; //5
## Цикли
Циклите ни позволяват да изпълняваме повтарящи се или **итеративни** задачи и могат да спестят много време и код. Всяка итерация може да се различава по своите променливи, стойности и условия. В JavaScript има различни видове цикли, които имат малки разлики, но по същество правят едно и също: обхождат данни.
Циклите ни позволяват да изпълняваме повтарящи се или **итеративни** задачи и могат да спестят много време и код. Всяка итерация може да варира по своите променливи, стойности и условия. В JavaScript има различни видове цикли, които имат малки разлики, но по същество правят едно и също нещо: обхождат данни.
### For цикъл
Цикълът `for` изисква 3 части, за да се изпълни:
- `counter` Променлива, която обикновено се инициализира с число, което брои итерациите
- `counter` Променлива, която обикновено се инициализира с число и брои итерациите
- `condition` Израз, който използва оператори за сравнение, за да спре цикъла, когато стане `false`
- `iteration-expression` Изпълнява се в края на всяка итерация, обикновено се използва за промяна на стойността на брояча
- `iteration-expression` Изпълнява се в края на всяка итерация, обикновено за промяна на стойността на брояча
```javascript
// Counting up to 10
@ -97,7 +97,7 @@ for (let i = 0; i < 10; i++) {
### While цикъл
За разлика от синтаксиса на цикъла `for`, цикълът `while` изисква само условие, което ще спре цикъла, когато условието стане `false`. Условията в циклите обикновено зависят от други стойности като броячи и трябва да се управляват по време на цикъла. Началните стойности за броячите трябва да се създадат извън цикъла, а всички изрази за изпълнение на условието, включително промяната на брояча, трябва да се поддържат вътре в цикъла.
За разлика от синтаксиса на `for` цикъла, `while` цикълът изисква само условие, което ще спре цикъла, когато стане `false`. Условията в циклите обикновено зависят от други стойности като броячи и трябва да се управляват по време на цикъла. Началните стойности за броячите трябва да бъдат създадени извън цикъла, а всички изрази за изпълнение на условието, включително промяната на брояча, трябва да се поддържат вътре в цикъла.
```javascript
//Counting up to 10
@ -110,7 +110,7 @@ while (i < 10) {
✅ Защо бихте избрали for цикъл вместо while цикъл? 17 хиляди потребители имаха същия въпрос в StackOverflow, а някои от мненията [може да ви бъдат интересни](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript).
## Цикли и масиви
## Цикли и Масиви
Масивите често се използват с цикли, защото повечето условия изискват дължината на масива, за да спрат цикъла, а индексът може също да бъде стойността на брояча.
@ -128,18 +128,18 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
## 🚀 Предизвикателство
Има и други начини за обхождане на масиви освен for и while цикли. Съществуват [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) и [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Пренапишете вашия цикъл за масив, използвайки една от тези техники.
Има и други начини за обхождане на масиви освен for и while цикли. Съществуват [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) и [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Пренапишете цикъла си за масив, използвайки една от тези техники.
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/14)
## Преглед и самостоятелно обучение
## Преглед и Самостоятелно Учение
Масивите в JavaScript имат много методи, които са изключително полезни за манипулиране на данни. [Прочетете за тези методи](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) и изпробвайте някои от тях (като push, pop, slice и splice) върху масив, който сте създали.
HTML, или HyperText Markup Language, е„скелетът“ на уеба. Ако CSS „облича“ вашия HTML, а JavaScript го „съживява“, то HTML е тялото на вашето уеб приложение. Синтаксисът на HTML дори отразява тази идея, тъй като включва тагове като "head", "body" и "footer".
HTML, или HyperText Markup Language, е"скелетът" на уеба. Ако CSS "облича" вашия HTML, а JavaScript го "оживява", то HTML е тялото на вашето уеб приложение. Синтаксисът на HTML дори отразява тази идея, като включва тагове като "head", "body" и "footer".
В този урок ще използваме HTML, за да изградим „скелета“ на интерфейса на нашия виртуален терариум. Той ще има заглавие и три колони: дясна и лява колона, където ще се намират плъзгащите се растения, и централна зона, която ще представлява самия стъклен терариум. До края на този урок ще можете да видите растенията в колоните, но интерфейсът ще изглежда малко странно; не се притеснявайте, в следващата секция ще добавим CSS стилове, за да направим интерфейса по-привлекателен.
В този урок ще използваме HTML, за да създадем "скелета" на интерфейса на нашия виртуален терариум. Той ще има заглавие и три колони: дясна и лява колона, където ще се намират плъзгащите се растения, и централна зона, която ще представлява самия стъклен терариум. До края на този урок ще можете да видите растенията в колоните, но интерфейсът ще изглежда малко странно; не се притеснявайте, в следващата секция ще добавим CSS стилове, за да гонаправим по-привлекателен.
### Задача
На вашия компютър създайте папка с име 'terrarium' и вътре в нея файл с име 'index.html'. Можете да направите това във Visual Studio Code, след като създадете папката 'terrarium', като отворите нов прозорец на VS Code, кликнете върху 'open folder' и навигирате до новата папка. Кликнете върху малкия бутон 'file' в панела Explorer и създайте новия файл:
На вашия компютър създайте папка с име 'terrarium' и в нея файл с име 'index.html'. Можете да направите това във Visual Studio Code, като отворите нов прозорец на VS Code, кликнете върху 'open folder' и навигирате до новата си папка. Кликнете върху малкия бутон 'file' в панела Explorer и създайте новия файл:

@ -41,17 +41,17 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
* `touch index.html`
* `code index.html` или `nano index.html`
> Файловете index.html указват на браузъра, че това е основният файл в папката; URL адреси като `https://anysite.com/test` може да са изградени с папка, наречена `test`, която съдържа`index.html`; `index.html` не е задължително да се показва в URL адреса.
> Файловете index.html указват на браузъра, че това е основният файл в папката; URL адреси като `https://anysite.com/test` може да са изградени с папка, наречена `test`, в която се намира`index.html`; `index.html` не е задължително да се показва в URL адреса.
---
## DocType и html тагове
Първият ред на HTML файл е неговият doctype. Малкое изненадващо, че трябва да имате този ред най-отгоре на файла, но той указва на по-старите браузъри, че страницата трябва да се рендерира в стандартен режим, следвайки текущата HTML спецификация.
Първият ред в HTML файл е неговият doctype. Може дае изненадващо, че трябва да имате този ред най-отгоре на файла, но той указва на по-старите браузъри, че страницата трябва да се рендерира в стандартен режим, следвайки текущата HTML спецификация.
> Съвет: във VS Code можете да задържите курсора върху таг и да получите информация за неговото използване от MDN Reference guides.
> Съвет: във VS Code можете да задържите курсора върху таг, за да получите информация за неговото използване от MDN Reference guides.
Вторият ред трябва да бъде отварящият `<html>` таг, следван веднага от затварящия таг `</html>`. Тези тагове саосновните елементи на вашия интерфейс.
Вторият ред трябва да бъде отварящият таг `<html>`, последван веднага от затварящия таг `</html>`. Тези тагове сакореновите елементи на вашия интерфейс.
### Задача
@ -62,23 +62,23 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
<html></html>
```
✅ Има няколко различни режима, които могат да бъдат определени чрез задаване на DocType с низ за заявка: [Quirks Mode и Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Тези режими се използваха за поддръжка на много стари браузъри, които вече не се използват често (като Netscape Navigator 4 и Internet Explorer 5). Можете да се придържате към стандартната декларация за doctype.
✅ Има няколко различни режима, които могат да бъдат определени чрез задаване на DocType с низ за заявка: [Quirks Mode и Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Тези режими са създадени за поддръжка на много стари браузъри, които вече почти не се използват (Netscape Navigator 4 и Internet Explorer 5). Можете да се придържате към стандартната декларация за doctype.
---
## 'head' на документа
Зоната 'head' на HTML документа включва важна информация за вашата уеб страница, известна също като [метаданни](https://developer.mozilla.org/docs/Web/HTML/Element/meta). В нашия случай казваме на уеб сървъра, към който тази страница ще бъде изпратена за рендериране, следните четири неща:
Зоната 'head' в HTML документа включва важна информация за вашата уеб страница, известна също като [метаданни](https://developer.mozilla.org/docs/Web/HTML/Element/meta). В нашия случай ще кажем на уеб сървъра, към който ще бъде изпратена страницата за рендериране, следните четири неща:
- заглавието на страницата
- метаданни на страницата, включително:
- 'character set', който указва какво кодиране на символите се използва на страницата
- 'character set', указващ какво кодиране на символите се използва на страницата
- информация за браузъра, включително `x-ua-compatible`, който указва, че се поддържа браузърът IE=edge
- информация за това как трябва да се държи viewport при зареждане. Задаването на viewport с начален мащаб 1 контролира нивото на увеличение при първоначалното зареждане на страницата.
### Задача
Добавете блок 'head' към вашия документ между отварящия и затварящия `<html>` таг.
Добавете блок 'head' към вашия документ между отварящия и затварящия таг `<html>`.
```html
<head>
@ -97,7 +97,7 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
### HTML тагове
В HTML добавяте тагове към вашия .html файл, за да създадете елементи на уеб страницата. Всеки таг обикновено има отварящ и затварящ таг, като този: `<p>hello</p>`, за да обозначи параграф. Създайте тялото на вашия интерфейс, като добавите комплект `<body>` тагове вътре в двойката `<html>` тагове; вашият код сега изглежда така:
В HTML добавяте тагове към вашия .html файл, за да създадете елементи на уеб страница. Всеки таг обикновено има отварящ и затварящ таг, като този: `<p>hello</p>`, за да обозначи параграф. Създайте тялото на вашия интерфейс, като добавите комплект от `<body>` тагове вътре в двойката `<html>` тагове; вашият код сега изглежда така:
### Задача
@ -120,11 +120,11 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
Един HTML таг, който не се нуждае от затварящ таг, е`<img>`, защото той има елемент `src`, който съдържа цялата информация, необходима на страницата, за да рендерира елемента.
Създайте папка във вашето приложение, наречена `images`, и в нея добавете всички изображения от [папката с изходен код](../../../../3-terrarium/solution/images); (има 14 изображения на растения).
Създайте папка в приложението си, наречена `images`, и в нея добавете всички изображения от [папката с изходен код](../../../../3-terrarium/solution/images); (има 14 изображения на растения).
### Задача
Добавете тези изображения на растения в две колони между `<body></body>` таговете:
Добавете тези изображения на растения в две колони между таговете `<body></body>`:
```html
<divid="page">
@ -177,11 +177,11 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
</div>
```
> Забележка: Spans срещу Divs. Divs се считат за 'блокови' елементи, а Spans са 'вградени'. Какво би се случило, ако преобразувате тези divs в spans?
> Забележка: Spans срещу Divs. Divs се считат за 'блокови' елементи, а Spans са 'вградени'. Какво би се случило, ако трансформирате тези divs в spans?
С този код растенията вече се показват на екрана. Изглежда доста зле, защото все още не са стилизирани с CSS, но ще направим това в следващия урок.
Всяко изображение има alt текст, който ще се появи, дори ако не можете да видите или рендерирате изображение. Това е важен атрибут за включване за достъпност. Научете повече за достъпността в бъдещи уроци; засега запомнете, че атрибутът alt предоставя алтернативна информация за изображение, ако потребителят по някаква причина не може да го види (поради бавна връзка, грешка в атрибута src или ако потребителят използва екранен четец).
Всяко изображение има alt текст, който ще се появи, дори ако не можете да видите или рендерирате изображение. Това е важен атрибут за включване за достъпност. Научете повече за достъпността в бъдещи уроци; засега запомнете, че атрибутът alt предоставя алтернативна информация за изображение, ако потребителят по някаква причина не може да го види (поради бавна връзка, грешка в атрибута src или ако потребителят използва четец на екрана).
✅ Забелязахте ли, че всяко изображение има един и същ alt таг? Добра практика ли е това? Защо или защо не? Можете ли да подобрите този код?
@ -189,17 +189,17 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
## Семантичен код
По принцип е за предпочитане да използвате смислени 'семантики', когато пишете HTML. Какво означава това? Това означава, че използвате HTML тагове, за да представите типа данни или взаимодействие, за които са предназначени. Например, основният заглавен текст на страница трябва да използва `<h1>` таг.
По принцип е за предпочитане да използвате смислени 'семантики', когато пишете HTML. Какво означава това? Това означава, че използвате HTML тагове, за да представите типа данни или взаимодействие, за които са предназначени. Например, основният текст на заглавието на страница трябва да използва таг `<h1>`.
Добавете следния ред точно под отварящия `<body>` таг:
Добавете следния ред точно под отварящия таг `<body>`:
```html
<h1>My Terrarium</h1>
```
Използването на семантичен код, като например заглавия `<h1>` и неупорядъчени списъци `<ul>`, помага на екранните четци да навигират през страницата. По принцип бутоните трябва да бъдат написани като `<button>`, а списъците като `<li>`. Въпреки че е_възможно_ да използвате специално стилизирани `<span>` елементи с обработчици на кликвания, за да имитирате бутони, е по-добре за потребителите с увреждания да използват технологии, които определят къде на страницата се намира бутонът и да взаимодействат с него, ако елементът се появява като бутон. Поради тази причина се опитвайте да използвате семантичен код, колкото е възможно повече.
Използването на семантичен код, като например заглавия `<h1>` и неупорядочени списъци `<ul>`, помага на четците на екрана да навигират през страницата. По принцип бутоните трябва да бъдат написани като `<button>`, а списъците като `<li>`. Въпреки че е_възможно_ да използвате специално стилизирани `<span>` елементи с обработчици на кликвания, за да имитирате бутони, е по-добре за потребителите с увреждания да използват технологии, за да определят къде на страницата се намира бутон и да взаимодействат с него, ако елементът се появява като бутон. Поради тази причина се опитвайте да използвате семантичен код колкото е възможно повече.
✅ Разгледайте екранен четец и [как той взаимодейства суеб страница](https://www.youtube.com/watch?v=OUDV1gqs9GA). Можете ли да видите защо несемантичният код може да разочарова потребителя?
✅ Разгледайте четец на екрана и [как той взаимодейства суеб страница](https://www.youtube.com/watch?v=OUDV1gqs9GA). Можете ли да видите защо несемантичният код може да разочарова потребителя?
## Терариумът
@ -207,7 +207,7 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
### Задача:
Добавете този код над последния `</div>` таг:
Добавете този код над последния таг `</div>`:
```html
<divid="terrarium">
@ -221,13 +221,13 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
</div>
```
✅ Въпреки че добавихте този код към екрана, не виждате абсолютно нищо да се рендерира. Защо?
✅ Въпреки че добавихте този код на екрана, не виждате абсолютно нищо да се рендерира. Защо?
---
## 🚀Предизвикателство
Има някои стари 'по-стари' тагове в HTML, които все още са забавни за използване, въпреки че не трябва да използвате остарели тагове като [тези тагове](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) във вашия код. Все пак, можете ли да използвате стария `<marquee>` таг, за да накарате заглавието h1 да се движи хоризонтално? (ако го направите, не забравяйте да го премахнете след това)
Има някои стари 'по-странни' тагове в HTML, които все още са забавни за използване, въпреки че не трябва да използвате остарели тагове като [тези тагове](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) във вашия код. Все пак, можете ли да използвате стария `<marquee>` таг, за да накарате заглавието h1 да се движи хоризонтално? (ако го направите, не забравяйте да го премахнете след това)
## Тест след лекцията
@ -235,15 +235,15 @@ HTML, или HyperText Markup Language, е „скелетът“ на уеба.
## Преглед и самостоятелно обучение
HTML е„изпитаната и вярна“ система за изграждане, която е помогнала за изграждането на уеба в това, което е днес. Научете малко за неговата история, като изучите някои стари и нови тагове. Можете ли да разберете защо някои тагове са били остарели, а други добавени? Какви тагове може да бъдат въведени в бъдеще?
HTML е"изпитаната и вярна" система за изграждане, която е помогнала за изграждането на уеба в това, което е днес. Научете малко за неговата история, като изучите някои стари и нови тагове. Можете ли да разберете защо някои тагове са били премахнати, а други добавени? Какви тагове може да бъдат въведени в бъдеще?
Научете повече за изграждането на сайтове за уеб и мобилни устройства в [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
## Задание
[Практикувайте HTML: Създайте макет на блог](assignment.md)
[Практикувайте вашия HTML: Създайте макет на блог](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
CSS, или Cascading Style Sheets, решава важен проблем в уеб разработката: как да направите вашия уебсайт да изглежда добре. Стилизирайки вашите приложения, ги правите по-удобни за използване и по-привлекателни; също така можете да използвате CSS за създаване на Responsive Web Design (RWD) - което позволява вашите приложения да изглеждат добре, независимо от размера на екрана, на който се показват. CSS не е само за външния вид на приложението; спецификацията му включва анимации и трансформации, които могат да осигурят сложни взаимодействия за вашите приложения. CSS Работната група помага за поддържането на актуалните CSS спецификации; можете да следите тяхната работа на [сайта на World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
CSS, или Cascading Style Sheets, решава важен проблем в уеб разработката: как да направите вашия уебсайт да изглежда добре. Стилизирайки вашите приложения, те стават по-удобни за използване и по-привлекателни; можете също да използвате CSS за създаване на Responsive Web Design (RWD) - позволявайки на вашите приложения да изглеждат добре независимо от размера на екрана, на който се показват. CSS не е само за визуалната част; спецификацията му включва анимации и трансформации, които могат да създадат сложни взаимодействия за вашите приложения. Работната група за CSS помага за поддържането на актуалните спецификации на CSS; можете да следите тяхната работа на [сайта на World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
> Забележка: CSS е език, който се развива, както всичко в уеб пространството, и не всички браузъри поддържат по-новите части от спецификацията. Винаги проверявайте вашите реализации, като се консултирате с [CanIUse.com](https://caniuse.com).
В този урок ще добавим стилове към нашия онлайн терариум и ще научим повече за няколко CSS концепции: каскадност, наследяване, използване на селектори, позициониране и използване на CSS за изграждане на оформления. В процеса ще подредим терариума и ще създадем самия терариум.
В този урок ще добавим стилове към нашия онлайн терариум и ще научим повече за няколко концепции на CSS: каскадата, наследяването, използването на селектори, позиционирането и използването на CSS за изграждане на оформления. В процеса ще оформим терариума и ще създадем самия терариум.
### Предпоставки
@ -31,7 +31,7 @@ CSS, или Cascading Style Sheets, решава важен проблем в у
> Вижте видеото
>
> [](https://www.youtube.com/watch?v=6yIdOIV9p1I)
> [](https://www.youtube.com/watch?v=6yIdOIV9p1I)
### Задача
@ -43,9 +43,9 @@ CSS, или Cascading Style Sheets, решава важен проблем в у
---
## Каскадност
## Каскадата
Cascading Style Sheets включват идеята, че стиловете "каскадират", така че прилагането на стил се ръководи от неговия приоритет. Стиловете, зададени от автора на уебсайта, имат приоритет пред тези, зададени от браузъра. Стиловете, зададени "inline", имат приоритет пред тези, зададени във външен стилов файл.
Cascading Style Sheets включват идеята, че стиловете "каскадират", така че приложението на стил се ръководи от неговия приоритет. Стиловете, зададени от автора на уебсайта, имат приоритет пред тези, зададени от браузъра. Стиловете, зададени "inline", имат приоритет пред тези, зададени във външен стилов файл.
### Задача
@ -55,7 +55,7 @@ Cascading Style Sheets включват идеята, че стиловете "
<h1style="color: red">My Terrarium</h1>
```
След това добавете следния код към вашия `style.css` файл:
След това добавете следния код към вашия файл `style.css`:
```CSS
h1 {
@ -63,17 +63,17 @@ h1 {
}
```
✅ Кой цвят се показва във вашето уеб приложение? Защо? Можете ли да намерите начин да презапишете стиловете? Кога бихте искали да направите това и защо не?
✅ Кой цвят се показва във вашето уеб приложение? Защо? Можете ли да намерите начин да отмените стиловете? Кога бихте искали да направите това или защо не?
---
## Наследяване
Стиловете се наследяват от стил на предшественик към наследник, така че вложените елементи наследяват стиловете на своите родители.
Стиловете се наследяват от стил на предшественик към потомък, така че вложените елементи наследяват стиловете на своите родители.
### Задача
Задайте шрифта на тялото на определен шрифт и проверете дали вложен елемент наследява този шрифт:
Задайте шрифта на тялото на даден шрифт и проверете шрифта на вложен елемент:
```CSS
body {
@ -81,7 +81,7 @@ body {
}
```
Отворете конзолата на браузъра в раздела 'Elements' и наблюдавайте шрифта на H1. Той наследява шрифта от тялото, както е посочено в браузъра:
Отворете конзолата на браузъра в таба 'Elements' и наблюдавайте шрифта на H1. Той наследява своя шрифт от тялото, както е посочено в браузъра:
Досега вашият `style.css` файл има само няколко стилизирани тага и приложението изглежда доста странно:
Досега вашият файл `style.css` има само няколко стилизирани тага и приложението изглежда доста странно:
```CSS
body {
@ -106,11 +106,11 @@ h1 {
}
```
Този начин на стилизиране на таг ви дава контрол върху уникални елементи, но трябва да контролирате стиловете на много растения във вашия терариум. За да направите това, трябва да използвате CSS селектори.
Този начин на стилизиране на таг ви дава контрол върху уникални елементи, но трябва да контролирате стиловете на много растения в терариума. За да направите това, трябва да използвате селектори на CSS.
### Id-та
### Ids
Добавете стил за подреждане на левия и десния контейнер. Тъй като има само един ляв контейнер и само един десен контейнер, те получават id-та в маркировката. За да ги стилизирате, използвайте `#`:
Добавете стил за оформяне на левия и десния контейнер. Тъй като има само един ляв контейнер и само един десен контейнер, те са получили ids в маркировката. За да ги стилизирате, използвайте `#`:
```CSS
#left-container {
@ -134,9 +134,9 @@ h1 {
}
```
Тук сте позиционирали тези контейнери с абсолютна позиция в крайната лява и дясна част на екрана и сте използвали проценти за тяхната ширина, така че да могат да се мащабират за малки мобилни екрани.
Тук сте позиционирали тези контейнери с абсолютно позициониране в крайната лява и дясна част на екрана и сте използвали проценти за тяхната ширина, така че да могат да се мащабират за малки мобилни екрани.
✅ Този код е доста повтарящ се, следователно не е "DRY" (Don't Repeat Yourself); можете ли да намерите по-добър начин за стилизиране на тези id-та, може би с id и клас? Ще трябва да промените маркировката и да рефакторирате CSS:
✅ Този код е доста повторен, което не е "DRY" (Don't Repeat Yourself); можете ли да намерите по-добър начин за стилизиране на тези ids, може би с id и клас? Ще трябва да промените маркировката и да рефакторирате CSS:
```html
<divid="left-container"class="container"></div>
@ -144,9 +144,9 @@ h1 {
### Класове
В горния пример сте стилизирали два уникални елемента на екрана. Ако искате стиловете да се прилагат към много елементи на екрана, можете да използвате CSS класове. Направете това, за да подредите растенията в левия и десния контейнер.
В горния пример сте стилизирали два уникални елемента на екрана. Ако искате стиловете да се прилагат към много елементи на екрана, можете да използвате CSS класове. Направете това, за да оформите растенията в левия и десния контейнер.
Обърнете внимание, че всяко растение в HTML маркировката има комбинация от id-та и класове. Id-тата тук се използват от JavaScript, който ще добавите по-късно, за да манипулирате разположението на растенията в терариума. Класовете обаче дават на всички растения определен стил.
Забележете, че всяко растение в HTML маркировката има комбинация от ids и класове. Ids тук се използват от JavaScript, който ще добавите по-късно, за да манипулирате разположението на растенията в терариума. Класовете обаче дават на всички растения определен стил.
```html
<divclass="plant-holder">
@ -154,7 +154,7 @@ h1 {
</div>
```
Добавете следното към вашия `style.css` файл:
Добавете следното към вашия файл `style.css`:
```CSS
.plant-holder {
@ -173,33 +173,33 @@ h1 {
Забележително в този фрагмент е смесването на относително и абсолютно позициониране, което ще разгледаме в следващия раздел. Обърнете внимание на начина, по който височините се обработват чрез проценти:
Задавате височината на държача на растенията на 13%, което е добро число, за да се уверите, че всички растения се показват във всеки вертикален контейнер без нужда от превъртане.
Задавате височината на държача на растенията на 13%, добро число, за да гарантирате, че всички растения се показват във всеки вертикален контейнер без нужда от превъртане.
Премествате държача на растенията наляво, за да позволите растенията да бъдат по-центрирани в техния контейнер. Изображенията имат голямо количество прозрачен фон, за да бъдат по-лесни за влачене, така че трябва да бъдат изместени наляво, за да сепоберат по-добре на екрана.
Премествате държача на растенията наляво, за да позволите растенията да бъдат по-центрирани в техния контейнер. Изображенията имат голямо количество прозрачен фон, за да бъдат по-лесни за влачене, така че трябва да бъдат изместени наляво, за да севпишат по-добре на екрана.
След това самото растение получава максимална ширина от 150%. Това му позволява да се мащабира надолу, когато браузърът се мащабира надолу. Опитайте да промените размера на браузъра си; растенията остават в контейнерите си, но се мащабират, за да сепоберат.
След това самото растение получава максимална ширина от 150%. Това му позволява да се мащабира надолу, когато браузърът се мащабира надолу. Опитайте да промените размера на браузъра си; растенията остават в контейнерите си, но се мащабират, за да севпишат.
Също така е забележимо използването на z-index, който контролира относителната височина на елемент (така че растенията да стоят върху контейнера и да изглеждат сякаш са вътре в терариума).
Също така е забележително използването на z-index, който контролира относителната височина на елемент (така че растенията да седят върху контейнера и да изглеждат сякаш са вътре в терариума).
✅ Защо ви трябват както държач за растения, така и CSS селектор за растения?
✅ Защо ви трябват както държач на растенията, така и CSS селектор за растенията?
## CSS Позициониране
Смесването на свойства за позициониране (има статично, относително, фиксирано, абсолютно и лепкаво позициониране) може да бъде малко сложно, но когато се направи правилно, ви дава добър контрол върху елементите на вашите страници.
Смесването на свойства за позициониране (има статично, относително, фиксирано, абсолютно и лепкаво позициониране) може да бъде малко сложно, но когато е направено правилно, ви дава добър контрол върху елементите на вашите страници.
Абсолютно позиционираните елементи се позиционират спрямо най-близките си позиционирани предшественици, а ако няма такива, се позиционират спрямо тялото на документа.
Абсолютно позиционираните елементи се позиционират спрямо най-близките позиционирани предшественици, а ако няма такива, тесе позиционират спрямо тялото на документа.
Относително позиционираните елементи се позиционират въз основа на указанията на CSS за коригиране на тяхното разположение спрямо първоначалната им позиция.
В нашия пример, `plant-holder`е елемент с относително позициониране, който е позициониран в контейнер с абсолютно позициониране. Полученото поведение е, че страничните контейнери са фиксирани вляво и вдясно, а`plant-holder`е вложен, като се настройва в рамките на страничните контейнери, осигурявайки място за растенията да бъдат подредени във вертикален ред.
В нашия пример, `plant-holder`е елемент с относително позициониране, който е позициониран в контейнер с абсолютно позициониране. Резултатното поведение е, че страничните контейнери са фиксирани вляво и вдясно, а`plant-holder`е вложен, коригирайки се в рамките на страничните контейнери, давайки пространство за растенията да бъдат поставени във вертикален ред.
> Самото `plant` също има абсолютно позициониране, необходимо за това да бъде влачено, както ще откриете в следващия урок.
> Самото `plant` също има абсолютно позициониране, необходимо за да бъде влачено, както ще откриете в следващия урок.
✅ Експериментирайте с превключване на типовете позициониране на страничните контейнери и `plant-holder`. Какво се случва?
✅ Експериментирайте с промяна на типовете позициониране на страничните контейнери и `plant-holder`. Какво се случва?
## CSS Оформления
Сега ще използвате наученото, за да изградите самия терариум, изцяло спомощта на CSS!
Сега ще използвате наученото, за да изградите самия терариум, изцяло с CSS!
Първо, стилизирайте децата на `.terrarium` div като заоблен правоъгълник с помощта на CSS:
@ -250,17 +250,17 @@ h1 {
}
```
Обърнете внимание на използването на проценти тук. Ако намалите размера на браузъра си, можете да видите как бурканът също се мащабира. Също така обърнете внимание на процентите за ширините и височините на елементите на буркана и как всеки елемент е абсолютно позициониран в центъра, фиксиран към дъното на изгледа.
Обърнете внимание на използването на проценти тук. Ако намалите размера на браузъра си, можете да видите как бурканът също се мащабира. Също така забележете ширините и височините в проценти за елементите на буркана и как всеки елемент е абсолютно позициониран в центъра, фиксиран към дъното на изгледа.
Също така използваме `rem` за border-radius, дължина, свързана с шрифта. Прочетете повече за този тип относително измерване в [CSS спецификацията](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
Използваме и `rem` за радиуса на границата, дължина, относителна към шрифта. Прочетете повече за този тип относително измерване в [CSS спецификацията](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
✅ Опитайте да промените цветовете и прозрачността на буркана спрямо тези на почвата. Какво се случва? Защо?
✅ Опитайте да промените цветовете и прозрачността на буркана спрямо тези на пръстта. Какво се случва? Защо?
---
## 🚀Предизвикателство
Добавете "блясък" към долната лява част на буркана, за да изглежда по-стъклен. Ще стилизирате `.jar-glossy-long` и `.jar-glossy-short`, за да изглеждат като отразен блясък. Ето как би изглеждало:
Добавете "балон" блясък в долната лява част на буркана, за да изглежда по-стъклен. Ще стилизирате `.jar-glossy-long` и `.jar-glossy-short`, за да изглеждат като отразен блясък. Ето как би изглеждало:
CSS изглежда измамно лесен, но има много предизвикателства при опитите да стилизирате приложение перфектно за всички браузъри и всички размери на екрана. CSS-Grid и Flexbox са инструменти, разработени, за да направят задачата малко по-структурирана и по-надеждна. Научете за тези инструменти, като играете [Flexbox Froggy](https://flexboxfroggy.com/) и [Grid Garden](https://codepip.com/games/grid-garden/).
CSS изглежда измамно лесен, но има много предизвикателства при опитите да стилизирате приложение перфектно за всички браузъри и всички размери на екрана. CSS-Grid и Flexbox са инструменти, които саразработени, за да направят задачата малко по-структурирана и по-надеждна. Научете за тези инструменти, като играете [Flexbox Froggy](https://flexboxfroggy.com/) и [Grid Garden](https://codepip.com/games/grid-garden/).
## Задание
@ -281,4 +281,4 @@ CSS изглежда измамно лесен, но има много пред
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
# Проект Терариум Част 3: Манипулация на DOM и Затваряне
# Проект Терариум Част 3: Манипулиране на DOM и Затваряне

> Скица от [Tomomi Imura](https://twitter.com/girlie_mac)
@ -18,15 +18,15 @@ CO_OP_TRANSLATOR_METADATA:
### Въведение
Манипулирането на DOM, или "Document Object Model", е ключов аспект науеб разработката. Според [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) е представяне на данните за обектите, които съставляват структурата и съдържанието на документ в уеб." Предизвикателствата около манипулацията на DOM често са причина за използването на JavaScript рамки вместо чист JavaScript за управление на DOM, но ние ще се справим сами!
Манипулирането на DOM, или "Document Object Model", е ключов аспект отуеб разработката. Според [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) е представяне на данните за обектите, които съставляват структурата и съдържанието на документ в уеб." Предизвикателствата около манипулирането на DOM често са причина за използването на JavaScript рамки вместо чист JavaScript за управление на DOM, но ние ще се справим сами!
Освен това, този урок ще въведе идеята за [затваряне в JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), което можете да си представите като функция, затворена от друга функция, така че вътрешната функция има достъп до обхвата на външната функция.
Освен това, този урок ще въведе идеята за [JavaScript затваряне](https://developer.mozilla.org/docs/Web/JavaScript/Closures), което можете да си представите като функция, затворена от друга функция, така че вътрешната функция да има достъп до обхвата на външната функция.
> Затварянията в JavaScript са обширна и сложна тема. Този урок разглежда най-основната идея, че в кода на този терариум ще намерите затваряне: вътрешна функция и външна функция, конструирани така, че вътрешната функция да има достъп до обхвата на външната функция. За много повече информация за това как работи, моля, посетете [подробната документация](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
> JavaScript затварянията са обширна и сложна тема. Този урок засяга най-основната идея, че в кода на този терариум ще намерите затваряне: вътрешна функция и външна функция, конструирани по начин, който позволява на вътрешната функция достъп до обхвата на външната функция. За много повече информация за това как работи, моля, посетете [обширната документация](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
Ще използваме затваряне, за да манипулираме DOM.
Представете си DOM като дърво, което представлява всички начини, по които документ на уеб страница може да бъде манипулиран. Различни API (Application Program Interfaces) са написани, за да позволят на програмистите, използвайки избрания от тях език за програмиране, да достъпват DOM и да го редактират, променят, пренареждат и управляват.
Представете си DOM като дърво, което представлява всички начини, по които документ на уеб страница може да бъде манипулиран. Различни API (Application Program Interfaces) са написани, за да позволят на програмистите, използвайки избрания от тях език за програмиране, да имат достъп до DOM и да го редактират, променят, пренареждат и управляват.

@ -36,7 +36,7 @@ CO_OP_TRANSLATOR_METADATA:
### Предпоставки
Трябва да имате HTML и CSS за вашия терариум готови. До края на този урок ще можете да местите растенията в и извън терариума чрез влачене.
Трябва да имате HTML и CSS за вашия терариум готови. До края на този урок ще можете да местите растенията в и извън терариума, като ги влачите.
### Задача
@ -49,7 +49,7 @@ CO_OP_TRANSLATOR_METADATA:
> Забележка: използвайте `defer`, когато импортирате външен JavaScript файл в HTML файла, за да позволите на JavaScript да се изпълни само след като HTML файлът е напълно зареден. Можете също да използвате атрибута `async`, който позволява скриптът да се изпълнява, докато HTML файлът се парсира, но в нашия случай е важно HTML елементите да са напълно налични за влачене, преди да позволим изпълнението на скрипта за влачене.
---
## Елементите на DOM
## DOM елементите
Първото нещо, което трябва да направите, е да създадете референции към елементите, които искате да манипулирате в DOM. В нашия случай това са 14-те растения, които в момента чакат в страничните ленти.
Какво се случва тук? Реферирате документа и търсите в неговия DOM, за да намерите елемент с определен Id. Спомнете си от първия урок за HTML, че дадохте индивидуални Id-та на всяко изображение на растение (`id="plant1"`)? Сега ще използвате този труд. След като идентифицирате всеки елемент, го предавате на функция, наречена `dragElement`, която ще изградите след малко. Така елементът в HTML вече еактивиран за влачене, или скоро ще бъде.
Какво се случва тук? Реферирате документа и търсите в неговия DOM, за да намерите елемент с определен Id. Спомнете си в първия урок за HTML, че дадохте индивидуални Id-та на всяко изображение на растение (`id="plant1"`)? Сега ще използвате това усилие. След като идентифицирате всеки елемент, го предавате на функция, наречена `dragElement`, която ще изградите след малко. Така елементът в HTML вече еготов за влачене, или скоро ще бъде.
✅ Защо реферираме елементи по Id? Защо не по техния CSS клас? Можете да се върнете към предишния урок за CSS, за да отговорите на този въпрос.
@ -96,7 +96,7 @@ displayCandy();
console.log(candy)
```
В този пример функцията `displayCandy` обгражда функция, която добавя нов тип бонбон към масив, който вече съществува във функцията. Ако изпълните този код, масивът `candy` ще бъде недефиниран, тъй като е локална променлива (локална за затварянето).
В този пример, функцията `displayCandy` обгражда функция, която добавя нов тип бонбон към масив, който вече съществува във функцията. Ако изпълните този код, масивът `candy` ще бъде недефиниран, тъй като е локална променлива (локална за затварянето).
✅ Как можете да направите масива `candy` достъпен? Опитайте да го преместите извън затварянето. Така масивът става глобален, вместо да остава достъпен само за локалния обхват на затварянето.
@ -117,15 +117,15 @@ function dragElement(terrariumElement) {
`dragElement` получава своя обект `terrariumElement` от декларациите в началото на скрипта. След това задавате някои локални позиции на `0` за обекта, предаден на функцията. Това са локалните променливи, които ще бъдат манипулирани за всеки елемент, докато добавяте функционалност за влачене и пускане в затварянето към всеки елемент. Терариумът ще бъде попълнен от тези влачени елементи, така че приложението трябва да следи къде са поставени.
Освен това, елементът `terrariumElement`, който се предава на тази функция, получава събитие `pointerdown`, което е част от [web APIs](https://developer.mozilla.org/docs/Web/API), предназначени да помагат при управлението на DOM. `onpointerdown`се активира, когато бутон е натиснат, или в нашия случай, когато докоснете влачим елемент. Този обработчик на събития работи както на [уеб, така и на мобилни браузъри](https://caniuse.com/?search=onpointerdown), с някои изключения.
Освен това, `terrariumElement`, който се предава на тази функция, получава събитие `pointerdown`, което е част от [web APIs](https://developer.mozilla.org/docs/Web/API), създадени да помагат при управлението на DOM. `onpointerdown`се активира, когато бутон е натиснат, или в нашия случай, когато докоснете влачим елемент. Този обработчик на събития работи както на [уеб, така и на мобилни браузъри](https://caniuse.com/?search=onpointerdown), с няколко изключения.
✅ [Обработчикът на събития `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) има много по-голяма поддръжка между браузърите; защо не го използвате тук? Помислете за точния тип взаимодействие с екрана, което се опитвате да създадете тук.
✅ [Обработчикът на събития `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) има много по-голяма поддръжка между браузърите; защо не бихте го използвали тук? Помислете за точния тип взаимодействие с екрана, което се опитвате да създадете тук.
---
## Функцията Pointerdrag
Елементът `terrariumElement`е готов да бъде влачен; когато събитието `onpointerdown`се активира, функцията `pointerDrag`се извиква. Добавете тази функция точно под този ред: `terrariumElement.onpointerdown = pointerDrag;`:
`terrariumElement`е готов да бъде влачен; когато събитието `onpointerdown`се активира, функцията `pointerDrag`се извиква. Добавете тази функция точно под този ред: `terrariumElement.onpointerdown = pointerDrag;`:
### Задача
@ -144,21 +144,21 @@ function pointerDrag(e) {
Второ, отворете `index.html` в прозорец на браузъра и инспектирайте интерфейса. Когато кликнете върху растение, можете да видите как събитието 'e' се улавя. Разгледайте събитието, за да видите колко информация се събира от едно pointerdown събитие!
След това, обърнете внимание как локалните променливи `pos3` и `pos4`се задават на e.clientX. Можете да намерите стойностите на `e` в панела за инспекция. Тези стойности улавят x и y координатите на растението в момента, в който го кликнете или докоснете. Ще ви е необходим прецизен контрол върху поведението на растенията, докато ги кликвате и влачите, така че следите техните координати.
След това, обърнете внимание как локалните променливи `pos3` и `pos4`се задават на e.clientX. Можете да намерите стойностите на `e` в панела за инспекция. Тези стойности улавят x и y координатите на растението в момента, в който го кликнете или докоснете. Ще ви е необходим фин контрол върху поведението на растенията, докато ги кликвате и влачите, така че следите техните координати.
✅ Става ли по-ясно защо цялото приложение е изградено с едно голямо затваряне? Ако не беше, как бихте поддържали обхват за всяко от 14-те влачими растения?
Завършете началната функция, като добавите още две манипулации на събитията за указател под `pos4 = e.clientY`:
Завършете началната функция, като добавите още две манипулации на събитията за pointer под `pos4 = e.clientY`:
```html
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
Сегауказвате, че искате растението да бъде влачено заедно с указателя, докато го местите, и жестът на влачене да спре, когато деселектирате растението. `onpointermove` и `onpointerup`са част от същия API като `onpointerdown`. Интерфейсът ще хвърля грешки сега, тъй като все още не сте дефинирали функциите `elementDrag` и `stopElementDrag`, така че ги изградете следващи.
Сегапосочвате, че искате растението да бъде влачено заедно с показалеца, докато го местите, и жестът за влачене да спре, когато премахнете избора на растението. `onpointermove` и `onpointerup`са част от същия API като `onpointerdown`. Интерфейсът ще хвърля грешки сега, тъй като все още не сте дефинирали функциите `elementDrag` и `stopElementDrag`, така че ги изградете следващи.
## Функциите elementDrag и stopElementDrag
Ще завършите вашето затваряне, като добавите още две вътрешни функции, които ще управляват какво се случва, когато влачите растение и спирате да го влачите. Поведението, което искате, е да можете да влачите всяко растение по всяко време и да го поставяте навсякъде на екрана. Този интерфейс е доста непретенциозен (например няма зона за пускане), за да ви позволи да проектирате вашия терариум точно както искате, като добавяте, премахвате и премествате растения.
Ще завършите вашето затваряне, като добавите още две вътрешни функции, които ще управляват какво се случва, когато влачите растение и спирате да го влачите. Поведението, което искате, е да можете да влачите всяко растение по всяко време и да го поставяте навсякъде на екрана. Този интерфейс е доста неограничен (например няма зона за пускане), за да ви позволи да проектирате вашия терариум точно както искате, като добавяте, премахвате и премествате растения.
### Задача
@ -177,7 +177,7 @@ function elementDrag(e) {
```
В тази функция правите много редакции на началните позиции 1-4, които зададохте като локални променливи във външната функция. Какво се случва тук?
Докато влачите, преназначавате `pos1`, като го правите равен на `pos3` (което зададохте по-рано като `e.clientX`) минус текущата стойност на `e.clientX`. Правите подобна операция за `pos2`. След това, нулирате `pos3` и `pos4` на новите X и Y координати на елемента. Можете да наблюдавате тези промени в конзолата, докато влачите. След това манипулирате CSS стила на растението, за да зададете новата му позиция въз основа на новите позиции на `pos1` и `pos2`, като изчислявате горните и левите X и Y координати на растението, сравнявайки неговото отместване с тези нови позиции.
Докато влачите, преназначавате `pos1`, като го правите равно на `pos3` (което зададохте по-рано като `e.clientX`) минус текущата стойност на `e.clientX`. Правите подобна операция за `pos2`. След това, нулирате `pos3` и `pos4` на новите X и Y координати на елемента. Можете да наблюдавате тези промени в конзолата, докато влачите. След това манипулирате CSS стила на растението, за да зададете новата му позиция въз основа на новите позиции на `pos1` и `pos2`, като изчислявате горните и левите X и Y координати на растението, сравнявайки неговото отместване с тези нови позиции.
> `offsetTop` и `offsetLeft`са CSS свойства, които задават позицията на елемент въз основа на тази на неговия родител; неговият родител може да бъде всеки елемент, който не е позициониран като `static`.
@ -206,25 +206,25 @@ function stopElementDrag() {
## 🚀Предизвикателство
Добавете нов обработчик на събития към вашето затваряне, за да направите нещо повече с растенията; например, двойно кликване върху растение, за да го преместите на преден план. Бъдете креативни!
Добавете нов обработчик на събития към вашето затваряне, за да направите нещо повече с растенията; например, двойно кликване върху растение, за да го поставите отпред. Бъдете креативни!
## Тест след лекцията
## Финален тест
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/20)
Докато влаченето на елементи по екрана изглежда тривиално, има много начини да го направите и много капани, в зависимост от ефекта, който търсите. Всъщност има цял [API за влачене и пускане](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API), който можете да опитате. Него използвахме в този модул, защото ефектът, който искахме, беше малко по-различен, но опитайте този API във ваш собствен проект и вижте какво можете да постигнете.
Докато влаченето на елементи по екрана изглежда тривиално, има много начини да го направите и много капани, в зависимост от ефекта, който търсите. Всъщност, има цял [drag and drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API), който можете да опитате. Него използвахме в този модул, защото ефектът, който искахме, беше малко по-различен, но опитайте този API на ваш собствен проект и вижте какво можете да постигнете.
Намерете повече информация за събитията за указатели в [документите на W3C](https://www.w3.org/TR/pointerevents1/) и в [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events).
Намерете повече информация за pointer събитията в [W3C документация](https://www.w3.org/TR/pointerevents1/) и в [MDN уеб документация](https://developer.mozilla.org/docs/Web/API/Pointer_events).
Винаги проверявайте възможностите на браузърите, използвайки [CanIUse.com](https://caniuse.com/).
## Задание
[Работете малко повечес DOM](assignment.md)
[Работете още малко с DOM](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Когато създаваме приложение за браузър, предоставяме графичен потребителски интерфейс (GUI), който потребителят използва за взаимодействие с това, което сме изградили. Най-често срещаният начин за взаимодействие с браузъра е чрез кликване и писане в различни елементи. Предизвикателството, пред което сме изправени като разработчици, е, че не знаем кога потребителят ще извърши тези действия!
Когато създаваме приложение за браузър, предоставяме графичен потребителски интерфейс (GUI), който потребителят използва за взаимодействие с това, което сме изградили. Най-често срещаният начин за взаимодействие с браузъра е чрез кликване и въвеждане в различни елементи. Предизвикателството, пред което сме изправени като разработчици, е, че не знаем кога потребителят ще извърши тези действия!
[Програмирането, базирано на събития](https://en.wikipedia.org/wiki/Event-driven_programming) е подходът, който трябва да използваме, за да създадем нашия GUI. Ако разгледаме малко по-подробно този термин, ще видим, че основната дума тук е**събитие**. [Събитие](https://www.merriam-webster.com/dictionary/event), според Merriam-Webster, сеопределя като "нещо, което се случва". Това описва нашата ситуация перфектно. Знаем, че нещо ще се случи, за което искаме да изпълним код в отговор, но не знаем кога точно ще се случи.
[Програмирането, базирано на събития](https://en.wikipedia.org/wiki/Event-driven_programming) е подходът, който трябва да използваме, за да създадем нашия GUI. Ако разгледаме малко по-подробно този термин, ще видим, че основната дума тук е**събитие**. [Събитие](https://www.merriam-webster.com/dictionary/event), според Merriam-Webster, седефинира като "нещо, което се случва". Това описва нашата ситуация перфектно. Знаем, че нещо ще се случи, за което искаме да изпълним код в отговор, но не знаем кога точно ще се случи.
Начинът, по който маркираме секция от код, която искаме да изпълним, е чрез създаване на функция. Когато мислим за [процедурно програмиране](https://en.wikipedia.org/wiki/Procedural_programming), функциите се извикват в определен ред. Същото важи и за програмирането, базирано на събития. Разликата ев **как** се извикват функциите.
Начинът, по който маркираме секция от код, която искаме да изпълним, е чрез създаване на функция. Когато мислим за [процедурно програмиране](https://en.wikipedia.org/wiki/Procedural_programming), функциите се извикват в определен ред. Същото важи и за програмирането, базирано на събития. Разликата е**как** функциите ще бъдат извикани.
За да обработваме събития (като кликване на бутон, писане и т.н.), регистрираме **слушатели на събития**. Слушателят на събитие е функция, която "слуша" за настъпването на събитие и се изпълнява в отговор. Слушателите на събития могат да актуализират потребителския интерфейс, да правят заявки към сървъра или да извършват други действия в отговор на действията на потребителя. Добавяме слушател на събитие чрез [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) и предоставяме функция за изпълнение.
За да обработваме събития (кликване на бутон, въвеждане на текст и т.н.), регистрираме **слушатели на събития**. Слушателят на събитие е функция, която "слуша" за настъпването на събитие и се изпълнява в отговор. Слушателите на събития могат да актуализират потребителския интерфейс, да правят заявки към сървъра или да извършват други действия в отговор на действията на потребителя. Добавяме слушател на събитие чрез [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener), като предоставяме функция за изпълнение.
> **NOTE:** Струва си да се отбележи, че има множество начини за създаване на слушатели на събития. Можете да използвате анонимни функции или да създавате именувани функции. Можете да използвате различни преки пътища, като задаване на свойството `click` или използване на `addEventListener`. В нашето упражнение ще се фокусираме върху `addEventListener` и анонимни функции, тъй като това вероятное най-често използваната техника от уеб разработчиците. Освен това е най-гъвкавата, тъй като `addEventListener` работи за всички събития, а името на събитието може да бъде предоставено като параметър.
> **NOTE:** Струва си да се отбележи, че има множество начини за създаване на слушатели на събития. Можете да използвате анонимни функции или да създавате именувани функции. Можете да използвате различни съкращения, като задаване на свойството `click` или използване на `addEventListener`. В нашето упражнение ще се фокусираме върху `addEventListener` и анонимни функции, тъй като това е най-често използваната техника от уеб разработчиците. Освен това е най-гъвкавата, тъй като `addEventListener` работи за всички събития, а името на събитието може да бъде предоставено като параметър.
### Често срещани събития
Има [десетки събития](https://developer.mozilla.org/docs/Web/Events), които можете да слушате, когато създавате приложение. Всъщност почти всяко действие на потребителя на страницата предизвиква събитие, което ви дава голяма свобода да осигурите желаното изживяване. За щастие, обикновено ще ви трябват само няколко събития. Ето някои от най-често срещаните (включително двете, които ще използваме при създаването на нашата игра):
Има [десетки събития](https://developer.mozilla.org/docs/Web/Events), които можете да слушате, когато създавате приложение. Всъщност почти всяко действие на потребителя на страницата предизвиква събитие, което ви дава голяма свобода да осигурите желаното изживяване. За щастие, обикновено ще ви трябват само няколко основни събития. Ето някои от най-често срещаните (включително двете, които ще използваме за създаване на нашата игра):
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): Потребителят е кликнал върху нещо, обикновено бутон или хипервръзка
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): Потребителят е кликнал с десния бутон на мишката
@ -48,7 +48,7 @@ CO_OP_TRANSLATOR_METADATA:
### Структура на файловете
Ще ни трябват общо три файла: **index.html**, **script.js** и **style.css**. Нека започнемс тях, за да улесним работата си.
Ще ни трябват общо три файла: **index.html**, **script.js** и **style.css**. Нека започнем, като ги създадем, за да улесним работата си.
- Създайте нова папка за вашата работа, като отворите конзола или терминал и изпълните следната команда:
@ -109,11 +109,11 @@ code .
Винаги е най-добре да разработвате итеративно, за да видите как изглеждат нещата. Нека стартираме нашето приложение. Има чудесно разширение за Visual Studio Code, наречено [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), което ще хоства вашето приложение локално и ще обновява браузъра всеки път, когато запазите.
- Инсталирайте [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), като следвате линка и кликнете върху **Install**
- Инсталирайте [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), като следвате линка и кликнете **Install**
- Браузърът ще ви подкани да отворите Visual Studio Code, а след това Visual Studio Code ще ви подкани да извършите инсталацията
- Рестартирайте Visual Studio Code, ако бъдете подканени
- След като инсталирате, във Visual Studio Code натиснете Ctrl-Shift-P (или Cmd-Shift-P), за да отворите командния палет
- Напишете **Live Server: Open with Live Server**
- Въведете **Live Server: Open with Live Server**
- Live Server ще започне да хоства вашето приложение
- Отворете браузър и навигирайте до **https://localhost:5500**
- Вече трябва да виждате страницата, която създадохте!
@ -122,7 +122,7 @@ code .
## Добавяне на CSS
С нашия HTML създаден, нека добавим CSS за основно стилизиране. Трябва да маркираме думата, която играчът трябва да напише, и да оцветим текстовото поле, ако това, което е написано, е грешно. Ще направим това с два класа.
С нашия HTML създаден, нека добавим CSS за основно стилизиране. Трябва да маркираме думата, която играчът трябва да пише, и да оцветим текстовото поле, ако това, което е написано, е грешно. Ще направим това с два класа.
Създайте нов файл с име **style.css** и добавете следния синтаксис.
@ -154,7 +154,7 @@ code .
Но първо, създайте нов файл с име **script.js**.
### Добавяне на константите
### Създаване на константите
Ще ни трябват няколко елемента, за да улесним програмирането. Отново, подобно на рецепта, ето какво ще ни трябва:
За да започне играта, играчът ще кликне върху старт. Разбира се, не знаем кога ще кликне върху старт. Тук влиза в действие [слушателят на събитие](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Слушателят на събитие ще ни позволи да слушаме за настъпването на нещо (събитие) и да изпълним код в отговор. В нашия случай искаме да изпълним код, когато потребителят кликне върху старт.
За да започне играта, играчът ще кликне върху старт. Разбира се, не знаем кога ще кликне старт. Тук влиза в действие [слушателят на събитие](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Слушателят на събитие ще ни позволи да слушаме за настъпването на нещо (събитие) и да изпълним код в отговор. В нашия случай искаме да изпълним код, когато потребителят кликне върху старт.
Когато потребителят кликне върху **старт**, трябва да изберем цитат, да настроим потребителския интерфейс и да настроим проследяването на текущата дума и времето. По-долу е JavaScript, който трябва да добавите; ще го обсъдим веднага след блока със скрипта.
Когато потребителят кликне **старт**, трябва да изберем цитат, да настроим потребителския интерфейс и да настроим проследяването на текущата дума и времето. По-долу е JavaScript, който трябва да добавите; ще го обсъдим веднага след блока със скрипта.
- Използването на [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) и [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random) ни позволява случайно да изберем цитат от масива `quotes`
- Преобразуваме `quote` в масив от `words`, за да можем да проследим думата, която играчът пише в момента
- Превръщаме `quote` в масив от `words`, за да можем да проследим думата, която играчът пише в момента
- `wordIndex`се задава на 0, тъй като играчът ще започне с първата дума
- Настройка на потребителския интерфейс
- Създаваме масив от `spanWords`, който съдържа всяка дума в `span` елемент
Нека разгледаме кода! Започваме, като вземаме текущата дума и стойността, която играчът е написал досега. След това имаме логика тип "водопад", където проверяваме дали цитатът е завършен, думата е завършена, думата е правилна или (накрая), дали има грешка.
Нека разгледаме кода! Започваме, като вземем текущата дума и стойността, която играчът е написал досега. След това имаме логика тип "водопад", където проверяваме дали цитатът е завършен, думата е завършена, думата е правилна или (накрая), дали има грешка.
- Цитатът е завършен, което се указва от `typedValue`, равен на `currentWord`, и `wordIndex`, равен на един по-малко от `length` на `words`
- Изчисляваме `elapsedTime`, като изваждаме `startTime` от текущото време
- Разделяме `elapsedTime` на 1,000, за да го преобразуваме от милисекунди в секунди
- Показваме съобщение за успех
- Думата е завършена, което се указва от `typedValue`, завършващ с интервал (края на дума), и `typedValue`, равен на `currentWord`
- Задаваме `value` на `typedElement` на `''`, за да позволим следващата дума да бъде написана
- Думата е завършена, което се указва от `typedValue`, завършващ с интервал (края на дума) и `typedValue`, равен на `currentWord`
- Задаваме `value` на `typedElement` на `''`, за да позволим въвеждането на следващата дума
- Увеличаваме `wordIndex`, за да преминем към следващата дума
- Преглеждаме всички `childNodes` на `quoteElement`, за да зададем `className` на `''`, за да севърнем към стандартния дисплей
- Преглеждаме всички `childNodes` на `quoteElement`, за да зададем `className` на `''`, за да върнем към стандартния дисплей
- Задаваме `className` на текущата дума на `highlight`, за да я маркираме като следващата дума за писане
- Думата е написана правилно (но не е завършена), което се указва от `currentWord`, започващ с`typedValue`
- Уверяваме се, че `typedValueElement`се показва като стандартен, като изчистваме `className`
- Ако сме стигнали дотук, имаме грешка
- Ако стигнем дотук, имаме грешка
- Задаваме `className` на `typedValueElement` на `error`
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/23)
### Въведение
Браузърните разширения добавят допълнителна функционалност към браузъра. Но преди да създадете такова, е добре да научите малко повече за това как браузърите работят.
Разширенията за браузъри добавят допълнителна функционалност към браузъра. Но преди да създадете такова, е добре да научите малко повече за това как браузърите работят.
### За браузъра
В тази серия от уроци ще научите как да създадете браузърно разширение, което ще работи на браузърите Chrome, Firefox и Edge. В тази част ще откриете как работят браузърите и ще изградите основните елементи на браузърното разширение.
В тази серия от уроци ще научите как да създадете разширение за браузър, което ще работи на Chrome, Firefox и Edge. В тази част ще откриете как работят браузърите и ще изградите основните елементи на разширението.
Но какво всъщност е браузърът? Това е софтуерно приложение, което позволява на крайния потребител да достъпва съдържание от сървър и да го показва на уеб страници.
✅ Малко история: първият браузър сее наричал 'WorldWideWeb' и е създаден от сър Тимъти Бърнърс-Лий през 1990 година.
✅ Малко история: първият браузър сее наричал 'WorldWideWeb' и е създаден от сър Тимъти Бърнърс-Лий през 1990 г.
> Някои от първите браузъри, чрез [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
Когато потребител се свърже с интернет чрез URL (Uniform Resource Locator) адрес, обикновено използвайки Hypertext Transfer Protocol чрез адрес `http` или `https`, браузърът комуникира суеб сървър и извлича уеб страница.
Когато потребител се свърже с интернет чрез URL (Uniform Resource Locator) адрес, обикновено използвайки Hypertext Transfer Protocol чрез `http` или `https` адрес, браузърът комуникира суеб сървър и извлича уеб страница.
На този етап, рендериращият двигател на браузъра я показва на устройството на потребителя, което може да бъде мобилен телефон, настолен компютър или лаптоп.
След това, рендиращият механизъм на браузъра я показва на устройството на потребителя, което може да бъде мобилен телефон, настолен компютър или лаптоп.
Браузърите също така имат способността да кешират съдържание, за да не се налага то да бъде извличано от сървъра всеки път. Те могат да записват историята на активността на потребителя, да съхраняват 'бисквитки', които са малки частици данни, съдържащи информация за активността на потребителя, и още много други функции.
Браузърите също така имат способността да кешират съдържание, за да не се налага то да бъде извличано от сървъра всеки път. Те могат да записват историята на активността на потребителя, да съхраняват 'бисквитки', които са малки части от данни, съдържащи информация за активността на потребителя, и още много.
Едно много важно нещо, което трябва да запомните за браузърите, е че те не са еднакви! Всеки браузър има своите силни и слаби страни, и професионалният уеб разработчик трябва да разбира как да направи уеб страниците да работят добре на различни браузъри. Това включва работа с малки екрани, като тези на мобилни телефони, както и с потребители, които са офлайн.
Много важно е да запомните, че браузърите не са еднакви! Всеки браузър има своите силни и слаби страни, и професионалният уеб разработчик трябва да разбира как да направи уеб страниците си да работят добре на различни браузъри. Това включва и работа с малки екрани, като тези на мобилните телефони, както и с потребители, които са офлайн.
Един много полезен уебсайт, който вероятно трябва да запазите в предпочитанията на браузъра, който използвате, е [caniuse.com](https://www.caniuse.com). Когато създавате уеб страници, е много полезно да използвате списъците на caniuse за поддържани технологии, за да можете най-добре да подкрепите своите потребители.
Един много полезен уебсайт, който вероятно трябва да запазите в отметките на предпочитания от вас браузър, е [caniuse.com](https://www.caniuse.com). Когато създавате уеб страници, е много полезно да използвате списъците на caniuse за поддържани технологии, за да осигурите най-добрата поддръжка за вашите потребители.
✅ Как можете да разберете кои браузъри са най-популярни сред потребителите на вашия уебсайт? Проверете вашата аналитика - можете да инсталирате различни аналитични пакети като част от процеса на уебразработка, и те ще ви покажат кои браузъри се използват най-често.
✅ Как можете да разберете кои браузъри са най-популярни сред потребителите на вашия уебсайт? Проверете вашата аналитика - можете да инсталирате различни аналитични пакети като част от процеса на разработка, и те ще ви покажат кои браузъри се използват най-често.
## Браузърни разширения
## Разширения за браузъри
Защо бихте искали да създадете браузърно разширение? Това е удобен инструмент, който можете да добавите към браузъра си, когато имате нужда от бърз достъп до задачи, които често повтаряте. Например, ако често ви се налага да проверявате цветовете на различни уеб страници, с които взаимодействате, можете да инсталирате браузърно разширение за избор на цветове. Ако имате затруднения с запомнянето на пароли, можете да използвате браузърно разширение за управление на пароли.
Защо бихте искали да създадете разширение за браузър? Това е удобен инструмент, който можете да добавите към браузъра си, когато имате нужда от бърз достъп до задачи, които често повтаряте. Например, ако често ви се налага да проверявате цветовете на различни уеб страници, можете да инсталирате разширение за избор на цветове. Ако имате проблеми с помненето на пароли, можете да използвате разширение за управление на пароли.
Създаването на браузърни разширения също е забавно. Те обикновено управляват ограничен брой задачи, които изпълняват добре.
Разширенията за браузъри също така са забавни за разработване. Те обикновено управляват ограничен брой задачи, които изпълняват добре.
✅ Кои са вашите любими браузърни разширения? Какви задачи изпълняват?
✅ Кои са вашите любими разширения за браузъри? Какви задачи изпълняват?
### Инсталиране на разширения
Преди да започнете да създавате, разгледайте процеса на създаване и разгръщане на браузърно разширение. Въпреки че всеки браузър има малки разлики в начина, по който управлява тази задача, процесът е подобен на Chrome и Firefox, както в този пример за Edge:
Преди да започнете да създавате, разгледайте процеса на изграждане и внедряване на разширение за браузър. Въпреки че всеки браузър има малки разлики в начина, по който управлява този процес, стъпките са сходни в Chrome и Firefox с този пример за Edge:

> Забележка: Уверете се, че сте включили режим за разработчици и сте разрешили разширения от други магазини.
По същество процесът ще бъде:
По същество процесът ще бъде следният:
- създайте вашето разширение, използвайки `npm run build`
- навигирайте в браузъра до панела с разширения, използвайки бутона "Настройки и още" (иконата `...`) в горния десен ъгъл
- ако е нова инсталация, изберете `load unpacked`, за да качите ново разширение от папката му за изграждане (в нашия случай това е`/dist`)
- или, кликнете `reload`, ако презареждате вече инсталирано разширение
- изградете вашето разширение, използвайки `npm run build`
- навигирайте в браузъра до панела с разширения, използвайки бутона "Настройки и още" (иконата `...`) в горния десен ъгъл
- ако е нова инсталация, изберете `load unpacked`, за да качите ново разширение от папката му за изграждане (в нашия случай това е`/dist`)
- или, кликнете върху `reload`, ако презареждате вече инсталирано разширение
✅ Тези инструкции се отнасят за разширения, които създавате сами; за да инсталирате разширения, които са публикувани в магазина за браузърни разширения, свързан с всеки браузър, трябва да навигирате до тези [магазини](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) и да инсталирате разширението, което сте избрали.
✅ Тези инструкции се отнасят за разширения, които създавате сами; за да инсталирате разширения, които са публикувани в магазина за разширения на съответния браузър, трябва да навигирате до тези [магазини](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) и да инсталирате избраното от вас разширение.
### Започнете
### Да започнем
Ще създадете браузърно разширение, което показва въглеродния отпечатък на вашия регион, като показва енергийното потребление на региона и източника на енергията. Разширението ще има форма, която събира API ключ, за да можете да достъпите API на CO2 Signal.
Ще създадете разширение за браузър, което показва въглеродния отпечатък на вашия регион, включително енергийната консумация и източника на енергия. Разширението ще има форма, която събира API ключ, за да можете да достъпите API на CO2 Signal.
**Необходимо ви е:**
- [API ключ](https://www.co2signal.com/); въведете вашия имейл в полето на тази страница и ще ви бъде изпратен ключ
- [код за вашия регион](http://api.electricitymap.org/v3/zones), съответстващ на [Electricity Map](https://www.electricitymap.org/map) (например, в Бостън използвам 'US-NEISO').
- [начален код](../../../../5-browser-extension/start). Изтеглете папката `start`; ще завършите кода в тази папка.
- [NPM](https://www.npmjs.com) - NPM е инструмент за управление на пакети; инсталирайте го локално и пакетите, изброени във вашия файл `package.json`, ще бъдат инсталирани за използване от вашия уеб актив
- [API ключ](https://www.co2signal.com/); въведете вашия имейл в полето на тази страница и ще получите ключ
- [код за вашия регион](http://api.electricitymap.org/v3/zones), съответстващ на [Electricity Map](https://www.electricitymap.org/map) (например, за Бостън използвам 'US-NEISO')
- [начален код](../../../../5-browser-extension/start). Изтеглете папката `start`; ще попълвате кода в тази папка
- [NPM](https://www.npmjs.com) - NPM е инструмент за управление на пакети; инсталирайте го локално и пакетите, изброени във вашия файл `package.json`, ще бъдат инсталирани за използване във вашия уеб проект
✅ Научете повече за управлението на пакети в този [отличен модул за обучение](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
Отделете минута, за да разгледате базата с код:
dist
-|manifest.json (настройките по подразбиране сатук)
-|index.html (HTML маркировката за предния край етук)
-|background.js (JS за фонови процеси е тук)
-|main.js (компилиран JS)
src
-|index.js (вашият JS код етук)
dist
-|manifest.json (тук се задават настройките по подразбиране)
-|index.html (тук еHTML маркировката за предния край)
-|background.js (тук е фоновият JS)
-|main.js (компилираният JS)
src
-|index.js (тук пишете вашия JS код)
✅ След като разполагате с вашия API ключ и код за региона, запазете ги някъде в бележка за бъдеща употреба.
✅ След като разполагате с вашия API ключ и код за региона, запазете ги някъде като бележка за бъдеща употреба.
### Създайте HTML за разширението
### Създаване на HTML за разширението
Това разширение има два изгледа. Един за събиране на API ключ и код за региона:
Това разширение има два изгледа. Един за събиране на API ключа и кода на региона:

И втори за показване на въглеродното потребление на региона:
И втори за показване на въглеродната консумация на региона:


Нека започнем със създаването на HTML за формата и стилизирането мус CSS.
Нека започнем със създаването на HTML за формата и стилизирането ѝс CSS.
В папката `/dist` ще създадете форма и зона за резултати. Във файла `index.html` попълнете обозначената зона за форма:
В папката `/dist` ще създадете форма и зона за резултати. Във файла `index.html` попълнете обозначената зона за формата:
```HTML
<formclass="form-data"autocomplete="on">
@ -122,8 +122,8 @@ src
</div>
<buttonclass="search-btn">Submit</button>
</form>
```
Това е формата, където вашата запазена информация ще бъде въведена и съхранена в локалното хранилище.
```
Това е формата, където ще се въвежда и съхранява информацията в локалното хранилище.
След това създайте зоната за резултати; под последния таг на формата добавете няколко div елемента:
@ -139,24 +139,24 @@ src
</div>
<buttonclass="clear-btn">Change region</button>
</div>
```
```
На този етап можете да опитате изграждане. Уверете се, че сте инсталирали зависимостите на пакета за това разширение:
```
npm install
```
```
Тази команда ще използва npm, мениджъра на пакети за Node, за да инсталира webpack за процеса на изграждане на вашето разширение. Можете да видите резултата от този процес, като погледнете в `/dist/main.js` - ще видите, че кодът е бил обединен.
Тази команда ще използва npm, мениджъра на пакети за Node, за да инсталира webpack за процеса на изграждане на разширението. Можете да видите резултата от този процес, като погледнете в `/dist/main.js` - ще видите, че кодът е обединен.
Засега разширението трябва да се изгради и, ако горазположите в Edge като разширение, ще видите форма, която е чисто показана.
Засега разширението трябва да се изгради и, ако говнедрите в Edge като разширение, ще видите формата, показана спретнато.
Поздравления, направихте първите стъпки към създаването на браузърно разширение. В следващите уроци ще го направите по-функционално и полезно.
Поздравления, направихте първите стъпки към създаването на разширение за браузър. В следващите уроци ще го направите по-функционално и полезно.
---
## 🚀 Предизвикателство
Разгледайте магазин за браузърни разширения и инсталирайте едно на вашия браузър. Можете да разгледате неговите файлове по интересни начини. Какво откривате?
Разгледайте магазин за разширения за браузъри и инсталирайте едно на вашия браузър. Можете да разгледате файловете му по интересни начини. Какво откривате?
## Тест след лекцията
@ -164,7 +164,7 @@ npm install
## Преглед и самостоятелно обучение
В този урок научихте малко за историята на уеб браузъра; използвайте тази възможност, за да научите повече за това как създателите на Световната мрежа са си представяли нейното използване, като прочетете повече за нейната история. Някои полезни сайтове включват:
В този урок научихте малко за историята на уеб браузъра; използвайте тази възможност, за да научите повече за това как създателите на Световната мрежа са си представяли нейното използване, като прочетете повече за историята ѝ. Някои полезни сайтове включват:
[История на уеб браузърите](https://www.mozilla.org/firefox/browsers/browser-history/)
@ -172,11 +172,11 @@ npm install
[Интервю с Тим Бърнърс-Лий](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
## Задание
## Задача
[Променете стила на вашето разширение](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/25)
### Въведение
В този урок ще извикате API, като изпратите формуляра на вашето браузърно разширение и покажете резултатите в него. Освен това ще научите как да съхранявате данни в локалното хранилище на браузъра за бъдеща справка и употреба.
В този урок ще извикате API, като изпратите формата на вашето браузърно разширение и покажете резултатите в него. Освен това ще научите как да съхранявате данни в локалното хранилище на браузъра за бъдеща употреба.
✅ Следвайте номерираните сегменти в съответните файлове, за да знаете къде да поставите кода си.
### Настройка на елементите за манипулиране в разширението:
До този момент сте създали HTML за формуляра и `<div>` за резултатите в браузърното разширение. Оттук нататък ще трябва да работите във файла `/src/index.js` и да изграждате разширението си стъпка по стъпка. Прегледайте [предишния урок](../1-about-browsers/README.md) за настройка на проекта и процеса на изграждане.
До този момент сте създали HTML за формата и `<div>` за резултатите в браузърното разширение. Оттук нататък ще работите във файла `/src/index.js` и ще изграждате разширението си стъпка по стъпка. Вижте [предишния урок](../1-about-browsers/README.md) за настройка на проекта и процеса на изграждане.
Работейки във файла `index.js`, започнете със създаването на някои `const` променливи, които да държат стойностите, свързани с различни полета:
Работейки във файла `index.js`, започнете, като създадете някои `const` променливи, които да държат стойностите, свързани с различни полета:
Всички тези полета се реферират чрез техния CSS клас, както сте го настроили в HTML в предишния урок.
Всички тези полета са реферирани чрез техния CSS клас, както сте ги настроили в HTML в предишния урок.
### Добавяне на слушатели
След това добавете слушатели на събития към формуляра и бутона за изчистване, който нулира формуляра, така че ако потребителят изпрати формуляра или кликне върху бутона за нулиране, да се случи нещо. Добавете и извикване за инициализация на приложението в края на файла:
След това добавете слушатели на събития към формата и бутона за изчистване, който нулира формата, така че ако потребителят изпрати формата или кликне върху бутона за нулиране, да се случи нещо. Добавете и извикване за инициализация на приложението в края на файла:
В тази функция има интересна логика. Четейки я, можете ли да разберете какво се случва?
В тази функция има интересна логика. Прочитайки я, можете ли да видите какво се случва?
- Две `const` променливи се създават, за да проверят дали потребителят е съхранил APIKey и регионален код в локалното хранилище.
- Ако някоя от тях е null, показва формуляра, като променя стила му на 'block'.
- Скрива областта за резултати, зареждане и бутона за изчистване, и задава текста за грешка като празен низ.
- Ако някоя от тях е null, формата сепоказва, като стилът ѝ сепроменя на 'block'.
- Скриват се резултатите, зареждането и clearBtn, а текстът за грешка се задава като празен низ.
- Ако има ключ и регион, започва рутина за:
- извикване на API за получаване на данни за въглеродна употреба,
- извикване на API за получаване на данни за въглеродната употреба,
- скриване на областта за резултати,
- скриване на формуляра,
- скриване на формата,
- показване на бутона за нулиране.
Преди да продължите, е полезно да научите за много важна концепция, налична в браузърите: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage е полезен начин за съхраняване на низове в браузъра като двойки `ключ-стойност`. Този тип уеб хранилище може да бъде манипулиран чрез JavaScript за управление на данни в браузъра. LocalStorage не изтича, докато SessionStorage, друг вид уеб хранилище, се изчиства при затваряне на браузъра. Различните видове хранилища имат своите плюсове и минуси.
> Забележка - вашето браузърно разширение има собствено локално хранилище; основният прозорец на браузъра е отделен екземпляр и се държи независимо.
Можете да зададете стойност на вашия APIKey, например, и да видите, че е зададен в Edge, като "инспектирате" уеб страница (можете да кликнете с десния бутон върху браузъра, за да инспектирате) и отидете в раздела Applications, за да видите хранилището.
Задавате стойност на вашия APIKey, например, и можете да видите, че тойе зададен в Edge, като "инспектирате" уеб страница (можете да кликнете с десния бутон върху браузъра, за да инспектирате) и отидете в раздела Applications, за да видите хранилището.

✅ Помислете за ситуации, в които НЕ бихте искали да съхранявате някои данни в LocalStorage. Като цяло, поставянето на API ключове в LocalStorage е лоша идея! Можете ли да разберете защо? В нашия случай, тъй като приложението ни е само за обучение и няма да бъде публикувано в магазин за приложения, ще използваме този метод.
✅ Помислете за ситуации, в които НЕ бихте искали да съхранявате някои данни в LocalStorage. Като цяло, поставянето на API ключове в LocalStorage е лоша идея! Можете ли да видите защо? В нашия случай, тъй като приложението ни е само за обучение и няма да бъде публикувано в магазин за приложения, ще използваме този метод.
Обърнете внимание, че използвате Web API за манипулиране на LocalStorage, като използвате `getItem()`, `setItem()` или `removeItem()`. Той е широко поддържан в браузърите.
Преди да изградите функцията `displayCarbonUsage()`, която се извиква в `init()`, нека изградим функционалността за обработка на първоначалното изпращане на формуляра.
Преди да изградите функцията `displayCarbonUsage()`, която се извиква в `init()`, нека изградим функционалността за обработка на първоначалното изпращане на формата.
### Обработка на изпращането на формуляра
### Обработка на изпращането на формата
Създайте функция, наречена `handleSubmit`, която приема аргумент за събитие `(e)`. Спрете разпространението на събитието (в този случай искаме да спрем браузъра от обновяване) и извикайте нова функция, `setUpUser`, като предадете аргументите `apiKey.value` и `region.value`. По този начин използвате двете стойности, които се въвеждат чрез първоначалния формуляр, когато съответните полета са попълнени.
Създайте функция, наречена `handleSubmit`, която приема аргумент за събитие `(e)`. Спрете разпространението на събитието (в този случай искаме да спрем браузъра от обновяване) и извикайте нова функция, `setUpUser`, като предадете аргументите `apiKey.value` и `region.value`. По този начин използвате двете стойности, които се въвеждат чрез първоначалната форма, когато съответните полета са попълнени.
```JavaScript
function handleSubmit(e) {
@ -149,7 +149,7 @@ function setUpUser(apiKey, regionName) {
Тази функция показва съобщение за зареждане, докато се извиква API. На този етап сте стигнали до създаването на най-важната функция на това браузърно разширение!
### Показване на въглеродна употреба
### Показване на въглеродната употреба
Накрая е време да направите заявка към API!
@ -157,7 +157,7 @@ function setUpUser(apiKey, regionName) {
✅ Терминът 'REST' означава 'Representational State Transfer' и включва използването на различно конфигурирани URL адреси за извличане на данни. Направете малко проучване за различните видове API, достъпни за разработчиците. Кой формат ви допада?
Има важни неща, които трябва да отбележите за тази функция. Първо, обърнете внимание на [`async` ключовата дума](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Писането на вашите функции така, че да работят асинхронно, означава, че те изчакват завършването на действие, като например връщане на данни, преди да продължат.
Има важни неща, които трябва да отбележите за тази функция. Първо, обърнете внимание на [`async` ключовата дума](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Писането на вашите функции така, че да работят асинхронно, означава, че те изчакват дадено действие, като например връщане на данни, да бъде завършено, преди да продължат.
Ето кратко видео за `async`:
@ -207,7 +207,7 @@ async function displayCarbonUsage(apiKey, region) {
Това е голяма функция. Какво се случва тук?
- Следвайки добрите практики, използвате ключовата дума `async`, за да направите тази функция да работи асинхронно. Функцията съдържа блок `try/catch`, тъй като ще върне обещание, когато API върне данни. Тъй като нямате контрол върху скоростта, с която API ще отговори (може изобщо да не отговори!), трябва да се справите с тази несигурност, като я извикате асинхронно.
- Следвайки добрите практики, използвате ключовата дума `async`, за да направите тази функция асинхронна. Функцията съдържа блок `try/catch`, тъй като ще върне обещание, когато API върне данни. Тъй като нямате контрол върху скоростта, с която API ще отговори (може изобщо да не отговори!), трябва да се справите с тази несигурност, като я извикате асинхронно.
- Правите заявка към co2signal API, за да получите данни за вашия регион, използвайки вашия API ключ. За да използвате този ключ, трябва да използвате вид автентикация в параметрите на заглавката.
- След като API отговори, присвоявате различни елементи от неговите данни за отговор на частите от екрана, които сте настроили да показват тези данни.
- Ако има грешка или няма резултат, показвате съобщение за грешка.
@ -222,9 +222,9 @@ async function displayCarbonUsage(apiKey, region) {
Обсъдихме няколко типа API досега в тези уроци. Изберете уеб API и проучете подробно какво предлага. Например, разгледайте API, достъпни в браузърите, като [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Какво според вас прави един API страхотен?
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/26)
## Преглед и самостоятелно обучение
@ -237,4 +237,4 @@ async function displayCarbonUsage(apiKey, region) {
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
# Проект за браузърно разширение, част 3: Научете за фонови задачи и производителност
# Проект за браузърно разширение, част 3: Научете за фоновите задачи и производителността
## Тест преди лекцията
@ -15,7 +15,7 @@ CO_OP_TRANSLATOR_METADATA:
### Въведение
В последните два урока от този модул научихте как да създадете форма и зона за показване на данни, извлечени от API. Това е много стандартен начин за създаване на уеб присъствие. Дори научихте как да обработвате асинхронно извличане на данни. Вашето браузърно разширение е почти завършено.
В последните две уроци от този модул научихте как да създадете форма и зона за показване на данни, извлечени от API. Това е много стандартен начин за създаване на уеб присъствие. Дори научихте как да обработвате асинхронно извличане на данни. Вашето браузърно разширение е почти завършено.
Остава да управлявате някои фонови задачи, включително обновяване на цвета на иконата на разширението, така че това е чудесен момент да обсъдим как браузърът управлява този тип задачи. Нека разгледаме тези задачи в контекста на производителността на вашите уеб ресурси, докато ги изграждате.
@ -23,51 +23,51 @@ CO_OP_TRANSLATOR_METADATA:
> "Производителността на уебсайта се свежда до две неща: колко бързо се зарежда страницата и колко бързо работи кодът на нея." -- [Зак Гросбарт](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
Темата за това как да направите вашите уебсайтове изключително бързи на всякакви устройства, за всякакви потребители и в различни ситуации, е, разбира се, обширна. Ето някои точки, които да имате предвид, докато изграждате стандартен уеб проект или браузърно разширение.
Темата за това как да направите вашите уебсайтове изключително бързи на всякакви устройства, за всякакви потребители и във всякакви ситуации е, разбираемо, обширна. Ето някои точки, които да имате предвид, докато изграждате стандартен уеб проект или браузърно разширение.
Първото нещо, което трябва да направите, за да се уверите, че вашият сайт работи ефективно, е да съберете данни за неговата производителност. Първото място, където можете да направите това, е в инструментите за разработчици на вашия уеб браузър. В Edge можете да изберете бутона "Настройки и още" (иконата с три точки в горния десен ъгъл на браузъра), след това да отидете на Още инструменти > Инструменти за разработчици и да отворите раздела "Производителност". Можете също да използвате клавишните комбинации `Ctrl` + `Shift` + `I` на Windows или `Option` + `Command` + `I` на Mac, за да отворите инструментите за разработчици.
Първото нещо, което трябва да направите, за да се уверите, че вашият сайт работи ефективно, е да съберете данни за неговата производителност. Първото място за това са инструментите за разработчици на вашия уеб браузър. В Edge можете да изберете бутона "Настройки и още" (иконата с трите точки в горния десен ъгъл на браузъра), след това да отидете на Още инструменти > Инструменти за разработчици и да отворите раздела "Производителност". Можете също да използвате клавишните комбинации `Ctrl` + `Shift` + `I` на Windows или `Option` + `Command` + `I` на Mac, за да отворите инструментите за разработчици.
Разделът "Производителност" съдържа инструмент за профилиране. Отворете уебсайт (например [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) и кликнете върху бутона "Запис", след което обновете сайта. Спрете записа по всяко време и ще можете да видите рутините, които се генерират за 'скрипт', 'рендиране' и 'рисуване' на сайта:
Разделът "Производителност" съдържа инструмент за профилиране. Отворете уебсайт (например [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) и кликнете върху бутона "Запис", след което обновете сайта. Спрете записа по всяко време и ще можете да видите рутините, които се генерират за 'скриптиране', 'рендиране' и 'рисуване' на сайта:

✅ Посетете [документацията на Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) за панела "Производителност" в Edge.
✅ Посетете [документацията на Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) за раздела "Производителност" в Edge.
> Съвет: за да получите точни данни за времето за стартиране на вашия сайт, изчистете кеша на браузъра си.
Изберете елементи от времевата линия на профила, за да увеличите събитията, които се случват, докато страницата висе зарежда.
Изберете елементи от времевата линия на профила, за да увеличите събитията, които се случват, докато вашата страница се зарежда.
Получете моментна снимка на производителността на вашата страница, като изберете част от времевата линия на профила и разгледате панела със сумарни данни:
Получете моментна снимка на производителността на вашата страница, като изберете част от времевата линия на профила и разгледате панела за обобщение:


Проверете панела "Дневник на събитията", за да видите дали някое събитие е отнело повече от 15 ms:


✅ Запознайте сес вашия инструмент за профилиране! Отворете инструментите за разработчици на този сайт и вижте дали има някакви тесни места. Кой е най-бавно зареждащият сересурс? А най-бързият?
✅ Опознайте вашия профайлер! Отворете инструментите за разработчици на този сайт и вижте дали има някакви тесни места. Кой е най-бавно зареждащият сересурс? Най-бързият?
## Проверки при профилиране
## Проверки за профилиране
Като цяло, има някои "проблемни области", които всеки уеб разработчик трябва да следи, когато изгражда сайт, за да избегне неприятни изненади при внедряване в продукция.
Като цяло, има някои "проблемни области", които всеки уеб разработчик трябва да следи, когато изгражда сайт, за да избегне неприятни изненади при пускането му в продукция.
**Размери на ресурсите**: Уебът стана "по-тежък" и съответно по-бавен през последните години. Част от това теглосе дължи на използването на изображения.
**Размери на ресурсите**: Уебът стана "по-тежък" и следователно по-бавен през последните години. Част от тази тежестсе дължи на използването на изображения.
✅ Разгледайте [Интернет архива](https://httparchive.org/reports/page-weight) за исторически преглед на теглото на страниците и още.
Добра практика е да се уверите, че изображенията виса оптимизирани и доставени в правилния размер и резолюция за вашите потребители.
Добра практика е да се уверите, че вашите изображения са оптимизирани и доставени в правилния размер и резолюция за вашите потребители.
**Обхождане на DOM**: Браузърът трябва да изгради своя Document Object Model въз основа на кода, който пишете, така че в интерес на добрата производителност на страницата еда поддържате таговете минимални, като използвате и стилизирате само това, което е необходимо. Например, излишният CSS, свързан със страницата, може да бъде оптимизиран; стилове, които трябва да се използват само на една страница, не е необходимо да бъдат включени в основния стилов файл.
**Обхождане на DOM**: Браузърът трябва да изгради своя модел на документния обект (DOM) въз основа на кода, който пишете, така чее в интерес на добрата производителност на страницата да поддържате таговете минимални, като използвате и стилизирате само това, което страницата изисква. Например, излишният CSS, свързан със страницата, може да бъде оптимизиран; стилове, които трябва да се използват само на една страница, не е необходимо да бъдат включени в основния стилов файл.
**JavaScript**: Всеки JavaScript разработчик трябва да следи за скриптове, които блокират рендирането и трябва да бъдат заредени, преди останалата част от DOM да може да бъде обходена и нарисувана в браузъра. Помислете за използване на `defer`с вашите вградени скриптове (както е направено в модула Terrarium).
**JavaScript**: Всеки JavaScript разработчик трябва да следи за "скриптове, блокиращи рендирането", които трябва да бъдат заредени, преди останалата част от DOM да може да бъде обходена и нарисувана в браузъра. Помислете за използването на `defer`с вашите вградени скриптове (както е направено в модула Terrarium).
✅ Изпробвайте някои сайтове на [уебсайт за тест на скоростта](https://www.webpagetest.org/), за да научите повече за обичайните проверки, които се правят за определяне на производителността на сайта.
✅ Изпробвайте някои сайтове на [уебсайт за тестване на скорост](https://www.webpagetest.org/), за да научите повече за общите проверки, които се извършват за определяне на производителността на сайта.
Сега, когато имате представа как браузърът рендира ресурсите, които му изпращате, нека разгледаме последните няколко неща, които трябва да направите, за да завършите вашето разширение:
### Създайте функция за изчисляване на цвят
### Създайте функция за изчисляване на цвета
Работейки в `/src/index.js`, добавете функция, наречена `calculateColor()` след поредицата от `const` променливи, които сте задали, за да получите достъп до DOM:
Работейки в `/src/index.js`, добавете функция, наречена `calculateColor()` след серията от `const` променливи, които зададохте, за да получите достъп до DOM:
```JavaScript
function calculateColor(value) {
@ -88,11 +88,11 @@ function calculateColor(value) {
}
```
Какво се случва тук? Подавате стойност (интензитета на въглерода) от API извикването, което завършихте в последния урок, и след това изчислявате колко близка е стойността му до индекса, представен в масива с цветове. След това изпращате тази най-близка цветова стойност към chrome runtime.
Какво се случва тук? Подавате стойност (интензивността на въглерода) от API извикването, което завършихте в последния урок, и след това изчислявате колко близка енейната стойност до индекса, представен в масива с цветове. След това изпращате тази най-близка цветова стойност към chrome runtime.
Chrome.runtime има [API](https://developer.chrome.com/extensions/runtime), което обработва всякакви фонови задачи, и вашето разширение гоизползва:
Chrome.runtime има [API](https://developer.chrome.com/extensions/runtime), което обработва всякакви фонови задачи, и вашето разширение използва това:
> "Използвайте chrome.runtime API, за да извлечете фоновата страница, да върнете детайли за манифеста и да слушате и отговаряте на събития в жизнения цикъл на приложението или разширението. Можете също да използвате този API, за да конвертирате относителния път на URL адреси в напълно квалифицирани URL адреси."
> "Използвайте chrome.runtime API, за да извлечете фоновата страница, да върнете подробности за манифеста и да слушате и отговаряте на събития в жизнения цикъл на приложението или разширението. Можете също така да използвате този API, за да конвертирате относителния път на URL адресите в напълно квалифицирани URL адреси."
✅ Ако разработвате това браузърно разширение за Edge, може да ви изненада, че използвате chrome API. По-новите версии на браузъра Edge работят на браузърния енджин Chromium, така че можете да използвате тези инструменти.
@ -113,7 +113,7 @@ chrome.runtime.sendMessage({
### Извикайте функцията, изпълнете извикването
След това извикайте функцията, която току-що създадохте, като я добавите към обещанието, върнато от API на C02Signal:
След това извикайте функцията, която току-що създадохте, като я добавите към обещанието, върнато от C02Signal API:
```JavaScript
//let CO2...
@ -142,11 +142,11 @@ function drawIcon(value) {
}
```
В този код добавяте слушател за всякакви съобщения, идващи към мениджъра на фонови задачи. Ако е наречено 'updateIcon', следващият код се изпълнява, за да нарисува икона с правилния цвят, използвайки Canvas API.
В този код добавяте слушател за всякакви съобщения, идващи към мениджъра на фонови задачи. Ако се нарича 'updateIcon', следващият код се изпълнява, за да нарисува икона с правилния цвят, използвайки Canvas API.
✅ Ще научите повече за Canvas API в [уроците за космическата игра](../../6-space-game/2-drawing-to-canvas/README.md).
Сега, изградете отново вашето разширение (`npm run build`), обновете и стартирайте разширението си и наблюдавайте как цветът се променя. Добър момент ли е да излезете за малко или да измиете чиниите? Сега знаете!
Сега, изградете отново вашето разширение (`npm run build`), обновете и стартирайте вашето разширение и наблюдавайте как цветът се променя. Добър момент ли е да излезете за малко или да измиете чиниите? Сега знаете!
Поздравления, създадохте полезно браузърно разширение и научихте повече за това как работи браузърът и как да профилирате неговата производителност.
@ -154,7 +154,7 @@ function drawIcon(value) {
## 🚀 Предизвикателство
Разгледайте някои отворени уебсайтове, които съществуват отдавна, и въз основа на тяхната история в GitHub, вижте дали можете да определите как са били оптимизирани през годините за производителност, ако изобщоса били. Коя е най-честата проблемна точка?
Разгледайте някои уебсайтовес отворен код, които съществуват отдавна, и въз основа на тяхната история в GitHub, вижте дали можете да определите как са били оптимизирани през годините за производителност, ако изобщо. Кой е най-често срещаният проблем?
## Тест след лекцията
@ -162,9 +162,9 @@ function drawIcon(value) {
## Преглед и самостоятелно обучение
Обмислете да се абонирате за [бюлетин за производителност](https://perf.email/).
Помислете за абониране за [бюлетин за производителност](https://perf.email/).
Разгледайте някои от начините, по които браузърите оценяват уеб производителността, като прегледате разделите за производителност в техните уеб инструменти. Откривате ли някакви съществени разлики?
Разгледайте някои от начините, по които браузърите оценяват уеб производителността, като разгледате разделите за производителност в техните уеб инструменти. Намирате ли някакви съществени разлики?
## Задание
@ -173,4 +173,4 @@ function drawIcon(value) {
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/29)
### Наследяване и композиция в разработката на игри
В предишните уроци не беше необходимо да се замисляте много за архитектурата на приложенията, които създавахте, тъй като проектите бяха с малък обхват. Но когато приложенията ви нарастват по размер и сложност, архитектурните решения стават по-важни. Има два основни подхода за създаване на по-големи приложения в JavaScript: *композиция* или *наследяване*. И двата подхода имат своите предимства и недостатъци, но нека ги обясним в контекста на игра.
В предишните уроци не беше необходимо да се замисляте много за архитектурата на приложенията, които създавахте, тъй като проектите бяха с малък обхват. Но когато приложенията ви нараснат по размер и сложност, архитектурните решения стават по-важни. Има два основни подхода за създаване на по-големи приложения в JavaScript: *композиция* или *наследяване*. И двата подхода имат своите предимства и недостатъци, но нека ги разгледаме в контекста на игра.
✅ Една от най-известните книги за програмиране е свързана с [дизайн модели](https://en.wikipedia.org/wiki/Design_Patterns).
В една игра имате `обекти на играта`, които са обекти, съществуващи на екрана. Това означава, че те имат местоположение в декартова координатна система, характеризирано с`x` и `y` координати. Докато разработвате игра, ще забележите, че всички обекти на играта имат стандартни свойства, общи за всяка игра, която създавате, а именно елементи, които са:
В една игра имате `обекти на играта`, които са обекти, съществуващи на екрана. Това означава, че те имат местоположение в декартова координатна система, характеризирано скоординати `x` и `y`. Докато разработвате игра, ще забележите, че всички обекти на играта имат стандартни свойства, общи за всяка игра, която създавате, а именно елементи, които са:
- **базирани на местоположение** Повечето, ако не всички, елементи на играта са базирани на местоположение. Това означава, че те имат местоположение, `x` и `y`.
- **подвижни** Това са обекти, които могат да се преместят на ново местоположение. Обикновено това е герой, чудовище или NPC (персонаж, който не е играч), но не например статичен обект като дърво.
@ -38,7 +38,7 @@ CO_OP_TRANSLATOR_METADATA:
Идеята е да използваме `класове` в комбинация с`наследяване`, за да добавим определено поведение към даден клас.
✅ Наследяването е важна концепция за разбиране. Научете повече от [статията на MDN за наследяване](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
✅ Наследяването е важна концепция за разбиране. Научете повече от [статията на MDN за наследяването](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
Изразено чрез код, обект на играта обикновено изглежда така:
@ -88,11 +88,11 @@ hero.moveTo(5,5);
const tree = new Tree();
```
✅ Отделете няколко минути, за да си представите герой от Pac-Man (например Inky, Pinky или Blinky) и как би изглеждал в JavaScript.
✅ Отделете няколко минути, за да си представите герой от Pac-Man (например Inky, Pinky или Blinky) и как би бил написан на JavaScript.
**Композиция**
Друг начин за управление на наследяването на обекти е чрез използване на *композиция*. Тогава обектите изразяват своето поведение по следния начин:
Друг начин за обработка на наследяването на обекти е чрез използване на *композиция*. Тогава обектите изразяват своето поведение по следния начин:
```javascript
//create a constant gameObject
@ -145,17 +145,17 @@ const tree = createStatic(0,0, 'Tree');
Друг модел, често срещан в разработката на игри, се занимава с проблема за управлението на потребителското изживяване и производителността на играта.
## Модел Pub/sub
## Модел Pub/Sub
✅ Pub/Sub означава 'публикуване-абониране'
Този модел разглежда идеята, че различните части на вашето приложение не трябва да знаят една за друга. Защо? Това прави много по-лесно да се разбере какво се случва като цяло, ако различните части са разделени. Също така улеснява внезапната промяна на поведението, ако е необходимо. Как постигаме това? Чрез установяване на някои концепции:
Този модел разглежда идеята, че различните части на вашето приложение не трябва да знаят една за друга. Защо? Това прави много по-лесно да се разбере какво се случва като цяло, ако различните части са разделени. Освен това улеснява внезапната промяна на поведението, ако е необходимо. Как постигаме това? Чрез установяване на няколко концепции:
- **съобщение**: Съобщението обикновено е текстов низ, придружен от опционален полезен товар (част от данни, която уточнява за какво е съобщението). Типично съобщение в игра може да бъде `KEY_PRESSED_ENTER`.
- **съобщение**: Съобщението обикновено е текстов низ, придружен от незадължителен полезен товар (част от данни, която уточнява за какво е съобщението). Типично съобщение в игра може да бъде `KEY_PRESSED_ENTER`.
- **публикуващ**: Този елемент *публикува* съобщение и го изпраща до всички абонати.
- **абонат**: Този елемент *слуша* конкретни съобщения и изпълнява определена задача в резултат на получаването на това съобщение, като например изстрелване на лазер.
- **абонат**: Този елемент *слуша*за конкретни съобщения и изпълнява някаква задача в резултат на получаването на това съобщение, като например изстрелване на лазер.
Реализацията е доста малка по размер, но това е много мощен модел. Ето как може да бъде реализиран:
Реализацията е доста малка по размер, но е много мощен модел. Ето как може да бъде реализиран:
```javascript
//set up an EventEmitter class that contains listeners
Горе свързваме събитие от клавиатурата, `ArrowLeft`, и изпращаме съобщението `HERO_MOVE_LEFT`. Слушаме това съобщение и преместваме`hero` в резултат. Силата на този модел е, че слушателят на събития и героят не знаят един за друг. Можете да пренасочите `ArrowLeft` към клавиша `A`. Освен това е възможно да направите нещо напълно различно при `ArrowLeft`, като направите няколко редакции на функцията `on` на eventEmitter:
Горе свързваме събитие от клавиатурата, `ArrowLeft`, и изпращаме съобщението `HERO_MOVE_LEFT`. Слушаме това съобщение и местим`hero` в резултат. Силата на този модел е, че слушателят на събития и героят не знаят един за друг. Можете да пренастроите `ArrowLeft` към клавиша `A`. Освен това би било възможно да направите нещо напълно различно при `ArrowLeft`, като направите няколко редакции на функцията `on` на eventEmitter:
Помислете как моделът pub-sub може да подобри играта. Кои части трябва да излъчват събития и как играта трябва да реагира на тях? Сегае вашият шанс да бъдете креативни, като измислите нова игра и как нейните части могат да се държат.
Помислете как моделът pub-sub може да подобри една игра. Кои части трябва да излъчват събития и как играта трябва да реагира на тях? Сегае вашият шанс да бъдете креативни, като измислите нова игра и как нейните части могат да се държат.
@ -33,16 +33,16 @@ Canvas е HTML елемент, който по подразбиране няма
## Рисуване на прости геометрични фигури
Canvas използва картезианска координатна система за рисуване. Следователно използва x-ос и y-ос, за да изрази местоположението на нещо. Местоположението`0,0`е горният ляв ъгъл, а долният десен е това, което сте задали като WIDTH и HEIGHT на платното.
Canvas използва декартова координатна система за рисуване. Следователно използва x-ос и y-ос, за да изрази къде се намира нещо. Локацията`0,0`е горният ляв ъгъл, а долният десен е това, което сте задали като WIDTH и HEIGHT на canvas.


> Изображение от [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
За да рисувате върху елемента Canvas, трябва да преминете през следните стъпки:
За да рисувате върху елемента canvas, трябва да преминете през следните стъпки:
1. **Получете референция** към елемента Canvas.
1. **Получете референция** към елемента Context, който се намира върху Canvas.
1. **Извършете операция за рисуване** с помощта на елемента Context.
1. **Получете референция** към елемента Canvas.
2. **Получете референция** към Context елемента, който се намира върху canvas елемента.
3. **Извършете операция по рисуване** с помощта на context елемента.
✅ Canvas API основно се фокусира върху 2D форми, но можете също да рисувате 3D елементи на уеб страница; за това може да използвате [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
С Canvas API можете да рисувате всякакви неща, като:
С Canvas API можете да рисувате всякакви неща, като например:
- **Геометрични фигури**: вече показахме как да нарисувате правоъгълник, но има много повече, което можете да нарисувате.
- **Текст**: можете да нарисувате текст с всякакъв шрифт и цвят, който пожелаете.
- **Изображения**: можете да нарисувате изображение, базирано на актив като .jpg или .png например.
- **Геометрични фигури**– вече показахме как да нарисувате правоъгълник, но има още много, което можете да нарисувате.
- **Текст**– можете да рисувате текст с всякакъв шрифт и цвят, който пожелаете.
- **Изображения**– можете да рисувате изображение, базирано на ресурс като .jpg или .png, например.
✅ Опитайте! Знаете как да нарисувате правоъгълник, можете ли да нарисувате кръг на страницата? Разгледайте някои интересни рисунки с Canvas в CodePen. Ето [особено впечатляващ пример](https://codepen.io/dissimulate/pen/KrAwx).
## Зареждане и рисуване на изображение
Можете да заредите изображение, като създадете обект `Image` и зададете неговото свойство `src`. След това слушате събитието `load`, за да знаете кога е готово за използване. Кодът изглежда така:
Можете да заредите изображение, като създадете обект `Image` и зададете неговото свойство `src`. След това слушате събитието `load`, за да разберете кога е готово за използване. Кодът изглежда така:
### Зареждане на актив
### Зареждане на ресурс
```javascript
const img = new Image();
@ -85,9 +85,9 @@ img.onload = () => {
}
```
### Шаблон за зареждане на актив
### Шаблон за зареждане на ресурс
Препоръчително еда обвиете горното в конструкция като тази, за да е по-лесно за използване и да сеопитате да го манипулирате само когато е напълно заредено:
Препоръчително егорното да бъде обвито в конструкция като тази, за да е по-лесно за използване и да сеуверите, че манипулирате изображението само когато е напълно заредено:
```javascript
function loadAsset(path) {
@ -110,7 +110,7 @@ async function run() {
```
За да нарисувате активи от играта на екрана, вашият код би изглеждал така:
За да нарисувате игрови ресурси на екрана, кодът ви би изглеждал така:
```javascript
async function run() {
@ -124,17 +124,17 @@ async function run() {
}
```
## Време е да започнете да изграждате вашата игра
## Време е да започнете да изграждате играта си
### Какво да изградите
Ще създадете уеб страница селемент Canvas. Тя трябва да показва черен екран с размери `1024*768`. Предоставили сме ви две изображения:
Ще създадете уеб страница сCanvas елемент. Тя трябва да изобразява черен екран с размери `1024*768`. Предоставили сме ви две изображения:
- Кораб на героя
- Кораб на героя

- 5*5 чудовища
- 5*5 чудовища

@ -151,16 +151,16 @@ async function run() {
-| package.json
```
Отворете копие на тази папка в Visual Studio Code. Трябва да имате локална среда за разработка, за предпочитане с Visual Studio Codeс NPM и Node инсталирани. Ако нямате `npm` настроен на вашия компютър, [ето как да го направите](https://www.npmjs.com/get-npm).
Отворете копие на тази папка във Visual Studio Code. Трябва да имате настроена локална среда за разработка, за предпочитане с Visual Studio Code, NPM и Node. Ако нямате инсталиран `npm` на компютъра си, [ето как да го направите](https://www.npmjs.com/get-npm).
Започнете вашия проект, като навигирате до папката `your_work`:
Стартирайте проекта си, като навигирате до папката `your_work`:
```bash
cd your-work
npm start
```
Горният код ще стартира HTTP сървър на адрес `http://localhost:5000`. Отворете браузър и въведете този адрес. В момента страницата е празна, но това ще се промени.
Горното ще стартира HTTP сървър на адрес `http://localhost:5000`. Отворете браузър и въведете този адрес. В момента страницата е празна, но това ще се промени.
> Забележка: за да видите промените на екрана, обновете браузъра си.
@ -168,14 +168,14 @@ npm start
Добавете необходимия код в `your-work/app.js`, за да решите следното:
1. **Нарисувайте** Canvas с черен фон
> съвет: добавете два реда под съответния TODO в `/app.js`, задавайки елемента `ctx` да бъде черен, а горните/левите координати да са 0,0, а височината и ширината да съответстват на Canvas.
1. **Нарисувайте** canvas с черен фон
> съвет: добавете два реда под съответния TODO в `/app.js`, задавайки елемента `ctx` да бъде черен, а горните/левите координати да са 0,0, като височината и ширината да съвпадат с тези на canvas.
2. **Заредете** текстури
> съвет: добавете изображенията на играча и врага, използвайки `await loadTexture` и подавайки пътя на изображението. Все още няма да ги видите на екрана!
> съвет: добавете изображенията на играча и враговете, използвайки `await loadTexture` и подавайки пътя към изображението. Все още няма да ги виждате на екрана!
3. **Нарисувайте** героя в центъра на екрана в долната половина
> съвет: използвайте API-то `drawImage`, за да нарисувате heroImg на екрана, задавайки `canvas.width / 2 - 45` и `canvas.height - canvas.height / 4)`.
> съвет: използвайте API-то `drawImage`, за да нарисувате heroImg на екрана, задавайки `canvas.width / 2 - 45` и `canvas.height - canvas.height / 4`.
4. **Нарисувайте** 5*5 чудовища
> съвет: сега можете да разкоментирате кода за рисуване на враговете на екрана. След това отидете във функцията `createEnemies` и я изградете.
> съвет: сега можете да разкоментирате кода за рисуване на враговете на екрана. След това отидете във функцията `createEnemies` и я изградете.
Първо, задайте някои константи:
@ -186,7 +186,7 @@ npm start
const STOP_X = START_X + MONSTER_WIDTH;
```
след това създайте цикъл, за да нарисувате масива от чудовища на екрана:
след това създайте цикъл, за да нарисувате масива от чудовища на екрана:
```javascript
for (let x = START_X; x <STOP_X;x+=98){
@ -198,23 +198,23 @@ npm start
## Резултат
Завършеният резултат трябва да изглежда така:
Крайният резултат трябва да изглежда така:

## Решение
Опитайте първо да го решите сами, но ако се затрудните, погледнете [решението](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
Моля, опитайте да го решите сами първо, но ако се затрудните, погледнете [решението](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
---
## 🚀 Предизвикателство
Научихте за рисуване с 2D-фокусирания Canvas API; разгледайте [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) и опитайте да нарисувате 3D обект.
Научихте за рисуванетос 2D-фокусирания Canvas API; разгледайте [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) и опитайте да нарисувате 3D обект.
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/32)
## Преглед и самостоятелно обучение
@ -222,9 +222,9 @@ npm start
## Задание
[Играйте с Canvas API](assignment.md)
[Работете с Canvas API](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Игрите не са много забавни, докато не започнат да се появяват извънземни на екрана! В тази игра ще използваме два типа движения:
Игрите не са много забавни, докато не започнат да се появяват извънземни, които се движат по екрана! В тази игра ще използваме два типа движения:
- **Движение с клавиатура/мишка**: когато потребителят взаимодейства с клавиатурата или мишката, за да премести обект на екрана.
- **Движение, предизвикано от играта**: когато играта премества обект с определен времеви интервал.
- **Движение, предизвикано от играта**: когато играта премества обект на определен времеви интервал.
Как всъщност движим нещата на екрана? Всичко се свежда до картезиански координати: променяме местоположението (x, y) на обекта и след това прерисуваме екрана.
Обикновено са нужни следните стъпки, за да постигнем *движение* на екрана:
1. **Задаване на ново местоположение** за обект; това е необходимо, за да изглежда, че обектът сее преместил.
1. **Задаване на ново местоположение** за обект; това е необходимо, за да се възприеме обектът като преместен.
2. **Изчистване на екрана**, екранът трябва да бъде изчистен между рисуванията. Можем да го изчистим, като нарисуваме правоъгълник, който запълваме с фонов цвят.
3. **Прерисуване на обекта** на новото местоположение. По този начин постигаме преместването на обекта от едно място на друго.
Обработвате събития, като свързвате специфични събития с код. Събитията от клавиатурата се задействат върху целия прозорец, докато събитията от мишката, като `click`, могат да бъдат свързани с кликване върху конкретен елемент. Ще използваме събития от клавиатурата през целия проект.
Събитията се обработват чрез свързване на специфични събития с код. Събитията от клавиатурата се задействат върху целия прозорец, докато събитията от мишката, като `click`, могат да бъдат свързани с кликване върху конкретен елемент. Ще използваме събития от клавиатурата през целия проект.
За да обработите събитие, трябва да използвате метода `addEventListener()` на прозореца и да му предоставите два входни параметъра. Първият параметър е името на събитието, например `keyup`. Вторият параметър е функцията, която трябва да бъде извикана в резултат на настъпването на събитието.
- `key`, това е текстово представяне на натиснатия клавиш, например `ArrowUp`.
- `keyCode`, това е числово представяне, например `37`, което съответства на `ArrowLeft`.
✅ Манипулирането на събития от клавиатурата е полезно извън разработката на игри. За какви други приложения можете да се сетите за тази техника?
✅ Манипулацията на събития от клавиатурата е полезна извън разработката на игри. За какви други приложения можете да се сетите за тази техника?
### Специални клавиши: предупреждение
Има някои *специални* клавиши, които влияят на прозореца. Това означава, че ако слушате събитие `keyup` и използвате тези специални клавиши, за да преместите героя си, това също ще извърши хоризонтално превъртане. Поради тази причина може да искате да *изключите* това вградено поведение на браузъра, докато изграждате играта си. Ще ви трябва код като този:
Има някои *специални* клавиши, които влияят на прозореца. Това означава, че ако слушате събитие `keyup` и използвате тези специални клавиши, за да преместите героя си, те също ще извършат хоризонтално превъртане. Поради тази причина може да искате да *изключите* това вградено поведение на браузъра, докато изграждате играта си. Ще ви трябва код като този:
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
Горният код ще гарантира, че клавишите със стрелки и клавишът за интервал имат своето *по подразбиране* поведение изключено. Механизмът за *изключване*се случва, когато извикваме `e.preventDefault()`.
Горният код ще гарантира, че клавишите със стрелки и клавишът за интервал имат своето *по подразбиране* поведение изключено. Механизмът за *изключване*се случва, когато извикаме `e.preventDefault()`.
## Движение, предизвикано от играта
Можем да накараме нещата да се движат сами, като използваме таймери като функциите `setTimeout()` или `setInterval()`, които актуализират местоположението на обекта при всяко тикване или времеви интервал. Ето как може да изглежда това:
Можем да накараме нещата да се движат сами, като използваме таймери като функциите `setTimeout()` или `setInterval()`, които актуализират местоположението на обекта на всяко тикване или времеви интервал. Ето как може да изглежда това:
```javascript
let id = setInterval(() => {
@ -103,9 +103,9 @@ let id = setInterval(() => {
## Игровият цикъл
Игровият цикъл е концепция, която представлява функция, извиквана на редовни интервали. Нарича се игров цикъл, защото всичко, което трябва да бъде видимо за потребителя, се рисува в цикъла. Игровият цикъл използва всички игрови обекти, които са част от играта, като рисува всички тях, освен ако по някаква причина не трябва да бъдат част от играта. Например, ако обектът е враг, който е бил ударен от лазер и сее взривил, той вече не е част от текущия игров цикъл (ще научите повече за това в следващите уроци).
Игровият цикъл е концепция, която представлява функция, извиквана на редовни интервали. Нарича се игрови цикъл, защото всичко, което трябва да бъде видимо за потребителя, се рисува в цикъла. Игровият цикъл използва всички игрови обекти, които са част от играта, като ги рисува, освен ако по някаква причина не трябва да бъдат част от играта повече. Например, ако обектът е враг, който е бил ударен от лазер и сее взривил, той вече не е част от текущия игрови цикъл (ще научите повече за това в следващите уроци).
Ето как обикновено може да изглежда игров цикъл, изразен в код:
Ето как обикновено може да изглежда игровият цикъл, изразен в код:
```javascript
let gameLoopId = setInterval(() =>
@ -121,7 +121,7 @@ let gameLoopId = setInterval(() =>
Горният цикъл се извиква на всеки `200` милисекунди, за да прерисува платното. Имате възможност да изберете най-добрия интервал, който има смисъл за вашата игра.
## Продължаване на космическата игра
## Продължаване на Космическата Игра
Ще вземете съществуващия код и ще го разширите. Можете да започнете с кода, който сте завършили по време на част I, или да използвате кода от [Част II - стартов](../../../../6-space-game/3-moving-elements-around/your-work).
@ -154,7 +154,7 @@ npm start
1. **Добавете специални обекти** за `hero`, `enemy` и `game object`, те трябва да имат свойства `x` и `y`. (Спомнете си частта за [Наследяване или композиция](../README.md)).
*ПОДСКАЗКА*`game object` трябва да бъде този с`x` и `y` и способността да се рисува върху платно.
*ПОДСКАЗКА*`game object` трябва да бъде този с`x` и `y` и способността да се рисува върху платното.
>подсказка: започнете, като добавите нов клас GameObject с неговия конструктор, дефиниран както следва, и след това го нарисувайте върху платното:
@ -207,7 +207,7 @@ npm start
2. **Добавете обработчици на събития от клавиатурата**, за да обработвате навигацията с клавиши (преместване на героя нагоре/надолу, наляво/надясно).
*ЗАПОМНЕТЕ* това е картезианска система, горният ляв ъгъл е`0,0`. Също така не забравяйте да добавите код за спиране на *поведение по подразбиране*.
*ЗАПОМНЕТЕ* това е картезианска система, горният ляв ъгъл е`0,0`. Също така не забравяйте да добавите код за спиране на *по подразбиране поведение*.
>подсказка: създайте своя функция onKeyDown и я свържете с прозореца:
@ -313,7 +313,7 @@ npm start
1. **Настройте игровия цикъл**
Рефакторирайте функцията window.onload, за да инициализирате играта и да настроите игров цикъл на подходящ интервал. Ще добавите и лазерен лъч:
Рефакторирайте функцията window.onload, за да инициализирате играта и да настроите игрови цикъл на подходящ интервал. Ще добавите и лазерен лъч:
```javascript
window.onload = async () => {
@ -334,9 +334,9 @@ npm start
};
```
5. **Добавете код** за движение на враговете на определен интервал
5. **Добавете код**, за да движите враговете на определен интервал
Рефакторирайте функцията `createEnemies()`, за да създадете враговете и да ги добавите към новия клас gameObjects:
Рефакторирайте функцията `createEnemies()`, за да създадете враговете и да ги добавите в новия клас gameObjects:
```javascript
function createEnemies() {
@ -388,9 +388,9 @@ npm start
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/34)
## Преглед и самостоятелно обучение
## Преглед и Самостоятелно Учение
Докато пишем играта си без използване на рамки, има много JavaScript-базирани рамки за платно за разработка на игри. Отделете време да направите [проучване за тях](https://github.com/collections/javascript-game-engines).
Докато пишем играта си без използване на рамки, има много JavaScript-базирани рамки за платно за разработка на игри. Отделете време да направите [четене за тях](https://github.com/collections/javascript-game-engines).
## Задание
@ -399,4 +399,4 @@ npm start
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
В този урок ще научите как да стреляте с лазери с помощта на JavaScript! Ще добавим две неща към нашата игра:
- **Лазер**: този лазер се изстрелва от кораба на героя и се движи вертикално нагоре.
- **Откриване на сблъсъци**, като част от реализирането на способността за *стрелба*, ще добавим някои интересни правила за игра:
- **Откриване на сблъсъци**: като част от реализирането на способността за *стрелба*, ще добавим някои интересни правила за играта:
- **Лазер удря враг**: Врагът умира, ако бъде ударен от лазер.
- **Лазер удря горната част на екрана**: Лазерът се унищожава, ако удари горната част на екрана.
- **Сблъсък между враг и герой**: Врагът и героят се унищожават, ако се сблъскат.
- **Враг удря долната част на екрана**: Врагът и героят се унищожават, ако врагът достигне долната част на екрана.
Накратко, вие -- *героят* -- трябва да унищожите всички врагове с лазер, преди те да достигнат долната част на екрана.
Накратко, вие -- *героят* -- трябва да унищожите всички врагове с лазер, преди те да успеят да достигнат долната част на екрана.
✅ Направете малко проучване за първата компютърна игра, която някога е била създадена. Каква беше нейната функционалност?
✅ Направете малко проучване за първата компютърна игра, която някога е била написана. Каква беше нейната функционалност?
Нека бъдем героични заедно!
## Откриване на сблъсъци
Как да откриваме сблъсъци? Трябва да мислим за обектите в играта като за правоъгълници, които се движат. Защо, може би ще попитате? Е, изображението, използвано за рисуване на обект в играта, е правоъгълник: има `x`, `y`, `ширина` и `височина`.
Как да откриваме сблъсъци? Трябва да мислим за обектите в играта като за правоъгълници, които се движат. Защо, може би ще попитате? Е, изображението, използвано за рисуване на обект в играта, е правоъгълник: то има `x`, `y`, `width` и `height`.
Ако два правоъгълника, например герой и враг, *се пресекат*, имаме сблъсък. Какво трябва да се случи след това зависи от правилата на играта. За да реализирате откриване на сблъсъци, ви е необходимо следното:
1. Начин за получаване на правоъгълно представяне на обект в играта, нещо като това:
1. Начин за получаване на правоъгълно представяне на обект в играта, нещо подобно:
```javascript
rectFromGameObject() {
@ -58,16 +58,16 @@ CO_OP_TRANSLATOR_METADATA:
}
```
## Как да унищожаваме обекти
## Как унищожаваме обекти
За да унищожите обекти в играта, трябва да уведомите играта, че този обект вече не трябва да се рисува в игровия цикъл, който се задейства на определен интервал. Един начин да направите това е да маркирате обекта като *мъртъв*, когато се случи нещо, например:
За да унищожите обекти в играта, трябва да уведомите играта, че този обект вече не трябва да се рисува в игровия цикъл, който се задейства на определен интервал. Един начин да направите това е да маркирате обект като *мъртъв*, когато се случи нещо, например:
```javascript
// collision happened
enemy.dead = true
```
След това можете да премахнете *мъртвите* обекти, преди да се нарисува екранът, например:
След това можете да премахнете *мъртвите* обекти преди повторното рисуване на екрана, например:
```javascript
gameObjects = gameObject.filter(go => !go.dead);
@ -109,13 +109,13 @@ class Weapon {
}
```
✅ Върнете се към урок 1 от серията за космическата игра, за да си припомните концепцията за *забавяне*.
✅ Върнете се към урок 1 от поредицата за космическата игра, за да си припомните концепцията за *забавяне*.
## Какво да изградим
Ще вземете съществуващия код (който трябва да сте почистили и рефакторирали) от предишния урок и ще го разширите. Можете да започнете с кода от част II или да използвате кода от [Част III - стартов код](../../../../../../../../../your-work).
Ще вземете съществуващия код (който трябва да сте почистили и рефакторирали) от предишния урок и ще го разширите. Можете да започнете с кода от част II или да използвате кода от [Part III- starter](../../../../../../../../../your-work).
> съвет: лазерът, с който ще работите, вече е в папката с ресурси и е рефериран от вашия код
> съвет: лазерът, с който ще работите, вече е в папката свашите ресурси и е рефериран от вашия код.
- **Добавете откриване на сблъсъци**, когато лазерът се сблъска с нещо, трябва да се приложат следните правила:
1. **Лазер удря враг**: врагът умира, ако бъде ударен от лазер.
@ -191,7 +191,7 @@ npm start
}
```
1. **Добавете слушатели**. Редактирайте функцията `initGame()`, за да гарантирате, че героят може да стреля, когато се натисне клавишът space:
1. **Добавете слушатели**. Редактирайте функцията `initGame()`, за да гарантирате, че героят може да стреля, когато клавишът spaceе натиснат:
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -230,7 +230,7 @@ npm start
}
```
1. **Обработете сблъсъци**, Реализирайте правила за сблъсъци за лазера. Добавете функция `updateGameObjects()`, която тества сблъсъци между обекти:
1. **Обработете сблъсъци**, Реализирайте правила за сблъсъци за лазера. Добавете функция `updateGameObjects()`, която тества сблъскващи се обекти за удари:
```javascript
function updateGameObjects() {
@ -252,7 +252,7 @@ npm start
}
```
Уверете се, че сте добавили `updateGameObjects()`в игровия цикъл в `window.onload`.
Уверете се, че сте добавили `updateGameObjects()`към игровия цикъл в `window.onload`.
4. **Реализирайте забавяне** за лазера, така че да може да се изстрелва само през определен интервал.
@ -291,7 +291,7 @@ npm start
## 🚀 Предизвикателство
Добавете експлозия! Разгледайте ресурсите за играта в [репото Space Art](../../../../6-space-game/solution/spaceArt/readme.txt) и опитайте да добавите експлозия, когато лазерът удари извънземно.
Добавете експлозия! Разгледайте ресурсите за играта в [репото Space Art](../../../../6-space-game/solution/spaceArt/readme.txt) и опитайте да добавите експлозия, когато лазер удари извънземно.
## Финален тест
@ -308,4 +308,4 @@ npm start
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
[Тест преди лекцията](https://ff-quizzes.netlify.app/web/quiz/37)
В този урок ще научите как да добавите точки към играта и как да изчислявате животи.
В този урок ще научите как да добавите точки към играта и да изчислявате животи.
## Рисуване на текст на екрана
@ -30,14 +30,14 @@ ctx.fillText("show this on the screen", 0, 0);
## Животът като концепция в игрите
Концепцията за живот в играта е просто число. В контекста на космическа игра е обичайно да се задават определен брой животи, които се намаляват един по един, когато вашият кораб понася щети. Ще е хубаво, ако можете да покажете графично представяне на това, например миникорабчета или сърца, вместо просто число.
Концепцията за живот в играта е просто число. В контекста на космическа игра е обичайно да се задават определен брой животи, които се намаляват един по един, когато вашият кораб понася щети. Добре е, ако можете да покажете графично представяне на това, например миникорабчета или сърца, вместо число.
## Какво да изградите
Нека добавим следното към вашата игра:
- **Резултат от играта**: За всеки унищожен вражески кораб, героят трябва да получава точки. Предлагаме 100 точки на кораб. Резултатът от играта трябва да се показва в долния ляв ъгъл.
- **Живот**: Вашият кораб има три живота. Губите живот всеки път, когато вражески кораб се сблъска с вас. Броят на животите трябва да се показва в долния десен ъгъл и да бъде представен с графика като тази: .
- **Резултат от играта**: За всеки унищожен вражески кораб, героят трябва да получава точки– предлагаме 100 точки на кораб. Резултатът от играта трябва да се показва в долния ляв ъгъл.
- **Живот**: Вашият кораб има три живота. Губите живот всеки път, когато вражески кораб се сблъска с вас. Броят на животите трябва да се показва в долния десен ъгъл и да бъде представен с графика като тази .
## Препоръчителни стъпки
@ -53,7 +53,7 @@ ctx.fillText("show this on the screen", 0, 0);
-| package.json
```
Започнете проекта си в папката `your_work`, като напишете:
Стартирайте проекта си в папката `your_work`, като напишете:
```bash
cd your-work
@ -64,7 +64,7 @@ npm start
### Добавяне на код
1. **Копирайте необходимите ресурси** от папката `solution/assets/` в папката `your-work`. Ще добавите ресурса`life.png`. Добавете lifeImg към функцията window.onload:
1. **Копирайте необходимите ресурси** от папката `solution/assets/` в папката `your-work`; ще добавите ресурса`life.png`. Добавете `lifeImg` към функцията `window.onload`:
```javascript
lifeImg = await loadTexture("assets/life.png");
@ -80,7 +80,7 @@ npm start
eventEmitter = new EventEmitter();
```
2. **Добавете променливи**. Добавете код, който представлява общия резултат (0) и оставащите животи (3), и ги покажете на екрана.
2. **Добавете променливи**. Добавете код, който представя общия резултат (0) и оставащите животи (3), и ги показвайте на екрана.
3. **Разширете функцията `updateGameObjects()`**. Разширете функцията `updateGameObjects()`, за да обработва сблъсъци с врагове:
@ -94,14 +94,14 @@ npm start
```
4. **Добавете `life` и `points`**.
1. **Инициализирайте променливи**. Под `this.cooldown = 0` в класа `Hero` задайте life и points:
1. **Инициализирайте променливи**. Под `this.cooldown = 0` в класа `Hero` задайте `life` и `points`:
```javascript
this.life = 3;
this.points = 0;
```
1. **Рисувайте променливите на екрана**. Покажете тези стойности на екрана:
1. **Рисувайте променливите на екрана**. Показвайте тези стойности на екрана:
```javascript
function drawLife() {
@ -128,7 +128,7 @@ npm start
```
1. **Добавете методи към игровия цикъл**. Уверете се, че добавяте тези функции към функцията window.onload под `updateGameObjects()`:
1. **Добавете методи към игровия цикъл**. Уверете се, че добавяте тези функции към функцията `window.onload` под `updateGameObjects()`:
```javascript
drawPoints();
@ -150,7 +150,7 @@ npm start
}
```
2. **За всеки лазер, който удари враг**, увеличавайте резултата от играта със 100 точки.
2. **За всеки лазер, който удари враг**, увеличавайте резултата с 100 точки.
Разширете класа `Hero`, за да направите това увеличение:
@ -160,7 +160,7 @@ npm start
}
```
Добавете тези функции към вашите Collision Event Emitters:
Добавете тези функции към вашите емитери на събития за сблъсък:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -177,7 +177,7 @@ npm start
✅ Направете малко проучване, за да откриете други игри, създадени с JavaScript/Canvas. Какви са техните общи черти?
След като завършите тази работа, трябва да виждате малките "живот" кораби в долния десен ъгъл, точките в долния ляв ъгъл и да виждате как броят на животите намалява при сблъсък с врагове, а точките се увеличават, когато стреляте по врагове. Браво! Вашата игра е почти завършена.
След като завършите тази работа, трябва да виждате малките "живот" кораби в долния десен ъгъл, точките в долния ляв ъгъл и да наблюдавате как броят на животите намалява при сблъсък с врагове, а точките се увеличават, когато стреляте по врагове. Браво! Вашата игра е почти завършена.
---
@ -191,13 +191,13 @@ npm start
## Преглед и самостоятелно обучение
Проучете начини за увеличаване и намаляване на резултатите и животите в игрите. Съществуват интересни игрови енджини като [PlayFab](https://playfab.com). Как използването на такъв енджин би подобрило вашата игра?
Проучете начини за увеличаване и намаляване на резултати и животи в игрите. Съществуват интересни игрови енджини като [PlayFab](https://playfab.com). Как използването на такъв енджин би подобрило вашата игра?
## Задача
## Задание
[Създайте игра с точки](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Има различни начини да сеизрази *условие за край* в една игра. Вие, като създател на играта, решавате защо играта приключва. Ето някои причини, ако приемем, че говорим за космическата игра, която създавате досега:
Има различни начини да изразите*условие за край* в играта. Вие, като създател на играта, решавате защо играта приключва. Ето някои причини, ако приемем, че говорим за космическата игра, която създавате досега:
- **Унищожени са`N` вражески кораба**: Често, когато играта е разделена на различни нива, трябва да унищожите `N` вражески кораба, за да завършите нивото.
- **Унищожени са`N` вражески кораби**: Това е доста често срещано, ако разделите играта на различни нива, където трябва да унищожите `N` вражески кораби, за да завършите нивото.
- **Вашият кораб е унищожен**: Има игри, в които губите, ако вашият кораб бъде унищожен. Друг често срещан подход е концепцията за животи. Всеки път, когато вашият кораб бъде унищожен, се отнема един живот. Когато всички животи бъдат загубени, играта приключва.
- **Събрали сте`N` точки**: Друго често срещано условие за край е събирането на точки. Как ще получите точки зависи от вас, но еобичайно да се присвояват точки за различни дейности, като унищожаване на вражески кораб или събиране на предмети, които се*пускат*, когато бъдат унищожени.
- **Завършване на ниво**: Това може да включва няколко условия, като унищожени `X` вражески кораба, събрани `Y` точки или може би събиране на конкретен предмет.
- **Събрани са`N` точки**: Друго често срещано условие за край е събирането на точки. Как ще получите точки зависи от вас, но едоста често срещано да се присъждат точки за различни дейности, като унищожаване на вражески кораб или събиране на предмети, които се*пускат*, когато бъдат унищожени.
- **Завършване на ниво**: Това може да включва няколко условия, като унищожени `X` вражески кораби, събрани `Y` точки или може би събиране на конкретен предмет.
## Рестартиране
@ -31,7 +31,7 @@ CO_OP_TRANSLATOR_METADATA:
Ще добавите следните правила към вашата игра:
1. **Победа в играта**. След като всички вражески кораби бъдат унищожени, печелите играта. Освен това покажете някакво съобщение за победа.
1. **Рестарт**. След като всички животи бъдат загубени или играта бъде спечелена, трябва да предложите начин за рестартиране на играта. Не забравяйте! Ще трябва да инициализирате играта отново и да изчистите предишното състояние на играта.
1. **Рестарт**. След като всички животи бъдат загубени или играта бъде спечелена, трябва да предложите начин за рестартиране на играта. Запомнете! Ще трябва да инициализирате играта отново и да изчистите предишното състояние на играта.
## Препоръчителни стъпки
@ -74,7 +74,7 @@ npm start
}
```
1. **Добавяне на логика към обработващите съобщения**. Редактирайте `eventEmitter`, за да обработва тези условия:
1. **Добавяне на логика към обработчиците на съобщения**. Редактирайте `eventEmitter`, за да обработва тези условия:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -117,7 +117,7 @@ npm start
2. **Добавяне на код за рестарт**. Добавете код, който рестартира играта при натискане на избран бутон.
1. **Слушане за натискане на клавиш `Enter`**. Редактирайте eventListener на прозореца, за да слуша за това натискане:
1. **Слушане за натискане на клавиш `Enter`**. Редактирайте eventListener на вашия прозорец, за да слуша за това натискане:
```javascript
else if(evt.key === "Enter") {
@ -125,13 +125,13 @@ npm start
}
```
1. **Добавяне на съобщение за рестарт**. Добавете това съобщение към constants:
1. **Добавяне на съобщение за рестарт**. Добавете това съобщение към constants на Messages:
```javascript
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
```
1. **Прилагане на правилата на играта**. Прилагайте следните правила:
1. **Реализиране на правила за игра**. Реализирайте следните правила за игра:
1. **Условие за победа на играча**. Когато всички вражески кораби бъдат унищожени, покажете съобщение за победа.
@ -216,7 +216,7 @@ npm start
## 🚀 Предизвикателство
Добавете звук! Можете ли да добавите звук, за да подобрите играта, например когато има лазерен удар, или когато героят загине или спечели? Разгледайте този [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play), за да научите как да възпроизвеждате звук с JavaScript.
Добавете звук! Можете ли да добавите звук, за да подобрите играта, например когато има лазерен удар, или когато героят умира или печели? Разгледайте този [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play), за да научите как да възпроизвеждате звук с помощта на JavaScript.
## Финален тест
@ -226,11 +226,11 @@ npm start
Вашата задача е да създадете нова примерна игра, така че разгледайте някои интересни игри, за да видите какъв тип игра бихте могли да създадете.
## Задача
## Задание
[Създайте примерна игра](assignment.md)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Ако искате да създадете множество екрани за уеб страница, едно решение би било да създадете отделен HTML файл за всеки екран, който искате да покажете. Въпреки това, това решение има някои неудобства:
- Трябва да презареждате целия HTML при смяна на екрана, което може да е бавно.
- Трябва да презареждате целия HTML при смяна на екрана, което може да бъде бавно.
- Трудно е да се споделят данни между различните екрани.
Друг подход е да имате само един HTML файл и да дефинирате множество [HTML шаблони](https://developer.mozilla.org/docs/Web/HTML/Element/template), използвайки елемента `<template>`. Шаблонът е многократно използваем HTML блок, който не се показва от браузъра и трябва да бъде инстанциран по време на изпълнение с помощта на JavaScript.
### Задача
Ще създадем банково приложение с два екрана: страницата за вход и таблото за управление. Първо, нека добавим в тялото на HTML елемент за запазване на място, който ще използваме за инстанциране на различните екрани на нашето приложение:
Ще създадем банково приложение с два екрана: страницата за вход и таблото за управление. Първо, нека добавим в HTML тялото елемент за запазване на място, който ще използваме за инстанциране на различните екрани на нашето приложение:
```html
<divid="app">Loading...</div>
@ -64,7 +64,7 @@ CO_OP_TRANSLATOR_METADATA:
> Съвет: тъй като съдържанието на този елемент ще бъде заменено, можем да поставим съобщение за зареждане или индикатор, който ще се показва, докато приложението се зарежда.
След това нека добавим HTML шаблон за страницата за вход. Засега ще поставим само заглавие и секция, съдържаща връзка, която ще използваме за навигация.
След това, нека добавим HTML шаблон за страницата за вход. Засега ще поставим само заглавие и секция, съдържаща връзка, която ще използваме за навигация.
```html
<templateid="login">
@ -77,8 +77,8 @@ CO_OP_TRANSLATOR_METADATA:
След това ще добавим друг HTML шаблон за страницата на таблото за управление. Тази страница ще съдържа различни секции:
- Заглавна част със заглавие и връзка за изход
- Текущото салдо на банковата сметка
- Заглавие с текст и връзка за изход
- Текущият баланс на банковата сметка
- Списък с транзакции, показан в таблица
```html
@ -106,13 +106,13 @@ CO_OP_TRANSLATOR_METADATA:
</template>
```
> Съвет: когато създавате HTML шаблони, ако искате да видите как ще изглеждат, можете да коментирате линиите `<template>` и `</template>`, като ги обградите с`<!-- -->`.
> Съвет: когато създавате HTML шаблони, ако искате да видите как ще изглеждат, можете да коментирате линиите `<template>` и `</template>`, като ги оградите с`<!-- -->`.
✅ Защо мислите, че използваме атрибути`id` за шаблоните? Можем ли да използваме нещо друго, като например класове?
✅ Защо мислите, че използваме `id`атрибути за шаблоните? Можем ли да използваме нещо друго, като класове?
## Показване на шаблони с JavaScript
Ако опитате текущия HTML файл в браузър, ще видите, че той остава на екрана с надпис „Зареждане...“. Това е така, защото трябва да добавим JavaScript код, за да инстанцираме и покажем HTML шаблоните.
Ако опитате текущия HTML файл в браузър, ще видите, че той остава на `Loading...`. Това е така, защото трябва да добавим JavaScript код, за да инстанцираме и покажем HTML шаблоните.
Инстанцирането на шаблон обикновено се извършва в 3 стъпки:
@ -120,7 +120,7 @@ CO_OP_TRANSLATOR_METADATA:
2. Клониране на елемента шаблон, използвайки [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
3. Прикачване към DOM под видим елемент, например с [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
✅ Защо трябва да клонираме шаблона, преди да го прикачим към DOM? Какво мислите, че ще се случи, ако пропуснем тази стъпка?
✅ Защо трябва да клонираме шаблона, преди да го прикачим към DOM? Какво мислите, че би се случило, ако пропуснем тази стъпка?
### Задача
@ -142,7 +142,7 @@ function updateRoute(templateId) {
}
```
Това, което правим тук, са точно описаните по-горе 3 стъпки. Инстанцираме шаблона с`id``templateId` и поставяме клонираното му съдържание в нашия елемент за запазване на място. Забележете, че трябва да използваме `cloneNode(true)`, за да копираме цялото поддърво на шаблона.
Това, което правим тук, са точно 3-те стъпки, описани по-горе. Инстанцираме шаблона с`id``templateId` и поставяме неговото клонирано съдържание в нашия елемент за запазване на място. Забележете, че трябва да използваме `cloneNode(true)`, за да копираме цялото поддърво на шаблона.
Сега извикайте тази функция с един от шаблоните и вижте резултата.
@ -154,7 +154,7 @@ updateRoute('login');
## Създаване на роутове
Когато говорим за уеб приложение, наричаме *роутинг* намерението да се свържат **URL адреси** със специфични екрани, които трябва да бъдат показани. На уебсайт с множество HTML файлове това се прави автоматично, тъй като пътищата на файловете се отразяват в URL адреса. Например, с тези файлове във вашата проектна папка:
Когато говорим за уеб приложение, наричаме *Роутинг* намерението да се свържат **URL адреси** със специфични екрани, които трябва да бъдат показани. На уебсайт с множество HTML файлове това се прави автоматично, тъй като пътищата на файловете се отразяват в URL адреса. Например, с тези файлове в папката на вашия проект:
Въпреки това, за нашето уеб приложение използваме един HTML файл, съдържащ всички екрани, така че това поведение по подразбиране няма да ни помогне. Трябва да създадем тази карта ръчно и да актуализираме показания шаблон с помощта на JavaScript.
Въпреки това, за нашето уеб приложение използваме един HTML файл, съдържащ всички екрани, така че това стандартно поведение няма да ни помогне. Трябва да създадем тази карта ръчно и да обновим показания шаблон с помощта на JavaScript.
### Задача
Ще използваме прост обект, за да имплементираме [карта](https://en.wikipedia.org/wiki/Associative_array) между пътищата на URL адресите и нашите шаблони. Добавете този обект в началото на вашия `app.js` файл.
Ще използваме прост обект, за да реализираме [карта](https://en.wikipedia.org/wiki/Associative_array) между URL пътища и нашите шаблони. Добавете този обект в началото на вашия `app.js` файл.
```js
const routes = {
@ -183,7 +183,7 @@ const routes = {
};
```
Сега нека модифицираме малко функцията `updateRoute`. Вместо директно да подаваме `templateId` като аргумент, искаме първо да извлечем текущия URL адрес и след това да използваме нашата карта, за да получим съответстващата стойност на `templateId`. Можем да използваме [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname), за да получим само частта от пътя на URL адреса.
Сега нека модифицираме малко функцията `updateRoute`. Вместо директно да подаваме `templateId` като аргумент, искаме да го извлечем, като първо погледнем текущия URL адрес, а след това използваме нашата карта, за да получим съответната стойност на `templateId`. Можем да използваме [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname), за да получим само секцията с пътя от URL адреса.
```js
function updateRoute() {
@ -198,7 +198,7 @@ function updateRoute() {
}
```
Тук картографирахме декларираните от нас роутове към съответстващия шаблон. Можете да проверите дали работи правилно, като промените URL адреса ръчно в браузъра си.
Тук картографирахме декларираните роутове към съответния шаблон. Можете да проверите дали работи правилно, като промените URL адреса ръчно в браузъра.
✅ Какво се случва, ако въведете неизвестен път в URL адреса? Как бихме могли да решим този проблем?
@ -206,14 +206,14 @@ function updateRoute() {
Следващата стъпка за нашето приложение е да добавим възможност за навигация между страниците, без да се налага ръчно да променяме URL адреса. Това включва две неща:
1. Актуализиране на текущия URL адрес
2. Актуализиране на показания шаблон въз основа на новия URL адрес
1. Обновяване на текущия URL адрес
2. Обновяване на показания шаблон въз основа на новия URL адрес
Вече се погрижихме за втората част с функцията `updateRoute`, така че трябва да разберем как да актуализираме текущия URL адрес.
Вече се погрижихме за втората част с функцията `updateRoute`, така че трябва да разберем как да обновим текущия URL адрес.
Ще трябва да използваме JavaScript и по-специално [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), който позволява актуализиране на URL адреса и създаване на нов запис в историята на браузъра, без да се презарежда HTML.
Ще трябва да използваме JavaScript и по-специално [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), който позволява обновяване на URL адреса и създаване на нов запис в историята на браузъра, без да се презарежда HTML.
> Забележка: Докато HTML елементът за връзка [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) може да се използва самостоятелно за създаване на хипервръзки към различни URL адреси, той ще накара браузъра да презареди HTML по подразбиране. Необходимо е да се предотврати това поведение, когато се обработва роутинг с персонализиран JavaScript, като сеизползва функцията `preventDefault()` върху събитието за кликване.
> Забележка: Докато HTML елементът за връзка [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) може да се използва самостоятелно за създаване на хипервръзки към различни URL адреси, той ще накара браузъра да презареди HTML по подразбиране. Необходимо е да се предотврати това поведение при обработка на роутинг с персонализиран JavaScript, използвайки функцията `preventDefault()` върху събитието за клик.
### Задача
@ -226,9 +226,9 @@ function navigate(path) {
}
```
Този метод първо актуализира текущия URL адрес въз основа на дадения път, след което актуализира шаблона. Свойството `window.location.origin` връща корена на URL адреса, което ни позволява да реконструираме пълен URL адрес от даден път.
Този метод първо обновява текущия URL адрес въз основа на дадения път, след това обновява шаблона. Свойството `window.location.origin` връща корена на URL адреса, което ни позволява да реконструираме пълен URL адрес от даден път.
Сега, когато имаме тази функция, можем да се погрижим за проблема, който имаме, ако даден път не съвпада с някой от дефинираните роутове. Ще модифицираме функцията `updateRoute`, като добавим резервен вариант към един от съществуващите роутове, ако не можем да намерим съвпадение.
Сега, когато имаме тази функция, можем да се погрижим за проблема, който имаме, ако пътят не съответства на някой от дефинираните роутове. Ще модифицираме функцията `updateRoute`, като добавим резервен вариант към един от съществуващите роутове, ако не можем да намерим съвпадение.
```js
function updateRoute() {
@ -242,9 +242,9 @@ function updateRoute() {
...
```
Ако не може да се намери роут, сега ще пренасочваме към страницата за вход.
Ако роут не може да бъде намерен, сега ще пренасочим към страницата за вход.
Сега нека създадем функция, която да получава URL адреса, когато се кликне върху връзка, и да предотвратява стандартното поведение на браузъра за връзки:
Сега нека създадем функция за получаване на URL адреса, когато се кликне върху връзка, и за предотвратяване на стандартното поведение на браузъра за връзки:
```js
function onLinkClick(event) {
@ -253,7 +253,7 @@ function onLinkClick(event) {
}
```
Нека завършим системата за навигация, като добавим връзки към нашите бутони за *Вход* и *Изход* в HTML.
Нека завършим системата за навигация, като добавим връзки към нашите *Login* и *Logout* линкове в HTML.
@ -267,36 +267,36 @@ function onLinkClick(event) {
Опитайте да кликнете върху тези връзки, сега трябва да можете да навигирате между различните екрани на вашето приложение.
✅ Методът `history.pushState`е част от стандарта HTML5 и е имплементиран във [всички модерни браузъри](https://caniuse.com/?search=pushState). Ако създавате уеб приложение за по-стари браузъри, има трик, който можете да използвате вместо този API: използвайки [хаш (`#`)](https://en.wikipedia.org/wiki/URI_fragment) преди пътя, можете да имплементирате роутинг, който работи с обикновена навигация чрез връзки и не презарежда страницата, тъй като целта му е да създава вътрешни връзки в рамките на страница.
✅ Методът `history.pushState`е част от стандарта HTML5 и е имплементиран във [всички модерни браузъри](https://caniuse.com/?search=pushState). Ако създавате уеб приложение за по-стари браузъри, има трик, който можете да използвате вместо този API: използвайки [хаш (`#`)](https://en.wikipedia.org/wiki/URI_fragment) преди пътя, можете да реализирате роутинг, който работи с обикновена навигация чрез връзки и не презарежда страницата, тъй като целта му е да създава вътрешни връзки в рамките на страница.
## Обработка на бутоните за връщане и напред на браузъра
## Обработка на бутоните за назад и напред в браузъра
Използването на `history.pushState` създава нови записи в историята на навигацията на браузъра. Можете да проверите това, като задържите *бутона за връщане* на браузъра, трябва да се покаже нещо подобно:
Използването на `history.pushState` създава нови записи в историята на навигацията на браузъра. Можете да проверите това, като задържите *бутона за назад* на браузъра си, той трябва да показва нещо подобно:

Ако опитате да кликнете върху бутона за връщане няколко пъти, ще видите, че текущият URL адрес се променя и историята сеактуализира, но същият шаблон продължава да се показва.
Ако опитате да кликнете върху бутона за назад няколко пъти, ще видите, че текущият URL адрес се променя и историята сеобновява, но същият шаблон продължава да се показва.
Това е така, защото приложението не знае, че трябва да извика `updateRoute()` всеки път, когато историята се промени. Ако погледнете документацията за [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), ще видите, че ако състоянието се промени - което означава, че сме преминали към различен URL адрес - се задейства събитието [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event). Ще използваме това, за да решим този проблем.
Това е така, защото приложението не знае, че трябва да извика `updateRoute()` всеки път, когато историята се промени. Ако погледнете документацията за [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), можете да видите, че ако състоянието се промени - което означава, че сме преминали към различен URL адрес - събитието [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event)се задейства. Ще използваме това, за да поправим този проблем.
### Задача
За да се уверим, че показаният шаблон сеактуализира, когато историята на браузъра се промени, ще прикачим нова функция, която извиква `updateRoute()`. Ще направим това в края на нашия файл `app.js`:
За да се уверим, че показаният шаблон сеобновява, когато историята на браузъра се промени, ще прикачим нова функция, която извиква `updateRoute()`. Ще направим това в края на нашия `app.js` файл:
```js
window.onpopstate = () => updateRoute();
updateRoute();
```
> Забележка: използвахме [arrow функция](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) тук, за да декларираме нашия обработчик на събития`popstate` за краткост, но обикновена функция би работила по същия начин.
> Забележка: използвахме [стрелкова функция](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), за да декларираме нашия обработчик на събитие`popstate` за краткост, но обикновена функция би работила по същия начин.
Ето видео за освежаване на знанията за arrow функции:
Ето видео за освежаване на знанията за стрелкови функции:
[Тест след урока](https://ff-quizzes.netlify.app/web/quiz/42)
## Преглед и Самостоятелно Обучение
Роутингът е една от изненадващо сложните части на уеб разработката, особено когато уебът преминава от поведениес презареждане на страници към поведение на Single Page Application. Прочетете малко за [как услугата Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) обработва роутинг. Можете ли да обясните защо някои от решенията, описани в този документ, са необходими?
Роутингът е една от изненадващо сложните части на уеб разработката, особено когато уебът преминава от поведения с презареждане на страници към приложения с еднократна страница. Прочетете малко за [как услугата Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) обработва роутинг. Можете ли да обясните защо някои от решенията, описани в този документ, са необходими?
## Задание
@ -319,4 +319,4 @@ updateRoute();
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
В почти всички съвременни уеб приложения можете да създадете акаунт, за да имате свое собствено лично пространство. Тъй като множество потребители могат да имат достъп до уеб приложението едновременно, е необходим механизъм за съхранение на личните данни на всеки потребител отделно и за избор на информацията, която да се показва. Няма да разглеждаме как да управляваме [потребителската идентичност сигурно](https://en.wikipedia.org/wiki/Authentication), тъй като това е обширна тема сама по себе си, но ще се уверим, че всеки потребител може да създаде един (или повече) банкови акаунти в нашето приложение.
В тази част ще използваме HTML формуляри, за да добавим вход и регистрация към нашето уеб приложение. Ще видим как да изпращаме данни към сървърна API програмно и в крайна сметка как да дефинираме основни правила за валидиране на потребителски вход.
В тази част ще използваме HTML формуляри, за да добавим вход и регистрация към нашето уеб приложение. Ще видим как да изпращаме данни към сървърна API програмно и в крайна сметка как да дефинираме основни правила за валидиране на потребителски входове.
### Предварителни изисквания
### Предварителни условия
Трябва да сте завършили [HTML шаблони и маршрутизация](../1-template-route/README.md) на уеб приложението за този урок. Също така трябва да инсталирате [Node.js](https://nodejs.org) и [да стартирате сървърната API](../api/README.md) локално, за да можете да изпращате данни за създаване на акаунти.
**Обърнете внимание**
**Важно**
Ще имате два терминала, работещи едновременно, както е описано по-долу:
1. За основното банково приложение, което създадохме в урока [HTML шаблони и маршрутизация](../1-template-route/README.md)
2. За [сървърната API на Банковото Приложение](../api/README.md), която току-що настроихме.
@ -41,9 +41,9 @@ curl http://localhost:5000/api
## Формуляр и контроли
Елементът `<form>` обхваща секция от HTML документ, където потребителят може да въвежда и изпраща данни чрез интерактивни контроли. Съществуват всякакви потребителски интерфейсни (UI) контроли, които могат да се използват в рамките на формуляр, като най-често срещаните са елементите `<input>` и `<button>`.
Елементът `<form>` обхваща секция от HTML документ, където потребителят може да въвежда и изпраща данни чрез интерактивни контроли. Съществуват различни потребителски интерфейсни (UI) контроли, които могат да се използват в рамките на формуляр, като най-често срещаните са елементите `<input>` и `<button>`.
Има много различни [типове](https://developer.mozilla.org/docs/Web/HTML/Element/input) `<input>`, например за създаване на поле, където потребителят може да въведе своето потребителско име, можете да използвате:
Има много различни [типове](https://developer.mozilla.org/docs/Web/HTML/Element/input) на `<input>`. Например, за да създадете поле, където потребителят може да въведе своето потребителско име, можете да използвате:
```html
<inputid="username"name="username"type="text">
@ -51,19 +51,19 @@ curl http://localhost:5000/api
Атрибутът `name` ще се използва като име на свойството, когато данните от формуляра бъдат изпратени. Атрибутът `id`се използва за асоцииране на `<label>`с контролата на формуляра.
> Разгледайте целия списък с [`<input>` типове](https://developer.mozilla.org/docs/Web/HTML/Element/input) и [други контроли на формуляри](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls), за да получите представа за всички вградени UI елементи, които можете да използвате при изграждането на вашия интерфейс.
> Разгледайте целия списък с [`<input>` типове](https://developer.mozilla.org/docs/Web/HTML/Element/input) и [други контроли на формуляри](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls), за да получите представа за всички налични UI елементи, които можете да използвате при изграждането на вашия интерфейс.
✅ Забележете, че `<input>`е [празен елемент](https://developer.mozilla.org/docs/Glossary/Empty_element), на който не трябва да добавяте съответстващ затварящ таг. Можете обаче да използвате самозатварящата се нотация `<input/>`, но това не е задължително.
✅ Забележете, че `<input>`е [празен елемент](https://developer.mozilla.org/docs/Glossary/Empty_element), на който *не трябва* да добавяте съответстващ затварящ таг. Можете обаче да използвате самозатварящата се нотация `<input/>`, но това не е задължително.
Елементът `<button>` в рамките на формуляр е малко специален. Ако не зададете неговия атрибут `type`, той автоматично ще изпрати данните от формуляра към сървъра, когато бъде натиснат. Ето възможните стойности на `type`:
- `submit`: По подразбиране в рамките на `<form>`, бутонът задейства действието за изпращане на формуляра.
- `reset`: Бутонът нулира всички контроли на формуляра до техните начални стойности.
- `button`: Не задава никакво поведение по подразбиране, когато бутонът бъде натиснат. Можете да му зададете персонализирани действия с помощта на JavaScript.
- `button`: Не задава никакво поведение по подразбиране при натискане на бутона. Можете да му зададете персонализирани действия с помощта на JavaScript.
### Задача
Нека започнем с добавяне на формуляр към шаблона `login`. Ще ни трябва поле за *потребителско име* и бутон *Вход*.
Нека започнем с добавянето на формуляр към шаблона `login`. Ще ни трябва поле за *потребителско име* и бутон *Login*.
```html
<templateid="login">
@ -81,8 +81,8 @@ curl http://localhost:5000/api
Ако погледнете по-отблизо, можете да забележите, че тук сме добавили и елемент `<label>`. Елементите `<label>`се използват за добавяне на име към UI контроли, като нашето поле за потребителско име. Етикетите са важни за четимостта на вашите формуляри, но също така идват с допълнителни предимства:
- Чрез асоцииране на етикет с контрола на формуляра, това помага на потребителите, използващи асистивни технологии (като екранен четец), да разберат какви данни се очаква да предоставят.
- Можете да кликнете върху етикета, за да поставите директно фокуса върху свързаното поле, което улеснява достъпа на устройства с тъчскрийн.
- Асоциирането на етикет с контрола на формуляра помага на потребителите, използващи асистивни технологии (като екранен четец), да разберат какви данни се очаква да предоставят.
- Можете да кликнете върху етикета, за да поставите директно фокус върху свързаното поле, което улеснява достъпа на устройства с тъчскрийн.
> [Достъпността](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) в уеб пространството е много важна тема, която често се пренебрегва. Благодарение на [семантичните HTML елементи](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) не е трудно да създадете достъпно съдържание, ако ги използвате правилно. Можете [да прочетете повече за достъпността](https://developer.mozilla.org/docs/Web/Accessibility), за да избегнете често срещани грешки и да станете отговорен разработчик.
С помощта на атрибута `value` можем да дефинираме стойност по подразбиране за дадено поле.
Забележете също, че полето за `balance` има тип `number`. Изглежда ли различно от другите полета? Опитайте да взаимодействате с него.
✅ Можете ли да навигирате и взаимодействате с формулярите самос клавиатура? Как бихте направили това?
✅ Можете ли да навигирате и взаимодействате с формулярите, използвайки само клавиатура? Как бихте направили това?
## Изпращане на данни към сървъра
Сега, когато имаме функционален интерфейс, следващата стъпка е да изпратим данните към сървъра. Нека направим бърз тест с текущия код: какво се случва, ако кликнете върху бутона *Вход* или *Регистрация*?
Сега, когато имаме функционален интерфейс, следващата стъпка е да изпратим данните към нашия сървър. Нека направим бърз тест с текущия код: какво се случва, ако кликнете върху бутона *Login* или *Register*?
Забелязахте ли промяната в секцията на URL адреса на браузъра?
Забелязахте ли промяната в секцията с URL на вашия браузър?


По подразбиране действието на `<form>`е да изпрати формуляра към текущия URL адрес на сървъра, използвайки [GET метода](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), като добавя данните от формуляра директно към URL адреса. Този метод обаче има някои недостатъци:
По подразбиране действието на `<form>`е да изпрати формуляра към текущия URL на сървъра, използвайки [GET метода](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), като добави данните от формуляра директно към URL. Този метод обаче има някои недостатъци:
- Изпратените данни са много ограничени по размер (около 2000 символа)
- Данните са директно видими в URL адреса (не е подходящо за пароли)
- Данните са директно видими в URL (не е подходящо за пароли)
- Не работи с качване на файлове
Затова можете да го промените, за да използва [POST метода](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), който изпраща данните от формуляра към сървъра в тялото на HTTP заявката, без предишните ограничения.
> Въпреки че POST е най-често използваният метод за изпращане на данни, [в някои специфични сценарии](https://www.w3.org/2001/tag/doc/whenToUseGet.html) е за предпочитане да се използва GET методът, например при имплементиране на поле за търсене.
> Въпреки че POST е най-често използваният метод за изпращане на данни, [в някои специфични сценарии](https://www.w3.org/2001/tag/doc/whenToUseGet.html) е за предпочитане да се използва GET метод, например при имплементиране на поле за търсене.
Сега опитайте да регистрирате нов акаунт с вашето име. След като кликнете върху бутона *Регистрация*, трябва да видите нещо подобно:
Сега опитайте да регистрирате нов акаунт с вашето име. След като кликнете върху бутона *Register*, трябва да видите нещо подобно:

## Изпращане на данни без презареждане на страницата
Както вероятно забелязахте, има малък проблем с подхода, който току-що използвахме: при изпращане на формуляра излизаме от нашето приложение и браузърът се пренасочва към URL адреса на сървъра. Опитваме се да избегнем всички презареждания на страницата с нашето уеб приложение, тъй като създаваме [Едностранично приложение (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
Както вероятно забелязахте, има малък проблем с подхода, който току-що използвахме: при изпращане на формуляра излизаме от нашето приложение и браузърът се пренасочва към URL на сървъра. Опитваме се да избегнем всички презареждания на страницата с нашето уеб приложение, тъй като създаваме [Едностранично приложение (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
За да изпратим данните от формуляра към сървъра без да принуждаваме презареждане на страницата, трябва да използваме JavaScript код. Вместо да поставяме URL адрес в свойството `action` на елемента `<form>`, можете да използвате произволен JavaScript код, предшестван от низа `javascript:`, за да изпълните персонализирано действие. Използването на това означава също, че ще трябва да имплементирате някои задачи, които преди това се извършваха автоматично от браузъра:
За да изпратим данните от формуляра към сървъра, без да принуждаваме презареждане на страницата, трябва да използваме JavaScript код. Вместо да поставяме URL в свойството `action` на елемента `<form>`, можете да използвате произволен JavaScript код, предшестван от низа `javascript:`, за да изпълните персонализирано действие. Използването на това означава също, че ще трябва да имплементирате някои задачи, които преди това се извършваха автоматично от браузъра:
- Извличане на данните от формуляра
- Конвертиране и кодиране на данните от формуляра в подходящ формат
- Конвертиране и кодиране на данните в подходящ формат
- Създаване на HTTP заявка и изпращането й към сървъра
### Задача
@ -199,12 +199,12 @@ async function createAccount(account) {
> 🎥 Кликнете върху изображението по-горе за видео за async/await.
Използваме API-то`fetch()`, за да изпратим JSON данни към сървъра. Този метод приема 2 параметъра:
Използваме API `fetch()`, за да изпратим JSON данни към сървъра. Този метод приема 2 параметъра:
- URL адреса на сървъра, затова тук поставяме `//localhost:5000/api/accounts`.
- URL на сървъра, така че тук поставяме `//localhost:5000/api/accounts`.
- Настройките на заявката. Тук задаваме метода на `POST` и предоставяме `body` за заявката. Тъй като изпращаме JSON данни към сървъра, трябва също да зададем заглавката `Content-Type` на `application/json`, за да може сървърът да интерпретира съдържанието.
Тъй като сървърът ще отговори на заявката с JSON, можем да използваме `await response.json()`, за да анализираме JSON съдържанието и да върнем получения обект. Забележете, че този метод е асинхронен, затова използваме ключовата дума `await` тук, преди да върнем, за да се уверим, че всички грешки по време на анализа също са уловени.
Тъй като сървърът ще отговори на заявката с JSON, можем да използваме `await response.json()`, за да анализираме JSON съдържанието и да върнем получения обект. Забележете, че този метод е асинхронен, така че използваме ключовата дума `await` тук, преди да върнем резултата, за да се уверим, че всички грешки по време на анализа също са уловени.
Сега добавете малко код към функцията `register`, за да извикате `createAccount()`:
@ -245,17 +245,17 @@ async function register() {
Ако опитате да регистрирате нов акаунт, без да зададете потребителско име, можете да видите, че сървърът връща грешка със статус код [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
Преди да изпращате данни към сървъра, е добра практика [да валидирате данните от формуляра](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) предварително, когато е възможно, за да се уверите, че изпращате валидна заявка. HTML5 контролите на формуляра предоставят вградена валидиране, използвайки различни атрибути:
Преди да изпращате данни към сървъра, е добра практика [да валидирате данните от формуляра](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) предварително, когато е възможно, за да се уверите, че изпращате валидна заявка. HTML5 контролите на формуляра предоставят вградена валидиране чрез различни атрибути:
- `required`: полето трябва да бъде попълнено, иначе формулярът не може да бъде изпратен.
- `minlength` и `maxlength`: дефинират минималния и максималния брой символи в текстови полета.
- `min` и `max`: дефинират минималната и максималната стойност на числово поле.
- `type`: дефинира вида на очакваните данни, като `number`, `email`, `file` или [други вградени типове](https://developer.mozilla.org/docs/Web/HTML/Element/input). Този атрибут може също да промени визуалното представяне на контролата на формуляра.
- `pattern`: позволява дефиниране на [регулярен израз](https
> Съвет: можете да персонализирате външния вид на вашите контролни елементи във формуляра в зависимост от това дали са валидни или не, като използвате CSS псевдокласовете `:valid` и `:invalid`.
- `pattern`: позволява дефиниране на [регулярен израз](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions), за да се провери дали въведените данни са валидни или
> Съвет: можете да персонализирате външния вид на вашите контроли на формуляра в зависимост от това дали са валидни или не, като използвате CSS псевдокласовете `:valid` и `:invalid`.
### Задача
Има два задължителни полета за създаване на валиден нов акаунт: потребителско име и валута. Останалите полета са по избор. Актуализирайте HTML формуляра, като използвате както атрибута `required`, така и текст в етикета на полето, за да:
Има 2 задължителни полета за създаване на валиден нов акаунт: потребителско име и валута, като останалите полета са по избор. Актуализирайте HTML формуляра, като използвате както атрибута `required`, така и текст в етикета на полето, за да:
Въпреки че тази конкретна сървърна имплементация не налага специфични ограничения за максималната дължина на полетата, винаги е добра практика да се задават разумни ограничения за всяко текстово поле, което потребителят попълва.
Въпреки че тази конкретна сървърна имплементация не налага специфични ограничения за максималната дължина на полетата, винаги е добра практика да се задават разумни ограничения за всяко текстово поле за въвеждане от потребителя.
Добавете атрибут `maxlength` към текстовите полета:
Сега, ако натиснете бутона *Регистрация* и някое поле не отговаря на зададените правила за валидация, ще видите нещо подобно:
Сега, ако натиснете бутона *Регистрация* и някое поле не отговаря на зададените правила за валидация, трябва да видите нещо подобно:

Валидацията, която се извършва *преди* изпращането на данни към сървъра, се нарича **клиентска валидация**. Но имайте предвид, че не винаги е възможно да се извършат всички проверки без изпращане на данни. Например, тук не можем да проверим дали вече съществува акаунт със същото потребителско име, без да изпратим заявка към сървъра. Допълнителната валидация, която сеизвършва на сървъра, се нарича **сървърна валидация**.
Валидацията, която се извършва *преди* изпращането на данни към сървъра, се нарича **валидация на клиентската страна**. Но имайте предвид, че не винаги е възможно да се извършат всички проверки без изпращане на данни. Например, не можем да проверим тук дали вече съществува акаунт със същото потребителско име, без да изпратим заявка към сървъра. Допълнителната валидация, извършвана на сървъра, се нарича **валидация на сървърната страна**.
Обикновено и двете трябва да бъдат имплементирани. Клиентската валидация подобрява потребителското изживяване, като предоставя незабавна обратна връзка, но сървърната валидацияе от съществено значение, за да се гарантира, че данните, които обработвате, са коректни и безопасни.
Обикновено и двете трябва да бъдат имплементирани, като валидацията на клиентската страна подобрява потребителското изживяване, предоставяйки незабавна обратна връзка на потребителя, докато валидацията на сървърната странае от съществено значение, за да се гарантира, че данните, които обработвате, са коректни и безопасни.
---
@ -301,7 +301,7 @@ async function register() {
## Преглед и самостоятелно обучение
Разработчиците са станали много креативни в усилията си за създаване на формуляри, особено по отношение на стратегиите за валидация. Научете повече за различни подходи към формулярите, като разгледате [CodePen](https://codepen.com); можете ли да намерите интересни и вдъхновяващи примери?
Разработчиците са станали много креативни в усилията си за създаване на формуляри, особено по отношение на стратегиите за валидация. Научете повече за различни подходи към формуляри, като разгледате [CodePen](https://codepen.com); можете ли да намерите интересни и вдъхновяващи формуляри?
## Задание
@ -310,4 +310,4 @@ async function register() {
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
В основата на всяко уеб приложение стои *данните*. Данните могат да приемат различни форми, но основната им цел винаги е да предоставят информация на потребителя. С развитието на уеб приложенията, които стават все по-интерактивни и сложни, начинът, по който потребителят достъпва и взаимодейства с информацията, е ключова част от уеб разработката.
В основата на всяко уеб приложение стои *данните*. Данните могат да приемат различни форми, но основната им цел винаги е да предоставят информация на потребителя. С развитието на уеб приложенията, които стават все по-интерактивни и сложни, начинът, по който потребителят достъпва и взаимодейства с информацията, се превръща в ключова част от уеб разработката.
В този урок ще разгледаме как да извличаме данни от сървър асинхронно и как да използваме тези данни, за да показваме информация на уеб страница без презареждане на HTML.
В този урок ще разгледаме как да извличаме данни от сървър асинхронно и да ги използваме за показване на информация на уеб страница, без да презареждаме HTML.
### Предварителни изисквания
### Предпоставки
Трябва да сте създали [Формата за Вход и Регистрация](../2-forms/README.md) като част от уеб приложението за този урок. Също така трябва да инсталирате [Node.js](https://nodejs.org) и [да стартирате сървърния API](../api/README.md) локално, за да получите данни за акаунта.
Трябва да сте създали [Формата за вход и регистрация](../2-forms/README.md) като част от уеб приложението за този урок. Също така трябва да инсталирате [Node.js](https://nodejs.org) и [да стартирате API сървъра](../api/README.md) локално, за да получите данни за акаунта.
Можете да тествате дали сървърът работи правилно, като изпълните следната команда в терминала:
Можете да тествате дали сървърът работи правилно, като изпълните тази команда в терминала:
```sh
curl http://localhost:5000/api
@ -34,21 +34,21 @@ curl http://localhost:5000/api
## AJAX и извличане на данни
Традиционните уеб сайтове обновяват съдържанието, когато потребителят избере линк или изпрати данни чрез форма, като презареждат цялата HTML страница. Всеки път, когато трябва да се заредят нови данни, уеб сървърът връща изцяло нова HTML страница, която трябва да бъде обработена от браузъра, прекъсвайки текущото действие на потребителя и ограничавайки взаимодействията по време на презареждането. Този работен процес е известен като *Многостранично Приложение* или *MPA*.
Традиционните уеб сайтове обновяват съдържанието, когато потребителят избере линк или изпрати данни чрез форма, като презареждат цялата HTML страница. Всеки път, когато трябва да се заредят нови данни, уеб сървърът връща изцяло нова HTML страница, която трябва да бъде обработена от браузъра, прекъсвайки текущото действие на потребителя и ограничавайки взаимодействията по време на презареждането. Този работен процес се нарича *многостранично приложение* или *MPA*.


С развитието на по-сложни и интерактивни уеб приложения се появи нова техника, наречена [AJAX (Асинхронен JavaScript и XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Тази техника позволява на уеб приложенията да изпращат и получават данни от сървър асинхроннос помощта на JavaScript, без да се налага презареждане на HTML страницата, което води до по-бързи актуализации и по-гладки взаимодействия с потребителя. Когато нови данни се получат от сървъра, текущата HTML страница може да бъде обновена с JavaScript чрез [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. С времето този подход еволюира в това, което сега наричаме [*Едностранично Приложение* или *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
С развитието на сложни и интерактивни уеб приложения се появи нова техника, наречена [AJAX (Асинхронен JavaScript и XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Тази техника позволява на уеб приложенията да изпращат и получават данни от сървър асинхронно, използвайки JavaScript, без да се налага презареждане на HTML страницата, което води до по-бързи обновявания и по-гладки взаимодействия с потребителя. Когато нови данни се получат от сървъра, текущата HTML страница може да бъде обновена с JavaScript, използвайки [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. С времето този подход еволюира в това, което сега наричаме [*Едностранично приложение* или *SPA*](https://en.wikipedia.org/wiki/Single-page_application).


Когато AJAX беше въведен за първи път, единственият наличен API за асинхронно извличане на данни беше [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Но съвременните браузъри вече поддържат по-удобния и мощен [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), който използва обещания (promises) и е по-подходящ за работа с JSON данни.
Когато AJAX беше въведен, единственият наличен API за асинхронно извличане на данни беше [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Но съвременните браузъри вече поддържат по-удобния и мощен [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), който използва обещания и е по-подходящ за работа с JSON данни.
> Въпреки че всички съвременни браузъри поддържат `Fetch API`, ако искате вашето уеб приложение да работи на стари браузъри, винаги е добра идея да проверите [таблицата за съвместимост на caniuse.com](https://caniuse.com/fetch).
> Въпреки че всички съвременни браузъри поддържат `Fetch API`, ако искате вашето уеб приложение да работи на стари браузъри, винаги е добра идея първо да проверите [таблицата за съвместимост на caniuse.com](https://caniuse.com/fetch).
### Задача
В [предишния урок](../2-forms/README.md) имплементирахме формата за регистрация, за да създадем акаунт. Сега ще добавим код за вход с вече съществуващ акаунт и извличане на неговите данни. Отворете файла `app.js` и добавете нова функция `login`:
В [предишния урок](../2-forms/README.md) реализирахме формата за регистрация за създаване на акаунт. Сега ще добавим код за вход с вече съществуващ акаунт и извличане на неговите данни. Отворете файла `app.js` и добавете нова функция `login`:
```js
async function login() {
@ -72,11 +72,11 @@ async function getAccount(user) {
}
```
Използваме `fetch` API, за да заявим данните асинхронно от сървъра, но този път не се нуждаем от допълнителни параметри освен URL адреса, тъй като само извличаме данни. По подразбиране `fetch` създава HTTP заявка от тип [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), което е точно това, което ни трябва тук.
Използваме `fetch` API за асинхронно извличане на данни от сървъра, но този път не ни трябват допълнителни параметри освен URL, който да извикаме, тъй като само правим заявка за данни. По подразбиране `fetch` създава [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP заявка, което е точно това, което ни трябва тук.
✅ `encodeURIComponent()`е функция, която кодира специални символи за URL. Какви проблеми бихме могли да имаме, ако не извикаме тази функция и използваме директно стойността на `user` в URL?
✅ `encodeURIComponent()`е функция, която избягва специални символи за URL. Какви проблеми бихме могли да имаме, ако не извикаме тази функция и използваме директно стойността на `user` в URL?
Сеганека актуализираме нашата функция `login`, за да използва `getAccount`:
Сегада обновим нашата функция `login`, за да използва `getAccount`:
```js
async function login() {
@ -93,17 +93,17 @@ async function login() {
}
```
Първо, тъй като `getAccount`е асинхронна функция, трябва да я съчетаем с ключовата дума `await`, за да изчакаме резултата от сървъра. Както при всяка заявка към сървър, трябва да се справим и с грешки. Засега ще добавим само съобщение за грешка в конзолата и ще се върнем към това по-късно.
Първо, тъй като `getAccount`е асинхронна функция, трябва да я съчетаем с ключовата дума `await`, за да изчакаме резултата от сървъра. Както при всяка заявка към сървъра, трябва да се справим и с грешки. Засега ще добавим само съобщение за грешка в логовете и ще се върнем към това по-късно.
След това трябва да съхраним данните някъде, за да можем по-късно да ги използваме за показване на информацията на таблото. Тъй като променливата `account` все още не съществува, ще създадем глобална променлива за нея в началото на нашия файл:
След това трябва да съхраним данните някъде, за да можем по-късно да ги използваме за показване на информацията на таблото. Тъй като променливата `account` все още не съществува, ще създадем глобална променлива за нея в началото на файла:
```js
let account = null;
```
След като данните за потребителя са запазени в променлива, можем да преминем от страницата за *вход* към *таблото*с помощта на функцията `navigate()`, която вече имаме.
След като данните за потребителя са запазени в променлива, можем да преминем от страницата за вход към таблото, използвайки функцията `navigate()`, която вече имаме.
Накрая, трябва да извикаме нашата функция `login`, когато формата за вход е изпратена, като модифицираме HTML:
Накрая, трябва да извикаме нашата функция `login`, когато формата за вход бъде изпратена, като модифицираме HTML:
```html
<formid="loginForm"action="javascript:login()">
@ -118,25 +118,25 @@ account = result;
navigate('/dashboard');
```
✅ Знаете ли, че по подразбиране можете да извиквате сървърни API само от *същия домейн и порт*, от който разглеждате уеб страницата? Това е механизъм за сигурност, наложен от браузърите. Ноизчакайте, нашето уеб приложение работи на `localhost:3000`, докато сървърният API работи на `localhost:5000`. Защо тогава работи? Чрез използване на техника, наречена [Споделяне на Ресурси между Различни Произходи (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), е възможно да се изпълняват HTTP заявки между различни произходи, ако сървърът добави специални заглавия към отговора, позволяващи изключения за конкретни домейни.
✅ Знаете ли, че по подразбиране можете да извиквате API сървъри само от *същия домейн и порт*, от който разглеждате уеб страницата? Това е механизъм за сигурност, наложен от браузърите. Но чакайте, нашето уеб приложение работи на `localhost:3000`, докато API сървърът работи на `localhost:5000`. Защо работи? Чрез използване на техника, наречена [Споделяне на ресурси между различни източници (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), е възможно да се изпълняват HTTP заявки между различни източници, ако сървърът добави специални заглавия към отговора, позволяващи изключения за конкретни домейни.
> Научете повече за API, като преминете този [урок](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)
> Научете повече за API, като вземете този [урок](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)
## Актуализиране на HTML за показване на данни
## Обновяване на HTML за показване на данни
Сега, когато разполагаме с данните за потребителя, трябва да актуализираме съществуващия HTML, за да ги покажем. Вече знаем как да извличаме елемент от DOM, напримерс`document.getElementById()`. След като имате базов елемент, ето някои API, които можете да използвате, за да го модифицирате или добавите дъщерни елементи към него:
Сега, когато имаме данните за потребителя, трябва да обновим съществуващия HTML, за да ги покажем. Вече знаем как да извличаме елемент от DOM, използвайки например `document.getElementById()`. След като имате основен елемент, ето някои API, които можете да използвате, за да го модифицирате или добавите дъщерни елементи към него:
- С помощта на свойството [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) можете да промените текста на елемента. Имайте предвид, че промяната на тази стойност премахва всички дъщерни елементи (ако има такива) и ги заменя с предоставения текст. Това също е ефективен метод за премахване на всички дъщерни елементи на даден елемент, като му зададете празен низ `''`.
- С помощта на свойството [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) можете да промените текста на елемент. Имайте предвид, че промяната на тази стойност премахва всички дъщерни елементи на елемента (ако има такива) и ги заменя с предоставения текст. По този начин това е и ефективен метод за премахване на всички дъщерни елементи на даден елемент, като му зададете празен низ `''`.
- С помощта на [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) заедно с метода [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) можете да създавате и прикачвате един или повече нови дъщерни елементи.
✅ С помощта на свойството [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) на елемент също е възможно да промените неговото HTML съдържание, но това трябва да се избягва, тъй като е уязвимо към [атаки чрез междусайтово скриптиране (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting).
✅ С помощта на свойството [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) на елемент също е възможно да промените неговото HTML съдържание, но това трябва да се избягва, тъй като е уязвимо към [атаки чрез скриптове междусайтове (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting).
### Задача
Преди да преминем към екрана на таблото, има още нещо, което трябва да направим на страницата за *вход*. В момента, ако се опитате да влезете с потребителско име, което не съществува, съобщение се показва в конзолата, но за обикновения потребител нищо не се променя и не е ясно какво се случва.
Преди да преминем към екрана на таблото, има още нещо, което трябва да направим на страницата за вход. В момента, ако се опитате да влезете с потребителско име, което не съществува, съобщение се показва в конзолата, но за обикновения потребител нищо не се променя и не знаете какво се случва.
Нека добавим елемент за запазване на място във формата за вход, където можем да показваме съобщение за грешка, ако е необходимо. Добро място би било точно преди бутона за вход`<button>`:
Нека добавим елемент за запазване на място във формата за вход, където можем да показваме съобщение за грешка, ако е необходимо. Добро място би било точно преди бутона за вход:
```html
...
@ -145,7 +145,7 @@ navigate('/dashboard');
...
```
Този `<div>` елемент е празен, което означава, че нищо няма да се показва на екрана, докато не добавим съдържание към него. Също така му даваме `id`, за да можем лесно да го извличамес JavaScript.
Този `<div>` елемент е празен, което означава, че нищо няма да се показва на екрана, докато не добавим съдържание към него. Също така му даваме `id`, за да можем лесно да го извлечемс JavaScript.
Върнете се към файла `app.js` и създайте нова помощна функция `updateElement`:
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
Тази функция е доста проста: като се дадат *id* на елемент и *текст*, тя ще актуализира текстовото съдържание на DOM елемента с даденото `id`. Нека използваме този метод вместо предишното съобщение за грешка във функцията `login`:
Тази функция е доста проста: като се дадат *id* на елемент и *текст*, тя ще обнови текстовото съдържание на DOM елемента с съответстващото `id`. Нека използваме този метод вместо предишното съобщение за грешка във функцията `login`:
```js
if (data.error) {
@ -166,19 +166,19 @@ if (data.error) {
Сега, ако се опитате да влезете с невалиден акаунт, трябва да видите нещо подобно:


Сега имаме текст за грешка, който се показва визуално, но ако го опитате със скрийн рийдър, ще забележите, че нищо не се обявява. За да може текст, който се добавя динамично към страница, да бъде обявен от скрийн рийдъри, ще трябва да използва нещо, наречено [Жива Област (Live Region)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Тук ще използваме специфичен тип жива област, наречена предупреждение:
Сега имаме текст за грешка, който се показва визуално, но ако го опитате със скрийн рийдър, ще забележите, че нищо не се обявява. За да може текст, който се добавя динамично към страница, да бъде обявен от скрийн рийдъри, той трябва да използва нещо, наречено [Жива област (Live Region)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Тук ще използваме специфичен тип жива област, наречена предупреждение:
```html
<divid="loginError"role="alert"></div>
```
Имплементирайте същото поведение за грешките във функцията `register` (не забравяйте да актуализирате HTML).
Реализирайте същото поведение за грешките във функцията `register` (не забравяйте да обновите HTML).
## Показване на информация на таблото
С помощта на същите техники, които току-що разгледахме, ще се погрижим и за показването на информацията за акаунта на страницата на таблото.
Използвайки същите техники, които току-що разгледахме, ще се погрижим и за показването на информацията за акаунта на страницата на таблото.
Ето как изглежда обектът на акаунта, получен от сървъра:
@ -196,11 +196,11 @@ if (data.error) {
}
```
> Забележка: за да улесните работата си, можете да използвате предварително създадения акаунт `test`, който вече е попълнен с данни.
> Забележка: за да улесните работата си, можете да използвате предварително съществуващия акаунт `test`, който вече е попълнен с данни.
### Задача
Нека започнем, като заменим секцията "Баланс" в HTML, за да добавим елементи за запазване на място:
Нека започнемс подмяна на секцията "Баланс" в HTML, за да добавим елементи за запазване на място:
```html
<section>
@ -208,13 +208,13 @@ if (data.error) {
</section>
```
Също така ще добавим нова секция точно под нея, за да показваме описанието на акаунта:
Също така ще добавим нова секция точно под нея, за да покажем описанието на акаунта:
```html
<h2id="description"></h2>
```
✅ Тъй като описанието на акаунта функционира като заглавие за съдържанието под него, то е маркирано семантично като заглавие. Научете повече за това как [структурата на заглавията](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) е важна за достъпността и направете критичен преглед на страницата, за да определите какво друго би могло да бъде заглавие.
✅ Тъй като описанието на акаунта функционира като заглавие за съдържанието под него, то е маркирано семантично като заглавие. Научете повече за това как [структурата на заглавията](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) е важна за достъпността и направете критичен преглед на страницата, за да определите какво друго може да бъде заглавие.
След това ще създадем нова функция в `app.js`, за да попълним елементите за запазване на място:
@ -230,11 +230,11 @@ function updateDashboard() {
}
```
Първо, проверяваме дали разполагаме с необходимите данни за акаунта, преди да продължим. След това използваме функцията `updateElement()`, която създадохме по-рано, за да актуализираме HTML.
Първо, проверяваме дали имаме необходимите данни за акаунта, преди да продължим. След това използваме функцията `updateElement()`, която създадохме по-рано, за да обновим HTML.
> За да направим показването на баланса по-привлекателно, използваме метода [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed), за да принудим показването на стойността с 2 цифри след десетичната запетая.
> За да направим показването на баланса по-привлекателно, използваме метода [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed), за да принудим показването на стойността с 2 цифри след десетичната точка.
Сега трябва да извикаме нашата функция `updateDashboard()` всеки път, когато таблото се зарежда. Ако вече сте завършили [заданието от урок 1](../1-template-route/assignment.md), това трябва да е лесно, в противен случай можете да използвате следната имплементация.
Сега трябва да извикаме нашата функция `updateDashboard()` всеки път, когато таблото се зарежда. Ако вече сте завършили [задачата от урок 1](../1-template-route/assignment.md), това трябва да е лесно, в противен случай можете да използвате следната реализация.
Добавете този код в края на функцията `updateRoute()`:
@ -244,7 +244,7 @@ if (typeof route.init === 'function') {
}
```
И актуализирайте дефиницията на маршрутите със:
И обновете дефиницията на маршрутите с:
```js
const routes = {
@ -257,9 +257,9 @@ const routes = {
## Създаване на редове в таблица динамично с HTML шаблони
В [първия урок](../1-template-route/README.md) използвахме HTML шаблони заедно с метода [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild), за да имплементираме навигацията в нашето приложение. Шаблоните могат да бъдат и по-малки и да се използват за динамично попълване на повтарящи се части от страница.
В [първия урок](../1-template-route/README.md) използвахме HTML шаблони заедно с метода [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild), за да реализираме навигацията в нашето приложение. Шаблоните могат да бъдат и по-малки и да се използват за динамично попълване на повтарящи се части от страница.
Ще използваме подобен подход, за да покажем списъка с транзакции в HTML таблица.
Ще използваме подобен подход, за да покажем списъка с транзакции в HTML таблицата.
### Задача
@ -297,7 +297,7 @@ function createTransactionRow(transaction) {
}
```
Тази функция прави точно това, което подсказва името ѝ: използвайки шаблона, който създадохме по-рано, тя създава нов ред в таблицата и попълва съдържанието му с данни за транзакцията. Ще използваме това в нашата функция`updateDashboard()`, за да попълним таблицата:
Тази функция прави точно това, което предполага името ѝ: използвайки шаблона, който създадохме по-рано, тя създава нов ред в таблицата и попълва съдържанието му с данни за транзакцията. Ще я използваме във функцията`updateDashboard()`, за да попълним таблицата:
Тук използваме метода [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment), който създава нов DOM фрагмент, върху който можем да работим, преди накрая да го прикачим към нашата HTML таблица.
Остава
Ако опитате да влезете с акаунта `test`, вече трябва да виждате списък с транзакции на таблото 🎉.
Има още едно нещо, което трябва да направим, преди този код да заработи, тъй като нашата функция `updateElement()` в момента поддържа само текстово съдържание. Нека променим нейния код малко:
```js
function updateElement(id, textOrNode) {
const element = document.getElementById(id);
element.textContent = ''; // Removes all children
element.append(textOrNode);
}
```
Използваме
Ако опитате да използвате акаунта `test` за вход, вече трябва да виждате списък с транзакции на таблото 🎉.
---
## 🚀 Предизвикателство
Работете заедно, за да направите страницата на таблото да изглежда като истинско банково приложение. Ако вече сте стилизирали приложението си, опитайте да използвате [медийни заявки](https://developer.mozilla.org/docs/Web/CSS/Media_Queries), за да създадете [отзивчив дизайн](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), който работи добре както на настолни, така и на мобилни устройства.
Работете заедно, за да направите страницата на таблото да изглежда като истинско приложение за банкиране. Ако вече сте стилизирали приложението си, опитайте да използвате [медийни заявки](https://developer.mozilla.org/docs/Web/CSS/Media_Queries), за да създадете [адаптивен дизайн](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), който работи добре както на настолни, така и на мобилни устройства.
Ето пример за стилизирана страница на таблото:


С разрастването на уеб приложението става предизвикателство да се следят всички потоци от данни. Кой код получава данните, коя страница ги използва, къде и кога трябва да бъдат актуализирани... лесно е да се стигне до объркан код, който е труден за поддръжка. Това е особено вярно, когато трябва да споделяте данни между различни страници на приложението, например данни за потребителя. Концепцията за *управление на състоянието* винаги е съществувала във всички видове програми, но с увеличаването на сложността на уеб приложенията тя вече е ключова точка, която трябва да се обмисли по време на разработката.
С разрастването на уеб приложението става предизвикателство да се следят всички потоци от данни. Кой код получава данните, коя страница ги използва, къде и кога трябва да бъдат актуализирани... лесно е да се стигне до объркан код, който е труден за поддръжка. Това е особено вярно, когато трябва да споделяте данни между различни страници на приложението, например данни за потребителя. Концепцията за *управление на състоянието* винаги е съществувала във всякакви програми, но с нарастващата сложност на уеб приложенията тя вече е ключова точка за обмисляне по време на разработката.
В тази последна част ще разгледаме приложението, което създадохме, за да преосмислим как се управлява състоянието, като позволим поддръжка на обновяване на браузъра по всяко време и запазване на данните между потребителските сесии.
В тази последна част ще разгледаме приложението, което създадохме, за да преосмислим как се управлява състоянието, като позволим поддръжка на обновяване на браузъра във всеки момент и запазване на данните между потребителските сесии.
### Предпоставки
Трябва да сте завършили [частта за извличане на данни](../3-data/README.md) от уеб приложението за този урок. Също така трябва да инсталирате [Node.js](https://nodejs.org) и [да стартирате API сървъра](../api/README.md) локално, за да можете да управлявате данните за акаунта.
Трябва да сте завършили частта за [извличане на данни](../3-data/README.md) от уеб приложението за този урок. Също така трябва да инсталирате [Node.js](https://nodejs.org) и [да стартирате API сървъра](../api/README.md) локално, за да можете да управлявате данните за акаунта.
Можете да тествате дали сървърът работи правилно, като изпълните тази команда в терминала:
@ -55,9 +55,9 @@ curl http://localhost:5000/api

> Тук няма да разглеждаме частта, в която данните автоматично задействат актуализацията на изгледа, тъй като тя е свързана с по-напреднали концепции на [Реактивното програмиране](https://en.wikipedia.org/wiki/Reactive_programming). Това е добра тема за последващо задълбочаване.
> Тук няма да разглеждаме частта, където данните автоматично задействат актуализацията на изгледа, тъй като тя е свързана с по-напреднали концепции на [Реактивното програмиране](https://en.wikipedia.org/wiki/Reactive_programming). Това е добра тема за последващо задълбочено изучаване.
✅ Съществуват много библиотеки с различни подходи към управлението на състоянието, като [Redux](https://redux.js.org) е популярна опция. Разгледайте концепциите и моделите, които се използват, тъй като често товае добър начин да научите какви потенциални проблеми може да срещнете в големи уеб приложения и как те могат да бъдат решени.
✅ Има много библиотеки с различни подходи за управление на състоянието, като [Redux](https://redux.js.org) е популярна опция. Разгледайте концепциите и моделите, които се използват, тъй като често е добър начин да научите какви потенциални проблеми може да срещнете в големи уеб приложения и как те могат да бъдат решени.
### Задача
@ -75,7 +75,7 @@ let state = {
};
```
Идеята е да *централизираме* всички данни на приложението в един обект за състояние. Засега имаме само `account` в състоянието, така че това не променя много, но създава път за бъдещи промени.
Идеята е да *централизираме* всички данни на приложението в един обект за състояние. Засега имаме само `account` в състоянието, така че това не променя много, но създава път за бъдещи подобрения.
Също така трябва да актуализираме функциите, които го използват. Във функциите `register()` и `login()` заменете `account = ...`с`state.account = ...`;
@ -85,13 +85,13 @@ let state = {
const account = state.account;
```
Това рефакториране само по себе си не донесе много подобрения, но идеята беше да се положи основата за следващите промени.
Това рефакториране само по себе си не донесе много подобрения, но идеята беше да се положат основите за следващите промени.
## Проследяване на промените в данните
Сега, когато сме поставили обекта `state` за съхранение на нашите данни, следващата стъпка е да централизиране актуализациите. Целта е да се улесни проследяването на всякакви промени и кога те се случват.
Сега, когато сме поставили обекта `state`, за да съхраняваме данните си, следващата стъпка е да централизиране актуализациите. Целта е да се улесни проследяването на всякакви промени и кога те се случват.
За да избегнем промени в обекта `state`, също е добра практика да го считаме за [*неизменяем*](https://en.wikipedia.org/wiki/Immutable_object), което означава, че той изобщо не може да бъде модифициран. Това означава, че трябва да създадете нов обект за състояние, ако искате да промените нещо в него. По този начин изграждате защита срещу потенциално нежелани [странични ефекти](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) и отваряте възможности за нови функции в приложението си, като например внедряване на undo/redo, като същевременно улеснявате дебъгването. Например, можете да регистрирате всяка промяна, направена в състоянието, и да запазите историята на промените, за да разберете източника на грешка.
За да избегнем промени в обекта `state`, също е добра практика да го считаме за [*неизменяем*](https://en.wikipedia.org/wiki/Immutable_object), което означава, че той изобщо не може да бъде модифициран. Това също означава, че трябва да създадете нов обект за състояние, ако искате да промените нещо в него. Като правите това, изграждате защита срещу потенциално нежелани [странични ефекти](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) и отваряте възможности за нови функции в приложението си, като например внедряване на undo/redo, като същевременно улеснявате дебъгването. Например, можете да регистрирате всяка промяна, направена в състоянието, и да запазите история на промените, за да разберете източника на грешка.
В JavaScript можете да използвате [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze), за да създадете неизменяема версия на обект. Ако се опитате да направите промени в неизменяем обект, ще бъде хвърлено изключение.
@ -112,7 +112,7 @@ function updateState(property, newData) {
В тази функция създаваме нов обект за състояние и копираме данни от предишното състояние, използвайки [*оператора за разпръскване (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). След това презаписваме конкретно свойство на обекта за състояние с новите данни, използвайки [нотацията с квадратни скоби](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` за присвояване. Накрая заключваме обекта, за да предотвратим модификации, използвайки `Object.freeze()`. Засега имаме само свойството `account`, съхранено в състоянието, но с този подход можете да добавите толкова свойства, колкото са ви необходими.
Също така ще актуализираме инициализацията на `state`, за да смесигурни, че началното състояние също е заключено:
Също така ще актуализираме инициализацията на `state`, за да сеуверим, че началното състояние също е заключено:
```js
let state = Object.freeze({
@ -151,27 +151,27 @@ function logout() {
## Запазване на състоянието
Повечето уеб приложения трябва да запазват данни, за да могат да работят правилно. Всички критични данни обикновено се съхраняват в база данни и се достъпват чрез API на сървъра, като например данните за потребителския акаунт в нашия случай. Но понякога е интересно да се запазят някои данни в клиентското приложение, което работи в браузъра, за по-добро потребителско изживяване или за подобряване на производителността при зареждане.
Повечето уеб приложения трябва да запазват данни, за да могат да работят правилно. Всички критични данни обикновено се съхраняват в база данни и се достъпват чрез API сървър, като например данните за потребителския акаунт в нашия случай. Но понякога е интересно да се запазят някои данни в клиентското приложение, което работи в браузъра, за по-добро потребителско изживяване или за подобряване на производителността при зареждане.
Когато искате да запазите данни в браузъра, има няколко важни въпроса, които трябва да си зададете:
- *Данните чувствителни ли са?* Трябва да избягвате съхраняването на чувствителни данни в клиента, като например пароли на потребители.
- *За колко време трябва да запазите тези данни?* Планирате ли да достъпвате тези данни само за текущата сесия или искате те да се съхраняват завинаги?
- *За колко време трябва да запазите тези данни?* Планирате ли да достъпите тези данни само за текущата сесия или искате те да бъдат съхранени завинаги?
Съществуват множество начини за съхранение на информация в уеб приложение, в зависимост от това, което искате да постигнете. Например, можете да използвате URL адресите, за да съхранявате заявка за търсене и да я направите споделима между потребителите. Можете също така да използвате [HTTP бисквитки](https://developer.mozilla.org/docs/Web/HTTP/Cookies), ако данните трябва да се споделят със сървъра, като например информация за [автентикация](https://en.wikipedia.org/wiki/Authentication).
Има множество начини за съхраняване на информация в уеб приложение, в зависимост от това, което искате да постигнете. Например, можете да използвате URL адресите, за да съхранявате заявка за търсене и да я направите споделима между потребителите. Можете също така да използвате [HTTP бисквитки](https://developer.mozilla.org/docs/Web/HTTP/Cookies), ако данните трябва да бъдат споделени със сървъра, като информация за [автентикация](https://en.wikipedia.org/wiki/Authentication).
Друга опция е да използвате един от многото API на браузъра за съхранение на данни. Два от тях са особено интересни:
Друга опция е да използвате една от многото API на браузъра за съхраняване на данни. Две от тях са особено интересни:
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): [Key/Value хранилище](https://en.wikipedia.org/wiki/Key%E2%80%93value_database), което позволява запазване на данни, специфични за текущия уеб сайт, между различни сесии. Данните, запазени в него, никога не изтичат.
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): работи по същия начин като `localStorage`, с изключение на това, че данните, съхранени в него, се изчистват, когато сесията приключи (когато браузърът се затвори).
Имайте предвид, че и двата API позволяват съхранение само на [низове](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Ако искате да съхранявате сложни обекти, ще трябва да ги сериализирате във формат [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON), използвайки [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
Имайте предвид, че и двата API позволяват съхраняване само на [стрингове](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Ако искате да съхранявате сложни обекти, ще трябва да ги сериализирате във формат [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON), използвайки [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
✅ Ако искате да създадете уеб приложение, което не работи със сървър, е възможно да създадете база данни на клиента, използвайки [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Това е запазено за напреднали случаи на употреба или ако трябва да съхранявате значително количество данни, тъй като е по-сложно за използване.
✅ Ако искате да създадете уеб приложение, което не работи със сървър, е възможно да създадете база данни на клиента, използвайки API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Това е запазено за напреднали случаи на употреба или ако трябва да съхранявате значително количество данни, тъй като е по-сложно за използване.
### Задача
Искаме нашите потребители да останат влезли, докато не кликнат изрично върху бутона *Изход*, така че ще използваме `localStorage`, за да съхраняваме данните за акаунта. Първо, нека дефинираме ключ, който ще използваме за съхранение на нашите данни.
Искаме нашите потребители да останат влезли, докато не кликнат изрично върху бутона *Изход*, така че ще използваме `localStorage`, за да съхраняваме данните за акаунта. Първо, нека дефинираме ключ, който ще използваме за съхраняване на нашите данни.
С това данните за потребителския акаунт ще бъдат запазени и винаги актуални, тъй като преди това централизирахме всички актуализации на състоянието. Тук започваме да се възползваме от всички предишни рефакторирания 🙂.
С това данните за потребителския акаунт ще бъдат запазени и винаги актуални, както централизирахме преди всички актуализации на състоянието. Тук започваме да се възползваме от всички предишни рефакторирания 🙂.
Тъй като данните се запазват, трябва също така да се погрижим за тяхното възстановяване, когато приложението се зареди. Тъй като започваме да имаме повече код за инициализация, може би е добра идея да създадем нова функция `init`, която включва и предишния код в края на `app.js`:
Тъй като данните се запазват, трябва също да се погрижим за тяхното възстановяване, когато приложението се зареди. Тъй като ще започнем да имаме повече код за инициализация, може би е добра идея да създадем нова функция `init`, която също включва предишния код в края на `app.js`:
```js
function init() {
@ -204,7 +204,7 @@ init();
Тук извличаме запазените данни и ако има такива, актуализираме състоянието съответно. Важно е да направим това *преди* актуализирането на маршрута, тъй като може да има код, който разчита на състоянието по време на актуализацията на страницата.
Също така можем да направим страницата *Табло* основната страница на нашето приложение, тъй като сега запазваме данните за акаунта. Ако не се намерят данни, таблото се грижи за пренасочването към страницата *Вход* така или иначе. В`updateRoute()` заменете резервния вариант `return navigate('/login');`с`return navigate('/dashboard');`.
Също така можем да направим страницата *Табло* основната страница на нашето приложение, тъй като сега запазваме данните за акаунта. Ако не се намерят данни, таблото се грижи за пренасочването към страницата *Вход* така или иначе. В`updateRoute()` заменете резервния `return navigate('/login');`с`return navigate('/dashboard');`.
Сега влезте в приложението и опитайте да обновите страницата. Трябва да останете на таблото. С тази актуализация сме се погрижили за всички първоначални проблеми...
@ -223,7 +223,7 @@ curl --request POST \
Опитайте да обновите страницата на таблото в браузъра сега. Какво се случва? Виждате ли новата транзакция?
Състоянието се запазва за неопределено време благодарение на `localStorage`, но това също означава, че то никога не се актуализира, докато не излезете от приложението и не влезете отново!
Състоянието се запазва безкрайно благодарение на `localStorage`, но това също означава, че то никога не се актуализира, докато не излезете от приложението и не влезете отново!
Една възможна стратегия за решаване на този проблем е да презареждаме данните за акаунта всеки път, когато таблото се зарежда, за да избегнем остарели данни.
@ -247,7 +247,7 @@ async function updateAccountData() {
}
```
Този метод проверява дали в момента сме влезли, след което презарежда данните за акаунта от сървъра.
Този метод проверява дали в момента сме влезли, след това презарежда данните за акаунта от сървъра.
Създайте друга функция, наречена `refresh`:
@ -258,7 +258,7 @@ async function refresh() {
}
```
Тази функция актуализира данните за акаунта, след което се грижи за актуализирането на HTML на страницата на таблото. Това е, което трябва да извикаме, когато маршрутът на таблото се зареди. Актуализирайте дефиницията на маршрута с:
Тази функция актуализира данните за акаунта, след товасе грижи за актуализирането на HTML на страницата на таблото. Това е, което трябва да извикаме, когато маршрутът на таблото се зареди. Актуализирайте дефиницията на маршрута с:
```js
const routes = {
@ -267,18 +267,14 @@ const routes = {
};
```
Опитайте да презаредите таблото с
[Тест след лекцията](https://ff-quizzes.netlify.app/web/quiz/48)
Опитайте да обновите таблото сега, то трябва да показва актуализираните данни за акаунта
[Реализиране на диалог "Добавяне на транзакция"](assignment.md)
## Задача
Ето примерен резултат след завършване на задачата:
[Реализирайте диалогов прозорец "Добавяне на транзакция"](assignment.md)
Ето примерен резултат след изпълнение на задачата:


---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
- Следите промените спомощта на система за контрол на версиите
- Персонализирате редактора за разработка
### Предпоставки
### Предварителни изисквания
Преди да започнете, ще трябва да създадете акаунт в [GitHub](https://github.com). Отидете на [GitHub](https://github.com/) и създайте акаунт, ако все още нямате такъв.
Преди да започнете, ще трябва да си създадете акаунт в [GitHub](https://github.com). Отидете на [GitHub](https://github.com/) и създайте акаунт, ако все още нямате такъв.
### Въведение
Редакторът за код е основен инструмент за писане на програми и сътрудничество по съществуващи проекти с код. След като разберете основите на редактора и как да използвате неговите функции, ще можете да ги прилагате при писане на код.
## Започванес VSCode.dev
## Първи стъпкис VSCode.dev
[VSCode.dev](https://vscode.dev) е редактор за код в уеб. Нее необходимо да инсталирате нищо, за да го използвате – просто го отворете като всеки друг уебсайт. За да започнете с редактора, отворете следния линк: [https://vscode.dev](https://vscode.dev). Ако не сте влезли в [GitHub](https://github.com/), следвайте указанията, за да влезете или да създадете нов акаунт и след това да влезете.
[VSCode.dev](https://vscode.dev) е редактор за код в уеб пространството. Нее необходимо да инсталирате нищо, за да го използвате – просто го отворете като всеки друг уебсайт. За да започнете с редактора, отворете следния линк: [https://vscode.dev](https://vscode.dev). Ако не сте влезли в [GitHub](https://github.com/), следвайте инструкциите, за да влезете или да създадете нов акаунт и след това влезте.
След като се зареди, трябва да изглежда подобно на този образ:
След като се зареди, интерфейсът трябва да изглежда подобно на това изображение:
Има три основни секции, започвайки от най-ляво и преминавайки надясно:
Има три основни секции, започвайки от най-ляво и движейки се надясно:
1. _Лентата за активност_, която включва някои икони, като лупа 🔎, зъбно колело ⚙️ и няколко други.
2. Разширената лента за активност, която по подразбиране е_Explorer_, наречена_странична лента_.
1. _Лента за активност_, която включва няколко икони, като лупа 🔎, зъбно колело ⚙️ и други.
2. Разширена лента за активност, която по подразбиране показва _Explorer_ и се нарича_странична лента_.
3. И накрая, зоната за код вдясно.
Кликнете върху всяка от иконите, за да покажете различно меню. След като приключите, кликнете върху _Explorer_, за да се върнете там, откъдето сте започнали.
Кликнете върху всяка от иконите, за да видите различно меню. След като приключите, кликнете върху _Explorer_, за да се върнете там, откъдето започнахте.
Когато започнете да създавате код или да модифицирате съществуващ код, това ще се случи в най-голямата зона вдясно. Ще използвате тази зона и за визуализиране на съществуващ код, което ще направите следващо.
Когато започнете да създавате код или да променяте съществуващ код, това ще се случва в най-голямата зона вдясно. Ще използвате тази зона и за визуализиране на съществуващ код, което ще направите след малко.
## Отваряне на GitHub хранилище
Първото нещо, което ще трябва да направите, е да отворите GitHub хранилище. Има няколко начина за отваряне на хранилище. В този раздел ще видите два различни начина, по които можете да отворите хранилище, за да започнете работа по промените.
Първото нещо, което трябва да направите, е да отворите GitHub хранилище. Има няколко начина за отваряне на хранилище. В тази секция ще видите два различни начина, по които можете да отворите хранилище и да започнете работа по промените.
### 1. С редактора
### 1. Чрез редактора
Използвайте самия редактор, за да отворите отдалечено хранилище. Ако отидете на [VSCode.dev](https://vscode.dev), ще видите бутон _"Open Remote Repository"_:
Можете също да използвате палитрата с команди. Палитрата с командие поле за въвеждане, където можете да напишете всяка дума, която е част от команда или действие, за да намерите правилната команда за изпълнение. Използвайте менюто в горния ляв ъгъл, след това изберете _View_, и след това изберете _Command Palette_, или използвайте следния клавишен пряк път: Ctrl-Shift-P (на MacOS това би било Command-Shift-P).
Можете също да използвате командния палет. Командният палете поле за въвеждане, където можете да напишете всяка дума, която е част от команда или действие, за да намерите правилната команда за изпълнение. Използвайте менюто в горния ляв ъгъл, след това изберете _View_, и след това изберете _Command Palette_, или използвайте следната клавишна комбинация: Ctrl-Shift-P (на MacOS това е Command-Shift-P).
След като менюто се отвори, напишете _open remote repository_, и след това изберете първата опция. Ще се покажат множество хранилища, на които сте част или които сте отваряли наскоро. Можете също да използвате пълен GitHub URL, за да изберете едно. Използвайте следния URL и го поставете в полето:
След като менюто се отвори, напишете _open remote repository_ и изберете първата опция. Ще се покажат няколко хранилища, на които сте част или които сте отваряли наскоро. Можете също да използвате пълен GitHub URL, за да изберете едно. Използвайте следния URL и го поставете в полето:
✅ Ако е успешно, ще видите всички файлове за това хранилище, заредени в текстовия редактор.
✅ Ако всичко е успешно, ще видите всички файлове от това хранилище, заредени в текстовия редактор.
### 2. Използване на URL
Можете също да използвате URL директно, за да заредите хранилище. Например, пълният URL за текущото хранилище е [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), но можете да замените домейна на GitHub с`VSCode.dev/github` и да заредите хранилището директно. Полученият URL би бил [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners).
Можете също да използвате директно URL, за да заредите хранилище. Например, пълният URL за текущото хранилище е [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), но можете да замените домейна на GitHub с`VSCode.dev/github` и директно да заредите хранилището. Полученият URL ще бъде [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners).
Можете да създадете файл вътре в съществуваща папка или да го създадете в основната директория/папка. За да създадете нов файл, отворете местоположение/директория, в която искате файлът да бъде запазен, и изберете иконата _'New file ...'_ на лентата за активност _(вляво)_, дайте му име и натиснете Enter.
Можете да създадете файл в съществуваща папка или в основната директория/папка. За да създадете нов файл, отворете местоположението/директорията, където искате да запазите файла, и изберете иконата _'New file ...'_ в лентата за активност _(вляво)_, дайте му име и натиснете Enter.

### 2. Редактиране и запазване на файл в хранилището
Използването на vscode.dev е полезно, когато искате да направите бързи актуализации на проекта си, без да зареждате никакъв софтуер локално.
За да актуализирате кода си, кликнете върху иконата 'Explorer', също разположена на лентата за активност, за да видите файловете и папките в хранилището.
Използването на vscode.dev е полезно, когато искате бързо да актуализирате проекта си, без да зареждате софтуер локално.
За да актуализирате кода си, кликнете върху иконата 'Explorer', също разположена в лентата за активност, за да видите файловете и папките в хранилището.
Изберете файл, за да го отворите в зоната за код, направете промените си и запазете.

След като приключите с актуализирането на проекта си, изберете иконата _`source control`_, която съдържа всички нови промени, които сте направили в хранилището си.
След като приключите с актуализациите на проекта си, изберете иконата _`source control`_, която съдържа всички нови промени, които сте направили в хранилището.
За да видите промените, които сте направили в проекта си, изберете файла(ите) в папката `Changes` в разширената лента за активност. Това ще отвори 'Работно дърво', за да визуализирате промените, които сте направили във файла. Червеното показва премахване от проекта, докато зеленото означава добавяне.
За да видите промените, които сте направили в проекта си, изберете файла(ите) в папката `Changes` в разширената лента за активност. Това ще отвори 'Working Tree', за да видите визуално промените, които сте направили във файла. Червеното показва премахване от проекта, докато зеленото означава добавяне.
Ако сте доволни от промените, които сте направили, задръжте курсора върху папката `Changes` и кликнете върху бутона `+`, за да подготвите промените. Подготовката означава просто да подготвите промените си за комитване към GitHub.
Ако сте доволни от направените промени, задръжте курсора върху папката `Changes` и кликнете върху бутона `+`, за да подготвите промените. Подготвянето означава, че подготвяте промените си за комитване в GitHub.
Ако обаче не сте доволни от някои промени и искате да ги отмените, задръжте курсора върху папката `Changes` и изберете иконата `undo`.
Ако обаче не сте доволни от някои промени и искате да ги отхвърлите, задръжте курсора върху папката `Changes` и изберете иконата `undo`.
След това напишете `commit message`_(Описание на промяната, която сте направили в проекта)_, кликнете върху иконата `check`, за да комитнете и изпратите промените си.
След това въведете `commit message`_(описание на промените, които сте направили в проекта)_, кликнете върху иконата `check`, за да комитнете и изпратите промените.
След като приключите с работата по проекта си, изберете иконата `hamburger menu` в горния ляв ъгъл, за да се върнете към хранилището на github.com.
Инсталирането на разширения в VSCode ви позволява да добавяте нови функции и опции за персонализирана среда за разработка в редактора си, за да подобрите работния си процес. Тези разширения също ви помагат да добавите поддръжка за множество програмни езици и често са или общи разширения, или базирани на език.
Инсталирането на разширения във VSCode ви позволява да добавяте нови функции и опции за персонализиране на средата за разработка, за да подобрите работния си процес. Тези разширения също така ви помагат да добавите поддръжка за множество програмни езици и често са или общи разширения, или базирани на езици.
За да разгледате списъка с всички налични разширения, кликнете върху иконата _`Extensions`_на лентата за активност и започнете да пишете името на разширението в текстовото поле, обозначено_'Search Extensions in Marketplace'_.
За да разгледате списъка с всички налични разширения, кликнете върху иконата _`Extensions`_в лентата за активност и започнете да въвеждате името на разширението в текстовото поле с надпис_'Search Extensions in Marketplace'_.
Ще видите списък с разширения, всяко от които съдържа **името на разширението, името на издателя, едно изречение описание, броя на изтеглянията** и **оценка със звезди**.
Можете също да видите всички предварително инсталирани разширения, като разширите папката _`Installed`_, популярни разширения, използвани от повечето разработчици, в папката _`Popular`_ и препоръчани разширения за вас, или от потребители в същото работно пространство, или въз основа на наскоро отворените ви файлове, в папката _`Recommended`_.
Можете също да видите всички предварително инсталирани разширения, като разширите папката _`Installed`_, популярни разширения, използвани от повечето разработчици, в папката _`Popular`_ и препоръчани разширения за вас, базирани на наскоро отворените ви файлове или от потребители в същото работно пространство, в папката _`Recommended`_.
За да инсталирате разширение, напишете името на разширението в полето за търсене и кликнете върху него, за да видите допълнителна информация за разширението в зоната за код, след като се появи в разширената лента за активност.
За да инсталирате разширение, въведете името му в полето за търсене и кликнете върху него, за да видите допълнителна информация за разширението в зоната за код, след като се появи в разширената лента за активност.
Можете или да кликнете върху _синия бутон за инсталиране_ в разширената лента за активност, за да го инсталирате, или да използвате бутона за инсталиране, който се появява в зоната за код, след като изберете разширението, за да заредите допълнителна информация.
След като инсталирате разширението, може да се наложи да модифицирате неговото поведение и да го персонализирате според вашите предпочитания. За да направите това, изберете иконата Extensions, и този път вашето разширение ще се появи в папката _Installed_, кликнете върху _**Gear icon**_ и навигирайте до _Extensions Setting_.
След като инсталирате разширението, може да се наложи да модифицирате поведението му и да го персонализирате според предпочитанията си. За да направите това, изберете иконата Extensions, и този път вашето разширение ще се появи в папката _Installed_, кликнете върху _**Gear icon**_ и навигирайте до _Extensions Setting_.
След като инсталирате и използвате разширението си, vscode.dev предлага опции за управление на разширението според различни нужди. Например, можете да изберете да:
След като инсталирате и използвате разширението, vscode.dev предлага опции за управление на разширението според различни нужди. Например, можете да изберете да:
- **Деактивирате:** _(Можете временно да деактивирате разширение, когато вече не ви е необходимо, но не искате да го деинсталирате напълно)_
Изберете инсталираното разширение в разширената лента за активност > кликнете върху иконата Gear > изберете 'Disable' или 'Disable (Workspace)' **ИЛИ** Отворете разширението в зоната за код и кликнете върху синия бутон Disable.
Изберете инсталираното разширение в разширената лента за активност > кликнете върху Gear icon > изберете 'Disable' или 'Disable (Workspace)' **ИЛИ** Отворете разширението в зоната за код и кликнете върху синия бутон Disable.
- **Деинсталирате:** Изберете инсталираното разширение в разширената лента за активност > кликнете върху иконата Gear > изберете 'Uninstall' **ИЛИ** Отворете разширението в зоната за код и кликнете върху синия бутон Uninstall.
- **Деинсталирате:** Изберете инсталираното разширение в разширената лента за активност > кликнете върху Gear icon > изберете 'Uninstall' **ИЛИ** Отворете разширението в зоната за код и кликнете върху синия бутон Uninstall.
Прочетете повече за [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) и някои от неговите други функции.
Прочетете повече за [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) и някои от другите му функции.
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да било недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Добавете детайлите на вашата автобиография, като замените _текста за попълване_ в HTML кода.
Добавете детайлите от вашата автобиография, за да замените _текста за попълване_ в HTML кода.
**Стъпка 5:** Задръжте курсора върху папката My-Resume, кликнете върху иконата `New File ...` и създайте 2 нови файла във вашия проект: `style.css` и `codeswing.json`.
**Стъпка 7:** Инсталирайте разширението `Codeswing`, за да визуализирате уебсайта с автобиография в кода.
**Стъпка 7:** Инсталирайте разширението `Codeswing`, за да визуализирате уебсайта с автобиография в текстовата област.
Кликнете върху иконата _`Extensions`_ в лентата с инструменти и въведете Codeswing. Или кликнете върху _синия бутон за инсталиране_ в разширената лента с инструменти, за да инсталирате, или използвайте бутона за инсталиране, който се появява в кода, след като изберете разширението, за да заредите допълнителна информация. Веднага след инсталирането на разширението, наблюдавайте промените във вашия проект 😃.
Кликнете върху иконата _`Extensions`_ в лентата с инструменти и въведете Codeswing. Или кликнете върху _синия бутон за инсталиране_ в разширената лента с инструменти, за да инсталирате, или използвайте бутона за инсталиране, който се появява в текстовата област, след като изберете разширението, за да заредите допълнителна информация. Веднага след инсталирането на разширението, наблюдавайте промените във вашия проект 😃.


Ако сте доволни от направените промени, задръжте курсора върху папката `Changes` и кликнете върху бутона `+`, за да добавите промените.
Ако сте доволни от направените промени, задръжте курсора върху папката `Changes` и кликнете върху бутона `+`, за да подготвите промените.
Въведете съобщение за комит _(Описание на промените, които сте направили в проекта)_ и комитнете промените, като кликнете върху `check`. След като приключите с работата по проекта, изберете иконата на менюто в горния ляв ъгъл, за да се върнете към хранилището в GitHub.
Въведете съобщение за commit _(Описание на направените промени в проекта)_ и запазете промените, като кликнете върху `check`. След като приключите с работата по проекта, изберете иконата на менюто (хамбургер) в горния ляв ъгъл, за да се върнете към хранилището в GitHub.
Поздравления 🎉 Току-що създадохте вашия уебсайт за автобиография с помощта на vscode.dev само за няколко стъпки.
Поздравления 🎉 Току-що създадохте уебсайт за автобиография с помощта на vscode.dev само в няколко стъпки.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Малко контекст: създаването на чат асистенти с помощта на генеративен AI е чудесен начин да започнете да учите за AI. В този урок ще научите как да интегрирате генеративен AI в уеб приложение. Да започваме.
## Свързване с генеративен AI
За бекенда използваме GitHub Models. Това е страхотна услуга, която ви позволява да използвате AI безплатно. Отидете в нейния playground и вземете кода, който съответства на избрания от вас език за бекенд. Ето как изглежда [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground).
<div>
<imgsrc="./assets/playground.png"alt="GitHub Models AI Playground"with="600">
</div>
Както казахме, изберете таба "Code" и вашата избрана среда за изпълнение.
В този случай избираме Python, което означава, че ще използваме този код:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
Нека почистим този код малко, за да бъде по-удобен за повторна употреба:
```python
def call_llm(prompt: str, system_message: str):
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
```
С тази функция `call_llm` можем да вземем prompt и системен prompt, а функцията ще върне резултата.
### Персонализиране на AI Асистента
Ако искате да персонализирате AI асистента, можете да зададете как искате да се държи, като попълните системния prompt по следния начин:
```python
call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")
```
## Излагане чрез Web API
Страхотно, завършихме AI частта, нека видим как можем да я интегрираме в Web API. За Web API избираме Flask, но всяка уеб рамка би била подходяща. Ето кода за това:
```python
# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
@app.route("/", methods=["GET"])
def index():
return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
Тук създаваме Flask API и дефинираме основен маршрут "/" и "/chat". Вторият е предназначен за използване от нашия фронтенд, за да предава въпроси към него.
За да интегрираме *llm.py*, ето какво трябва да направим:
- Импортирайте функцията `call_llm`:
```python
from llm import call_llm
from flask import Flask, request
```
- Извикайте я от маршрута "/chat":
```python
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
```
Тук анализираме входящата заявка, за да извлечем свойството `message` от JSON тялото. След това извикваме LLM с този код:
```python
response = call_llm(message, "You are a helpful assistant")
# return the response as JSON
return jsonify({
"response": response
})
```
Страхотно, вече сме готови.
### Конфигуриране на Cors
Трябва да отбележим, че настройваме нещо като CORS (споделяне на ресурси между различни произходи). Това означава, че тъй като нашият бекенд и фронтенд ще работят на различни портове, трябва да позволим на фронтенда да се свързва с бекенда. Има парче код в *api.py*, което настройва това:
```python
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
```
В момента е настроено да позволява "*" (всички произходи), което е малко небезопасно. Трябва да го ограничим, когато преминем към продукция.
## Стартиране на проекта
Добре, имаме *llm.py* и *api.py*, как можем да ги накараме да работят с бекенд? Ето какво трябва да направим:
- Инсталирайте зависимости:
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
pip install openai flask flask-cors openai
```
- Стартирайте API
```sh
python api.py
```
Ако сте в Codespaces, трябва да отидете в Ports в долната част на редактора, да кликнете с десния бутон върху него и да изберете "Port Visibility" и след това "Public".
### Работа върху фронтенд
Сега, когато имаме работещ API, нека създадем фронтенд за него. Минимален фронтенд, който ще подобрим постепенно. В папка *frontend* създайте следното:
```text
backend/
frontend/
index.html
app.js
styles.css
```
Нека започнем с**index.html**:
```html
<html>
<head>
<linkrel="stylesheet"href="styles.css">
</head>
<body>
<form>
<textareaid="messages"></textarea>
<inputid="input"type="text"/>
<buttontype="submit"id="sendBtn">Send</button>
</form>
<scriptsrc="app.js"/>
</body>
</html>
```
Горният код е абсолютният минимум, който ви е необходим за поддръжка на чат прозорец, тъй като се състои от текстово поле, където ще се показват съобщенията, поле за въвеждане на съобщението и бутон за изпращане на съобщението към бекенда. Нека разгледаме JavaScript в *app.js*.
- 1) Тук получаваме референция към всички елементи, които ще използваме по-късно в кода.
- 2) В тази секция създаваме функция, която използва вградения метод `fetch`, за да извика нашия бекенд.
- 3) `appendMessage` помага да добавим отговори, както и това, което въвеждате като потребител.
- 4) Тук слушаме събитието за изпращане и четем полето за въвеждане, поставяме съобщението на потребителя в текстовото поле, извикваме API и показваме отговора в текстовото поле.
Нека разгледаме стилизирането, тук можете да бъдете креативни и да го направите както искате, но ето някои предложения:
**styles.css**
```
.message {
background: #222;
box-shadow: 0 0 0 10px orange;
padding: 10px:
margin: 5px;
}
.message.user {
background: blue;
}
.message.assistant {
background: grey;
}
```
С тези три класа ще стилизирате съобщенията различно в зависимост от това дали идват от асистента или от вас като потребител. Ако искате вдъхновение, разгледайте папката `solution/frontend/styles.css`.
### Промяна на Base Url
Има едно нещо, което не зададохме, и това е`BASE_URL`. Това не е известно, докато вашият бекенд не бъде стартиран. За да го зададете:
- Ако стартирате API локално, трябва да бъде зададено на нещо като `http://localhost:5000`.
- Ако го стартирате в Codespaces, трябва да изглежда нещо като "[name]app.github.dev".
## Задача
Създайте собствена папка *project* със съдържание като следното:
```text
project/
frontend/
index.html
app.js
styles.css
backend/
api.py
llm.py
```
Копирайте съдържанието от инструкциите по-горе, но не се колебайте да го персонализирате според вашите предпочитания.
## Решение
[Решение](./solution/README.md)
## Бонус
Опитайте да промените личността на AI асистента. Когато извиквате `call_llm` в *api.py*, можете да промените втория аргумент на каквото искате, например:
```python
call_llm(message, "You are Captain Picard")
```
Променете също CSS и текста според вашите предпочитания, направете промени в *index.html* и *styles.css*.
## Обобщение
Страхотно, научихте от нулата как да създадете личен асистент, използвайки AI. Направихме това с помощта на GitHub Models, бекенд на Python и фронтенд на HTML, CSS и JavaScript.
## Настройка с Codespaces
- Навигирайте до: [Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners)
- Създайте от шаблон (уверете се, че сте влезли в GitHub) в горния десен ъгъл:

Това трябва да стартира среда, с която можете да работите.
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Намерете *app.js*, променете `BASE_URL` на URL адреса на вашия бекенд
Стартирайте го
```
npx http-server -p 8000
```
Опитайте да напишете съобщение в чата, трябва да видите отговор (ако го стартирате в Codespace или сте настроили токен за достъп).
## Настройка на токен за достъп (ако не го стартирате в Codespace)
Вижте [Set up PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
3. [**Присъединете се към Azure AI Foundry Discord и се срещнете с експерти и други разработчици**](https://discord.com/invite/ByRwuEEgH4)
# Уеб разработка за начинаещи - учебна програма
Научете основите на уеб разработката с нашия 12-седмичен курс, създаден от Microsoft Cloud Advocates. Всяка от 24-те лекции разглежда JavaScript, CSS и HTML чрез практически проекти като терариуми, разширения за браузъри и космически игри. Участвайте в тестове, дискусии и практически задачи. Подобрете уменията си и оптимизирайте запазването на знания с нашата ефективна проектно-базирана методология. Започнете своето кодиращо пътешествие още днес!
Научете основите на уеб разработката с нашия 12-седмичен курс, създаден от Microsoft Cloud Advocates. Всяка от 24-те лекции разглежда JavaScript, CSS и HTML чрез практически проекти като терариуми, разширения за браузъри и космически игри. Участвайте в тестове, дискусии и практически задачи. Подобрете уменията си и оптимизирайте запаметяването на знания с нашата ефективна проектно-базирана методология. Започнете своето кодиращо пътешествие още днес!
### 🌐 Поддръжка на много езици
#### Поддържано чрез GitHub Action (Автоматизирано и винаги актуално)
**Ако желаете да добавите допълнителни преводи, списъкът с поддържани езици е [тук](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md)**
#### 🧑🎓 _Студент ли сте?_
Посетете [**страницата Student Hub**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon), където ще намерите ресурси за начинаещи, студентски пакети и дори начини да получите безплатен ваучер за сертификат. Това е страницата, която трябва да запазите и проверявате периодично, тъй като съдържанието се обновява ежемесечно.
Посетете [**страницата за студенти**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon), където ще намерите ресурси за начинаещи, студентски пакети и дори начини да получите безплатен ваучер за сертификат. Това е страницата, която трябва да запазите и проверявате от време на време, тъй като съдържанието се сменя ежемесечно.
### 📣 Съобщение - _Нова учебна програма_ за Генеративен AI за JavaScript току-що беше пусната
### 📣 Съобщение - _Нов проект за изграждане с Генеративен AI_
Току-що добавен нов проект за AI асистент, вижте го [тук](./09-chat-project/README.md)
### 📣 Съобщение - _Нова учебна програма_ за Генеративен AI за JavaScript
Не пропускайте нашата нова учебна програма за Генеративен AI!
**[Ученици](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, за всеки урок започнете с предварителен тест и продължете с четене на учебния материал, изпълнение на различните дейности и проверете разбирането си с тест след лекцията.
За да подобрите учебния си опит, свържете сес вашите връстници, за да работите заедно по проектите! Дискусиите са насърчени в нашия [форум за дискусии](https://github.com/microsoft/Web-Dev-For-Beginners/discussions), където нашият екип от модератори ще бъде на разположение да отговори на вашите въпроси.
За да подобрите учебния си опит, свържете сес вашите връстници, за да работите заедно по проектите! Дискусиите са насърчавани в нашия [форум за дискусии](https://github.com/microsoft/Web-Dev-For-Beginners/discussions), където нашият екип от модератори ще бъде на разположение да отговори на вашите въпроси.
За да продължите образованието си, силно препоръчваме да разгледате [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) за допълнителни учебни материали.
@ -76,7 +88,7 @@ CO_OP_TRANSLATOR_METADATA:
Следвайте тези стъпки:
1. **Направете Fork на хранилището**: Кликнете върху бутона "Fork" в горния десен ъгъл на тази страница.
#### Изпълнение на учебната програма локално на вашия компютър
За да изпълните тази учебна програма локално на вашия компютър, ще ви е необходим текстов редактор, браузър и инструмент за команден ред. Нашият първи урок, [Въведение в програмните езици и инструменти](../../1-getting-started-lessons/1-intro-to-programming-languages), ще ви преведе през различни опции за всеки от тези инструменти, за да изберете това, което работи най-добре за вас.
За да изпълните тази учебна програма локално на вашия компютър, ще ви е необходим текстов редактор, браузър и инструмент за команден ред. Нашият първи урок, [Въведение в програмните езици и инструменти за работа](../../1-getting-started-lessons/1-intro-to-programming-languages), ще ви преведе през различни опции за всеки от тези инструменти, за да изберете това, което работи най-добре за вас.
Нашата препоръка е да използвате [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) като ваш редактор, който също има вграден [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon). Можете да изтеглите Visual Studio Code [тук](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
Нашата препоръка е да използвате [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) като редактор, който също има вграден [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon). Можете да изтеглите Visual Studio Code [тук](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
1. Клонирайте вашето хранилище на вашия компютър. Можете да направите това, като кликнете върху бутона **Code** и копирате URL адреса:
[!CodeSpace](./images/createcodespace.png)
След това отворете [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) в [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) и изпълнете следната команда, заменяйки `<your-repository-url>`с URL адреса, който току-що копирахте:
След това отворете [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) в [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) и изпълнете следната команда, като замените`<your-repository-url>`с URL адреса, който току-що копирахте:
```bash
git clone <your-repository-url>
```
2. Отворете папката във Visual Studio Code. Можете да направите това, като кликнете **File** > **Open Folder** и изберете папката, която току-що клонирахте.
> Препоръчани разширения за Visual Studio Code:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - за преглед на HTML страници във Visual Studio Code
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - за да ви помогне да пишете код по-бързо
## 📂 Всеки урок включва:
- опционална скица
- опционално допълнително видео
- предварителен тест
- писмен урок
- за проектно-базирани уроци, ръководства стъпка по стъпка за изграждане на проекта
- проверки на знанията
- предизвикателство
- допълнително четене
- задача
- [тест след урока](https://ff-quizzes.netlify.app/web/)
> **Бележка относно тестовете**: Всички тестове са в папката Quiz-app, общо 48 теста с по три въпроса всеки. Теса достъпни [тук](https://ff-quizzes.netlify.app/web/) и приложението за тестове може да се изпълнява локално или да се разположи в Azure; следвайте инструкциите в папката `quiz-app`.
## 🗃️ Уроци
| | Име на проекта | Преподавани концепции | Цели на обучението | Свързан урок | Автор |
| 01 | Започваме | Въведение в програмирането и инструментите на професията | Научете основите на повечето програмни езици и за софтуера, който помага на професионалните разработчици да вършат работата си | [Въведение в програмните езици и инструментите на професията](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | Започваме | Основи на GitHub, включително работа в екип | Как да използвате GitHub във вашия проект, как да си сътрудничите с други върху кодова база | [Въведение в GitHub](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | Започваме | Достъпност | Научете основите на уеб достъпността | [Основи на достъпността](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | Основи на JS | Типове данни в JavaScript | Основите на типовете данни в JavaScript | [Типове данни](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | Основи на JS | Функции и методи | Научете за функциите и методите за управление на логическия поток на приложението | [Функции и методи](./2-js-basics/2-functions-methods/README.md) | Jasmine и Christopher |
| 06 | Основи на JS | Вземане на решения с JS | Научете как да създавате условия в кода си, използвайки методи за вземане на решения | [Вземане на решения](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | Основи на JS | Масиви и цикли | Работа с данни, използвайки масиви и цикли в JavaScript | [Масиви и цикли](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Терариум](./3-terrarium/solution/README.md) | HTML на практика | Създайте HTML за онлайн терариум, фокусирайки се върху изграждането на оформление | [Въведение в HTML](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Терариум](./3-terrarium/solution/README.md) | CSS на практика | Създайте CSS за стилизиране на онлайн терариум, фокусирайки се върху основите на CSS, включително правене на страницата отзивчива | [Въведение в CSS](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Терариум](./3-terrarium/solution/README.md) | JavaScript затваряния, манипулация на DOM | Създайте JavaScript, за да направите терариума функционален като интерфейс за влачене/пускане, съсредоточавайки се върху затваряния и манипулация на DOM | [JavaScript затваряния, манипулация на DOM](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Джен |
| 11 | [Игра за писане](./4-typing-game/solution/README.md) | Създаване на игра за писане | Научете как да използвате събития от клавиатурата, за да управлявате логиката на вашето JavaScript приложение | [Програмиране, базирано на събития](./4-typing-game/typing-game/README.md) | Кристофър |
| 12 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Работа с браузъри | Научете как работят браузърите, тяхната история и как да създадете първите елементи на браузърно разширение | [За браузърите](./5-browser-extension/1-about-browsers/README.md) | Джен |
| 13 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Създаване на форма, извикване на API и съхраняване на променливи в локално хранилище | Създайте JavaScript елементите на вашето браузърно разширение, за да извикате API, използвайки променливи, съхранени в локално хранилище | [API, форми и локално хранилище](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Джен |
| 14 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Фонови процеси в браузъра, уеб производителност | Използвайте фоновите процеси на браузъра, за да управлявате иконата на разширението; научете за уеб производителността и някои оптимизации | [Фонови задачи и производителност](./5-browser-extension/3-background-tasks-and-performance/README.md) | Джен |
| 15 | [Космическа игра](./6-space-game/solution/README.md) | По-напреднало разработване на игри с JavaScript | Научете за наследяване, използвайки както класове, така и композиция, както и модела Pub/Sub, като подготовка за създаване на игра | [Въведение в напреднало разработване на игри](./6-space-game/1-introduction/README.md) | Крис |
| 16 | [Космическа игра](./6-space-game/solution/README.md) | Рисуване върху canvas | Научете за Canvas API, използван за рисуване на елементи на екрана | [Рисуване върху canvas](./6-space-game/2-drawing-to-canvas/README.md) | Крис |
| 17 | [Космическа игра](./6-space-game/solution/README.md) | Придвижване на елементи по екрана | Открийте как елементите могат да се движат, използвайки декартови координати и Canvas API | [Придвижване на елементи](./6-space-game/3-moving-elements-around/README.md) | Крис |
| 18 | [Космическа игра](./6-space-game/solution/README.md) | Откриване на сблъсъци | Направете елементите да се сблъскват и реагират един на друг, използвайки натискания на клавиши, и осигурете функция за охлаждане за производителност на играта | [Откриване на сблъсъци](./6-space-game/4-collision-detection/README.md) | Крис |
| 19 | [Космическа игра](./6-space-game/solution/README.md) | Поддържане на резултат | Извършвайте математически изчисления въз основа на състоянието и производителността на играта | [Поддържане на резултат](./6-space-game/5-keeping-score/README.md) | Крис |
| 20 | [Космическа игра](./6-space-game/solution/README.md) | Завършване и рестартиране на играта | Научете за завършване и рестартиране на играта, включително почистване на ресурси и нулиране на стойности на променливи | [Условие за край](./6-space-game/6-end-condition/README.md) | Крис |
| 21 | [Банкова апликация](./7-bank-project/solution/README.md) | HTML шаблони и маршрути в уеб приложение | Научете как да създадете структурата на многостраничен уебсайт, използвайки маршрутизация и HTML шаблони | [HTML шаблони и маршрути](./7-bank-project/1-template-route/README.md) | Йохан |
| 22 | [Банкова апликация](./7-bank-project/solution/README.md) | Създаване на форма за вход и регистрация | Научете за създаване на форми и обработка на процедури за валидация | [Форми](./7-bank-project/2-forms/README.md) | Йохан |
| 23 | [Банкова апликация](./7-bank-project/solution/README.md) | Методи за извличане и използване на данни | Как данните се движат в и извън вашето приложение, как да ги извличате, съхранявате и изтривате | [Данни](./7-bank-project/3-data/README.md) | Йохан |
| 24 | [Банкова апликация](./7-bank-project/solution/README.md) | Концепции за управление на състояние | Научете как вашето приложение запазва състояние и как да го управлявате програмно | [Управление на състояние](./7-bank-project/4-state-management/README.md) | Йохан |
2. Отворете папката във Visual Studio Code. Можете да направите това, като кликнете върху **File**.
> **Отворете папка** и изберете папката, която току-що клонирахте.
> Препоръчителни разширения за Visual Studio Code:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - за преглед на HTML страници директно във Visual Studio Code
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - за по-бързо писане на код
## 📂 Всяка лекция включва:
- опционална скица
- опционално допълнително видео
- предварителен тест за загрявка
- писмена лекция
- за лекции, базирани на проекти, ръководства стъпка по стъпка за изграждане на проекта
- проверки на знанията
- предизвикателство
- допълнително четиво
- задача
- [тест след лекцията](https://ff-quizzes.netlify.app/web/)
> **Бележка относно тестовете**: Всички тестове се намират в папката Quiz-app, общо 48 теста с по три въпроса всеки. Теса достъпни [тук](https://ff-quizzes.netlify.app/web/), като приложението за тестове може да се стартира локално или да се разположи в Azure; следвайте инструкциите в папката `quiz-app`.
## 🗃️ Лекции
| | Име на проекта | Преподавани концепции | Учебни цели | Свързана лекция | Автор |
| 01 | Първи стъпки | Въведение в програмирането и инструментите на професионалистите | Научете основите на повечето програмни езици и за софтуера, който помага на професионалните разработчици в работата им | [Въведение в програмните езици и инструментите](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | Първи стъпки | Основи на GitHub, включително работа в екип | Как да използвате GitHub във вашия проект и как да си сътрудничите с други разработчици | [Въведение в GitHub](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | Първи стъпки | Достъпност | Научете основите на уеб достъпността | [Основи на достъпността](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | Основи на JS | Типове данни в JavaScript | Основите на типовете данни в JavaScript | [Типове данни](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | Основи на JS | Функции и методи | Научете за функциите и методите за управление на логиката на приложението | [Функции и методи](./2-js-basics/2-functions-methods/README.md) | Jasmine и Christopher |
| 06 | Основи на JS | Вземане на решения с JS | Научете как да създавате условия в кода си, използвайки методи за вземане на решения | [Вземане на решения](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | Основи на JS | Масиви и цикли | Работа с данни, използвайки масиви и цикли в JavaScript | [Масиви и цикли](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Терариум](./3-terrarium/solution/README.md) | HTML на практика | Създайте HTML за онлайн терариум, фокусирайки се върху изграждането на оформление | [Въведение в HTML](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Терариум](./3-terrarium/solution/README.md) | CSS на практика | Създайте CSS за стилизиране на онлайн терариум, фокусирайки се върху основите на CSS, включително правене на страницата адаптивна | [Въведение в CSS](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Терариум](./3-terrarium/solution/README.md) | Затваряния в JavaScript, манипулация на DOM | Създайте JavaScript за функционалност на терариума като интерфейс за влачене/пускане, фокусирайки се върху затваряния и манипулация на DOM | [Затваряния в JavaScript, манипулация на DOM](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Игра за писане](./4-typing-game/solution/README.md) | Създаване на игра за писане | Научете как да използвате събития от клавиатурата за управление на логиката на вашето JavaScript приложение | [Програмиране, базирано на събития](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Работа с браузъри | Научете как работят браузърите, тяхната история и как да създадете първите елементи на браузърно разширение | [За браузърите](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Създаване на форма, извикване на API и съхраняване на променливи в локално хранилище | Създайте JavaScript елементи на вашето браузърно разширение за извикване на API, използвайки променливи, съхранени в локално хранилище | [API, форми и локално хранилище](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Еко браузърно разширение](./5-browser-extension/solution/README.md) | Фонови процеси в браузъра, уеб производителност | Използвайте фоновите процеси на браузъра за управление на иконата на разширението; научете за уеб производителност и оптимизации | [Фонови задачи и производителност](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Космическа игра](./6-space-game/solution/README.md) | По-напреднало разработване на игри с JavaScript | Научете за наследяване, използвайки както класове, така и композиция, и модела Pub/Sub, като подготовка за създаване на игра | [Въведение в напреднало разработване на игри](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Космическа игра](./6-space-game/solution/README.md) | Рисуване върху canvas | Научете за Canvas API, използван за рисуване на елементи на екрана | [Рисуване върху canvas](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Космическа игра](./6-space-game/solution/README.md) | Преместване на елементи по екрана | Открийте как елементите могат да се движат, използвайки картезиански координати и Canvas API | [Преместване на елементи](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Космическа игра](./6-space-game/solution/README.md) | Засичане на сблъсъци | Направете елементите да се сблъскват и реагират един на друг, използвайки натискания на клавиши, и осигурете функция за охлаждане за производителност на играта | [Засичане на сблъсъци](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Космическа игра](./6-space-game/solution/README.md) | Водене на резултат | Извършвайте математически изчисления, базирани на състоянието и производителността на играта | [Водене на резултат](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Космическа игра](./6-space-game/solution/README.md) | Завършване и рестартиране на играта | Научете за завършване и рестартиране на играта, включително почистване на ресурси и нулиране на стойности на променливи | [Условие за край](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Банкова апликация](./7-bank-project/solution/README.md) | HTML шаблони и маршрути в уеб приложение | Научете как да създадете структурата на архитектурата на многостраничен уебсайт, използвайки маршрути и HTML шаблони | [HTML шаблони и маршрути](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Банкова апликация](./7-bank-project/solution/README.md) | Създаване на форма за вход и регистрация | Научете за създаване на форми и обработка на рутините за валидиране | [Форми](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Банкова апликация](./7-bank-project/solution/README.md) | Методи за извличане и използване на данни | Как данните се движат в и извън вашето приложение, как да ги извличате, съхранявате и изтривате | [Данни](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Банкова апликация](./7-bank-project/solution/README.md) | Концепции за управление на състояние | Научете как вашето приложение запазва състояние и как да го управлявате програмно | [Управление на състояние](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [Браузър/VScode код](../../8-code-editor) | Работа с VScode | Научете как да използвате редактор за код | [Използване на редактор за код VScode](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [AI Асистенти](./9-chat-project/README.md) | Работа с AI | Научете как да създадете свой собствен AI асистент | [Проект за AI асистент](./9-chat-project/README.md) | Chris |
## 🏫 Педагогика
@ -158,52 +171,52 @@ CO_OP_TRANSLATOR_METADATA:
* обучение, базирано на проекти
* чести тестове
Програмата учи основите на JavaScript, HTML и CSS, както и най-новите инструменти и техники, използвани от съвременните уеб разработчици. Студентите ще имат възможност да придобият практически опит, като създадат игра за писане, виртуален терариум, екологично браузърно разширение, игра в стил космически нашественици и банкова апликация за бизнеси. До края на серията студентите ще са придобили солидно разбиране за уеб разработката.
Програмата преподава основите на JavaScript, HTML и CSS, както и най-новите инструменти и техники, използвани от съвременните уеб разработчици. Студентите ще имат възможност да придобият практически опит, като създадат игра за писане, виртуален терариум, екологично браузърно разширение, игра в стил "космически нашественици" и банкова апликация за бизнеси. До края на серията студентите ще са придобили солидно разбиране за уеб разработката.
> 🎓 Можете да вземете първите няколко урока от тази учебна програма като [Учебен път](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) в Microsoft Learn!
> 🎓 Можете да вземете първите няколко лекции от тази учебна програма като [Учебен път](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) в Microsoft Learn!
Чрез осигуряване на съдържание, което се съгласувас проекти, процесът става по-ангажиращ за студентите, а задържането на концепциисе увеличава. Също така написахме няколко начални урока по основи на JavaScript за въвеждане на концепции, съчетани с видео от "[Серия за начинаещи: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" колекция от видео уроци, някои от чиито автори допринесоха за тази учебна програма.
Като гарантираме, че съдържанието е свързанос проекти, процесът става по-ангажиращ за студентите, а задържането на концепциите се увеличава. Освен това написахме няколко начални лекции за основите на JavaScript, за да въведем концепции, съчетани с видео от "[Серия за начинаещи: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" колекция от видео уроци, някои от чиито автори допринесоха за тази учебна програма.
Освен това, тест с нисък риск преди час задава намерението на студента към изучаване на тема, докато втори тест след час осигурява по-нататъшно задържане. Тази учебна програма е проектирана да бъде гъвкава и забавна и може да бъде взета изцяло или частично. Проектите започват малки и стават все по-сложни до края на 12-седмичния цикъл.
Освен това, тест с нисък риск преди клас задава намерението на студента към изучаване на тема, докато втори тест след клас осигурява допълнително задържане. Тази учебна програма е проектирана да бъде гъвкава и забавна и може да бъде взета изцяло или частично. Проектите започват малки и стават все по-сложни до края на 12-седмичния цикъл.
Докато умишлено избягвахме въвеждането на JavaScript рамки, за да се концентрираме върху основните умения, необходими на уеб разработчик преди приемането на рамка, добра следваща стъпка след завършване на тази учебна програма би било изучаването на Node.js чрез друга колекция от видеа: "[Серия за начинаещи: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
Докато умишлено избягвахме въвеждането на JavaScript рамки, за да се концентрираме върху основните умения, необходими на уеб разработчика преди приемането на рамка, добра следваща стъпка след завършване на тази учебна програма би била изучаването на Node.js чрез друга колекция от видеа: "[Серия за начинаещи: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
> Посетете нашите [Правила за поведение](CODE_OF_CONDUCT.md) и [Насоки за принос](CONTRIBUTING.md). Очакваме вашата конструктивна обратна връзка!
## 🧭 Офлайн достъп
Можете да стартирате тази документация офлайн, използвайки [Docsify](https://docsify.js.org/#/). Форкнете това хранилище, [инсталирайте Docsify](https://docsify.js.org/#/quickstart) на вашата локална машина и след това в основната папка на това хранилище въведете `docsify serve`. Уебсайтът ще бъде достъпен на порт 3000 на вашия localhost: `localhost:3000`.
Можете да стартирате тази документация офлайн, използвайки [Docsify](https://docsify.js.org/#/). Форкнете това хранилище, [инсталирайте Docsify](https://docsify.js.org/#/quickstart) на вашия локален компютър и след това в основната папка на това хранилище напишете `docsify serve`. Уебсайтът ще бъде стартиран на порт 3000 на вашия localhost: `localhost:3000`.
## 📘 PDF
PDF с всички уроци може да бъде намерен [тук](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf).
PDF с всички лекции може да бъде намерен [тук](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf).
## 🎒 Други курсове
Нашият екип създава и други курсове! Разгледайте:
Нашият екип създава и други курсове! Вижте:
- [Генеративен AI за начинаещи](https://aka.ms/genai-beginners)
- [Генеративен AI за начинаещи .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [Генеративен AI с JavaScript](https://github.com/microsoft/generative-ai-with-javascript)
- [Генеративен AI с Java](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [AI за начинаещи](https://aka.ms/ai-beginners)
- [Наука за данни за начинаещи](https://aka.ms/datascience-beginners)
- [Машинно обучение за начинаещи](https://aka.ms/ml-beginners)
- [Киберсигурност за начинаещи](https://github.com/microsoft/Security-101)
- [Уеб разработка за начинаещи](https://aka.ms/webdev-beginners)
- [IoT за начинаещи](https://aka.ms/iot-beginners)
- [XR разработка за начинаещи](https://github.com/microsoft/xr-development-for-beginners)
- [Майсторство на GitHub Copilot за агентно използване](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Майсторство на GitHub Copilot за C#/.NET разработчици](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Избери своето приключение с Copilot](https://github.com/microsoft/CopilotAdventures)
- [Наука за данни за начинаещи](https://aka.ms/datascience-beginners)
- [Машинно обучение за начинаещи](https://aka.ms/ml-beginners)
- [Киберсигурност за начинаещи](https://github.com/microsoft/Security-101)
- [Уеб разработка за начинаещи](https://aka.ms/webdev-beginners)
- [IoT за начинаещи](https://aka.ms/iot-beginners)
- [Разработка на XR за начинаещи](https://github.com/microsoft/xr-development-for-beginners)
- [Овладяване на GitHub Copilot за агентно използване](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Овладяване на GitHub Copilot за разработчици на C#/.NET](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Избери своето собствено приключение с Copilot](https://github.com/microsoft/CopilotAdventures)
## Лиценз
Това хранилище е лицензирано под MIT лиценза. Вижте файла [LICENSE](../../LICENSE) за повече информация.
Този репозиторий е лицензиран под лиценза MIT. Вижте файла [LICENSE](../../LICENSE) за повече информация.
---
**Отказ от отговорност**:
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.
Tato lekce pokrývá základy programovacích jazyků. Témata zde uvedená se vztahují na většinu moderních programovacích jazyků. V části "Nástroje" se naučíte o užitečném softwaru, který vám jako vývojáři pomůže.
Tato lekce pokrývá základy programovacích jazyků. Témata zde uvedená platí pro většinu moderních programovacích jazyků. V části „Nástroje“ se naučíte o užitečném softwaru, který vám jako vývojáři pomůže.


> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před lekcí
## Kvíz před lekcí
[Kvíz před lekcí](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
## Úvod
V této lekci se budeme zabývat:
- Co je programování?
- Typy programovacích jazyků
- Základní prvky programu
- Užitečný software a nástroje pro profesionálního vývojáře
- Co je programování?
- Typy programovacích jazyků
- Základní prvky programu
- Užitečný software a nástroje pro profesionální vývojáře
> Tuto lekci si můžete projít na [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon)!
## Co je programování?
Programování (také známé jako kódování) je proces psaní instrukcí pro zařízení, jako je počítač nebo mobilní zařízení. Tyto instrukce píšeme pomocí programovacího jazyka, který je následně interpretován zařízením. Tyto sady instrukcí mohou být označovány různými názvy, například *program*, *počítačový program*, *aplikace (app)* nebo *spustitelný soubor*.
Programování (také známé jako kódování) je proces psaní instrukcí pro zařízení, jako je počítač nebo mobilní zařízení. Tyto instrukce píšeme pomocí programovacího jazyka, který zařízení následně interpretuje. Tyto sady instrukcí mohou být označovány různými názvy, například *program*, *počítačový program*, *aplikace (app)* nebo *spustitelný soubor*.
*Program* může být cokoliv, co je napsáno pomocí kódu; webové stránky, hry a mobilní aplikace jsou programy. I když je možné vytvořit program bez psaní kódu, základní logika je interpretována zařízením a tato logika byla s největší pravděpodobností napsána pomocí kódu. Program, který *běží* nebo *provádí* kód, vykonává instrukce. Zařízení, na kterém čtete tuto lekci, právě spouští program, aby ji zobrazilo na vaší obrazovce.
@ -42,9 +42,9 @@ Programovací jazyky umožňují vývojářům psát instrukce pro zařízení.
Programovací jazyky mají různé formáty a mohou sloužit různým účelům. Například JavaScript se primárně používá pro webové aplikace, zatímco Bash se používá hlavně pro operační systémy.
*Nízké úrovně jazyků* obvykle vyžadují méně kroků pro interpretaci instrukcí zařízením než *vysoké úrovně jazyků*. Co však činí vysoké úrovně jazyků populárními, je jejich čitelnost a podpora. JavaScript je považován za jazyk vysoké úrovně.
*Nízké úrovně jazyků* obvykle vyžadují méně kroků, aby zařízení interpretovalo instrukce, než *vysoké úrovně jazyků*. Co však činí vysoké úrovně jazyků populárními, je jejich čitelnost a podpora. JavaScript je považován za jazyk vysoké úrovně.
Následující kód ukazuje rozdíl mezi jazykem vysoké úrovně (JavaScript) a jazykem nízké úrovně (ARM assembler).
Následující kód ilustruje rozdíl mezi jazykem vysoké úrovně (JavaScript) a jazykem nízké úrovně (ARM assembly).
```javascript
let number = 10
@ -91,9 +91,9 @@ Věřte nebo ne, *oba dělají totéž*: tisknou Fibonacciho posloupnost až do
Jednotlivá instrukce v programu se nazývá *příkaz* a obvykle má znak nebo mezeru, která označuje, kde příkaz končí, nebo *končí*. Způsob, jakým program končí, se liší podle jazyka.
Příkazy v programu mohou záviset na datech poskytnutých uživatelem nebo z jiného zdroje, aby mohly vykonávat instrukce. Data mohou změnit chování programu, a proto programovací jazyky obsahují způsob, jak data dočasně uložit, aby mohla být použita později. Tyto způsoby se nazývají *proměnné*. Proměnné jsou příkazy, které zařízení instruují, aby uložilo data do své paměti. Proměnné v programech jsou podobné proměnným v algebře, kde mají jedinečný název a jejich hodnota se může časem měnit.
Příkazy v programu mohou záviset na datech poskytnutých uživatelem nebo jiným zdrojem, aby mohly vykonat instrukce. Data mohou změnit chování programu, a proto programovací jazyky obsahují způsob, jak dočasně ukládat data, aby mohla být použita později. Tyto se nazývají *proměnné*. Proměnné jsou příkazy, které zařízení instruují, aby uložilo data do své paměti. Proměnné v programech jsou podobné proměnným v algebře, kde mají jedinečný název a jejich hodnota se může časem měnit.
Existuje možnost, že některé příkazy nebudou zařízením vykonány. To je obvykle záměrné, když je to napsáno vývojářem, nebo náhodné, když dojde k neočekávané chybě. Tento typ kontroly nad aplikací ji činí robustnější a lépe udržovatelnou. Tyto změny v řízení obvykle nastávají, když jsou splněny určité podmínky. Běžným příkazem používaným v moderním programování k řízení běhu programu je příkaz `if..else`.
Existuje možnost, že některé příkazy nebudou zařízením vykonány. To je obvykle záměrně napsáno vývojářem nebo náhodou, když dojde k neočekávané chybě. Tento typ kontroly nad aplikací ji činí robustnější a udržovatelnější. Tyto změny v řízení obvykle nastávají, když jsou splněny určité podmínky. Běžným příkazem používaným v moderním programování k řízení běhu programu je příkaz `if..else`.
✅ O tomto typu příkazu se dozvíte více v následujících lekcích.
@ -103,51 +103,50 @@ Existuje možnost, že některé příkazy nebudou zařízením vykonány. To je
> 🎥 Klikněte na obrázek výše pro video o nástrojích
V této části se dozvíte o některém softwaru, který může být velmi užitečný, když začínáte svou profesionální vývojářskou cestu.
V této části se dozvíte o některém softwaru, který byste mohli považovat za velmi užitečný na začátku své profesionální vývojářské cesty.
**Vývojové prostředí** je jedinečná sada nástrojů a funkcí, které vývojář často používá při psaní softwaru. Některé z těchto nástrojů byly přizpůsobeny specifickým potřebám vývojáře a mohou se časem měnit, pokud vývojář změní priority v práci, osobních projektech nebo při používání jiného programovacího jazyka. Vývojová prostředí jsou tak jedinečná jako vývojáři, kteří je používají.
**Vývojové prostředí** je jedinečná sada nástrojů a funkcí, které vývojář často používá při psaní softwaru. Některé z těchto nástrojů byly přizpůsobeny specifickým potřebám vývojáře a mohou se časem měnit, pokud vývojář změní priority v práci, osobních projektech nebo při používání jiného programovacího jazyka. Vývojová prostředí jsou stejně jedinečná jako vývojáři, kteří je používají.
### Editory
Jedním z nejdůležitějších nástrojů pro vývoj softwaru je editor. Editory jsou místem, kde píšete svůj kód a někdy i spouštíte svůj kód.
Jedním z nejdůležitějších nástrojů pro vývoj softwaru je editor. Editory jsou místem, kde píšete svůj kód a někdy i místem, kde jej spouštíte.
Vývojáři spoléhají na editory z několika dalších důvodů:
- *Ladění* pomáhá odhalit chyby a problémy tím, že prochází kód řádek po řádku. Některé editory mají schopnosti ladění; mohou být přizpůsobeny a přidány pro specifické programovací jazyky.
- *Zvýraznění syntaxe* přidává barvy a formátování textu do kódu, což usnadňuje jeho čtení. Většina editorů umožňuje přizpůsobené zvýraznění syntaxe.
- *Rozšíření a integrace* jsou specializované nástroje pro vývojáře, vytvořené vývojáři. Tyto nástroje nebyly součástí základního editoru. Například mnoho vývojářů dokumentuje svůj kód, aby vysvětlili, jak funguje. Mohou nainstalovat rozšíření pro kontrolu pravopisu, které pomáhá najít překlepy v dokumentaci. Většina rozšíření je určena pro použití v konkrétním editoru a většina editorů má způsob, jak vyhledávat dostupná rozšíření.
- *Přizpůsobení* umožňuje vývojářům vytvořit jedinečné vývojové prostředí, které vyhovuje jejich potřebám. Většina editorů je extrémně přizpůsobitelná a může také umožnit vývojářům vytvářet vlastní rozšíření.
- *Ladění* pomáhá odhalit chyby a problémy tím, že prochází kód řádek po řádku. Některé editory mají schopnosti ladění; mohou být přizpůsobeny a přidány pro specifické programovací jazyky.
- *Zvýraznění syntaxe* přidává barvy a formátování textu do kódu, což usnadňuje jeho čtení. Většina editorů umožňuje přizpůsobené zvýraznění syntaxe.
- *Rozšíření a integrace* jsou specializované nástroje pro vývojáře, vytvořené vývojáři. Tyto nástroje nejsou součástí základního editoru. Například mnoho vývojářů dokumentuje svůj kód, aby vysvětlili, jak funguje. Mohou si nainstalovat rozšíření pro kontrolu pravopisu, které pomáhá najít překlepy v dokumentaci. Většina rozšíření je určena pro použití v konkrétním editoru a většina editorů umožňuje vyhledávání dostupných rozšíření.
- *Přizpůsobení* umožňuje vývojářům vytvořit jedinečné vývojové prostředí, které vyhovuje jejich potřebám. Většina editorů je extrémně přizpůsobitelná a může také umožnit vývojářům vytvářet vlastní rozšíření.
#### Populární editory a rozšíření pro webový vývoj
- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)
Dalším klíčovým nástrojem je prohlížeč. Weboví vývojáři spoléhají na prohlížeč, aby viděli, jak jejich kód běží na webu. Prohlížeč se také používá k zobrazení vizuálních prvků webové stránky, které jsou napsány v editoru, jako je HTML.
Dalším klíčovým nástrojem je prohlížeč. Weboví vývojáři spoléhají na prohlížeč, aby viděli, jak jejich kód běží na webu. Prohlížeč se také používá k zobrazení vizuálních prvků webové stránky napsaných v editoru, jako je HTML.
Mnoho prohlížečů obsahuje *nástroje pro vývojáře* (DevTools), které obsahují sadu užitečných funkcí a informací, jež pomáhají vývojářům shromažďovat a zachytávat důležité informace o jejich aplikaci. Například: Pokud má webová stránka chyby, je někdy užitečné vědět, kdy k nim došlo. DevTools v prohlížeči mohou být nakonfigurovány tak, aby tyto informace zachytily.
Mnoho prohlížečů obsahuje *nástroje pro vývojáře* (DevTools), které obsahují sadu užitečných funkcí a informací, jež pomáhají vývojářům shromažďovat a zachytávat důležité informace o jejich aplikaci. Například: Pokud má webová stránka chyby, je někdy užitečné vědět, kdy k nim došlo. DevTools v prohlížeči lze nakonfigurovat tak, aby tyto informace zachytily.
Někteří vývojáři preferují méně grafické prostředí pro své každodenní úkoly a spoléhají na příkazový řádek. Psaní kódu vyžaduje značné množství psaní a někteří vývojáři preferují nepřerušovat svůj tok na klávesnici. Používají klávesové zkratky pro přepínání mezi okny na ploše, práci na různých souborech a používání nástrojů. Většinu úkolů lze provést myší, ale jednou z výhod příkazového řádku je, že mnoho věcí lze provést bez nutnosti přepínání mezi myší a klávesnicí. Další výhodou příkazového řádku je, že je konfigurovatelný a můžete uložit vlastní konfiguraci, později ji změnit a importovat ji do jiných vývojových strojů. Protože vývojová prostředí jsou tak jedinečná pro každého vývojáře, někteří se příkazovému řádku vyhýbají, někteří na něm zcela spoléhají a někteří preferují kombinaci obojího.
Někteří vývojáři preferují méně grafický pohled na své každodenní úkoly a spoléhají na příkazový řádek. Psaní kódu vyžaduje značné množství psaní a někteří vývojáři preferují nepřerušovat svůj tok na klávesnici. Používají klávesové zkratky pro přepínání mezi okny na ploše, práci na různých souborech a používání nástrojů. Většinu úkolů lze provést pomocí myši, ale jednou z výhod příkazového řádku je, že mnoho věcí lze provést bez nutnosti přepínání mezi myší a klávesnicí. Další výhodou příkazového řádku je, že je konfigurovatelný a můžete uložit vlastní konfiguraci, později ji změnit a importovat do jiných vývojových strojů. Protože vývojová prostředí jsou tak jedinečná pro každého vývojáře, někteří se příkazovému řádku vyhýbají, jiní na něm zcela spoléhají a někteří preferují kombinaci obojího.
### Populární možnosti příkazového řádku
@ -157,28 +156,28 @@ Možnosti příkazového řádku se liší podle operačního systému, který p
- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands/?WT.mc_id=academic-77807-sagibbon) (také známý jako CMD) 💻
- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands/?WT.mc_id=academic-77807-sagibbon) (také známý jako CMD) 💻
- [Web.dev](https://web.dev), od Googlu, vydavatele [Chrome](https://www.google.com/chrome/)
- [Microsoftova vlastní dokumentace pro vývojáře](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), pro [Microsoft Edge](https://www.microsoft.com/edge)
- [Web.dev](https://web.dev), od Googlu, vydavatele [Chrome](https://www.google.com/chrome/)
- [Microsoftova vlastní dokumentace pro vývojáře](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), pro [Microsoft Edge](https://www.microsoft.com/edge)
✅ Udělejte si průzkum: Nyní, když znáte základy prostředí webového vývojáře, porovnejte a kontrastujte je s prostředím webového designéra.
✅ Udělejte si průzkum: Nyní, když znáte základy prostředí webového vývojáře, porovnejte a kontrastujte jej s prostředím webového designéra.
---
## 🚀 Výzva
Porovnejte některé programovací jazyky. Jaké jsou jedinečné vlastnosti JavaScriptu oproti Javě? A co třeba COBOL oproti Go?
Porovnejte některé programovací jazyky. Jaké jsou některé jedinečné vlastnosti JavaScriptu oproti Javě? A co COBOL oproti Go?
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/2)
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/)
## Přehled a samostudium
## Opakování a samostudium
Prostudujte si různé jazyky dostupné pro programátora. Zkuste napsat jeden řádek v jednom jazyce a poté jej přepište do dvou dalších. Co jste se naučili?
Prostudujte si různé jazyky dostupné programátorům. Zkuste napsat jeden řádek v jednom jazyce a poté jej přepište do dvou dalších. Co jste se naučili?
## Zadání
[Čtení dokumentace](assignment.md)
[Čtení dokumentace](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
@ -15,7 +15,7 @@ Tato lekce pokrývá základy GitHubu, platformy pro hostování a správu změn
> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před lekcí
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/3)
[Kvíz před lekcí](https://ff-quizzes.netlify.app)
## Úvod
@ -27,35 +27,35 @@ V této lekci se naučíte:
### Předpoklady
Než začnete, musíte zkontrolovat, zda máte nainstalovaný Git. V terminálu napište:
Než začnete, zkontrolujte, zda máte nainstalovaný Git. V terminálu zadejte:
`git --version`
Pokud Git není nainstalován, [stáhněte Git](https://git-scm.com/downloads). Poté nastavte svůj lokální Git profil v terminálu:
* `git config --global user.name "vaše-jméno"`
* `git config --global user.email "váš-email"`
Pro kontrolu, zda je Git již nakonfigurován, napište:
Pro kontrolu, zda je Git již nakonfigurován, můžete zadat:
`git config --list`
Budete také potřebovat účet na GitHubu, editor kódu (například Visual Studio Code) a otevřený terminál (nebo příkazový řádek).
Budete také potřebovat účet na GitHubu, editor kódu (například Visual Studio Code) a otevřít svůj terminál (nebo příkazový řádek).
Přejděte na [github.com](https://github.com/) a vytvořte si účet, pokud ho ještě nemáte, nebo se přihlaste a vyplňte svůj profil.
Přejděte na [github.com](https://github.com/) a vytvořte si účet, pokud ho ještě nemáte, nebo se přihlaste a vyplňte svůj profil.
✅ GitHub není jediným úložištěm kódu na světě; existují i další, ale GitHub je nejznámější.
### Příprava
Budete potřebovat složku s projektem kódu na svém lokálním počítači (notebooku nebo PC) a veřejné úložiště na GitHubu, které poslouží jako příklad, jak přispívat do projektů ostatních.
Budete potřebovat složku s projektem kódu na svém lokálním počítači (notebooku nebo PC) a veřejné úložiště na GitHubu, které poslouží jako příklad, jak přispívat do projektů ostatních.
---
## Správa kódu
Řekněme, že máte lokální složku s nějakým projektem kódu a chcete začít sledovat svůj pokrok pomocí gitu – systému pro správu verzí. Někteří lidé přirovnávají používání gitu k psaní milostného dopisu svému budoucímu já. Čtením vašich zpráv o commitech po dnech, týdnech nebo měsících si budete schopni vybavit, proč jste udělali určité rozhodnutí, nebo "vrátit zpět" změnu – samozřejmě za předpokladu, že píšete dobré zprávy o commitech.
Představte si, že máte lokální složku s nějakým projektem kódu a chcete začít sledovat svůj pokrok pomocí gitu - systému pro správu verzí. Někteří lidé přirovnávají používání gitu k psaní milostného dopisu svému budoucímu já. Čtením vašich zpráv o commitech po dnech, týdnech nebo měsících si budete schopni vybavit, proč jste udělali určité rozhodnutí, nebo "vrátit zpět" změnu - to vše za předpokladu, že píšete dobré zprávy o commitech.
### Úkol: Vytvořte úložiště a commitujte kód
> Podívejte se na video
> Podívejte se na video
>
> [](https://www.youtube.com/watch?v=9R31OUPpxU4)
@ -64,19 +64,19 @@ Budete potřebovat složku s projektem kódu na svém lokálním počítači (no
1. Dejte svému úložišti (složce) název.
1. Vyberte **create repository**.
1. **Přejděte do své pracovní složky**. V terminálu přepněte do složky (také známé jako adresář), kterou chcete začít sledovat. Napište:
1. **Přejděte do své pracovní složky**. V terminálu přepněte do složky (také známé jako adresář), kterou chcete začít sledovat. Zadejte:
```bash
cd [name of your folder]
```
1. **Inicializujte git úložiště**. Ve svém projektu napište:
1. **Inicializujte git úložiště**. Ve svém projektu zadejte:
```bash
git init
```
1. **Zkontrolujte stav**. Pro kontrolu stavu svého úložiště napište:
1. **Zkontrolujte stav**. Pro kontrolu stavu svého úložiště zadejte:
```bash
git status
@ -93,16 +93,16 @@ Budete potřebovat složku s projektem kódu na svém lokálním počítači (no
modified: file2.txt
```
Typicky příkaz `git status`říká věci jako, které soubory jsou připraveny k _uložení_ do úložiště nebo mají změny, které byste mohli chtít zachovat.
Typicky příkaz `git status`vám řekne například, které soubory jsou připraveny k _uložení_ do úložiště nebo mají změny, které byste mohli chtít zachovat.
1. **Přidejte všechny soubory ke sledování**
1. **Přidejte všechny soubory ke sledování**
Toto se také nazývá staging souborů/přidávání souborů do staging oblasti.
```bash
git add .
```
Argument `git add` plus `.` označuje, že všechny vaše soubory a změny jsou připraveny ke sledování.
Argument `git add` plus `.` označuje, že všechny vaše soubory a změny jsou připraveny ke sledování.
1. **Přidejte vybrané soubory ke sledování**
@ -128,17 +128,17 @@ Budete potřebovat složku s projektem kódu na svém lokálním počítači (no
Tento příkaz nám pomáhá zrušit staging pouze konkrétního souboru najednou, který nechceme zahrnout do dalšího commitu.
1. **Uložte svou práci**. V tomto bodě jste přidali soubory do tzv. _staging oblasti_. Místo, kde Git sleduje vaše soubory. Aby byla změna trvalá, musíte soubory _commitovat_. K tomu vytvoříte _commit_ pomocí příkazu `git commit`. _Commit_ představuje bod uložení v historii vašeho úložiště. Napište následující pro vytvoření _commitu_:
1. **Uložení vaší práce**. V tomto bodě jste přidali soubory do tzv. _staging oblasti_. Místa, kde Git sleduje vaše soubory. Aby byla změna trvalá, musíte _commitnout_ soubory. K tomu vytvoříte _commit_ pomocí příkazu `git commit`. _Commit_ představuje bod uložení v historii vašeho úložiště. Zadejte následující pro vytvoření _commitu_:
```bash
git commit -m "first commit"
```
Tento commit uloží všechny vaše soubory a přidá zprávu "first commit". Pro budoucí zprávy o commitech budete chtít být více popisní, abyste sdělili, jaký typ změny jste provedli.
Tento příkaz commitne všechny vaše soubory a přidá zprávu "first commit". Pro budoucí zprávy o commitech budete chtít být více popisní, abyste sdělili, jaký typ změny jste provedli.
1. **Propojte své lokální Git úložiště s GitHubem**. Git úložiště je dobré na vašem počítači, ale v určitém bodě budete chtít mít zálohu svých souborů někde jinde a také pozvat ostatní, aby s vámi pracovali na vašem úložišti. Jedním z takových skvělých míst je GitHub. Pamatujte, že jsme již vytvořili úložiště na GitHubu, takže jediná věc, kterou musíme udělat, je propojit naše lokální Git úložiště s GitHubem. Příkaz `git remote add` to udělá. Napište následující příkaz:
1. **Propojte své lokální Git úložiště s GitHubem**. Git úložiště je dobré na vašem počítači, ale v určitém bodě budete chtít mít zálohu svých souborů někde jinde a také pozvat ostatní, aby s vámi pracovali na vašem úložišti. Jedním z takových skvělých míst je GitHub. Pamatujte, že jsme již vytvořili úložiště na GitHubu, takže jediná věc, kterou musíme udělat, je propojit naše lokální Git úložiště s GitHubem. Příkaz `git remote add` to udělá. Zadejte následující příkaz:
> Poznámka: Před zadáním příkazu přejděte na stránku svého GitHub úložiště a najděte URL úložiště. Použijete ho v níže uvedeném příkazu. Nahraďte ```https://github.com/username/repository_name.git``` svým GitHub URL.
> Poznámka: Než zadáte příkaz, přejděte na stránku svého GitHub úložiště a najděte URL úložiště. Použijete ho v níže uvedeném příkazu. Nahraďte ```https://github.com/username/repository_name.git``` svým GitHub URL.
@ -146,17 +146,17 @@ Budete potřebovat složku s projektem kódu na svém lokálním počítači (no
Tento příkaz vytvoří _remote_, nebo spojení, nazvané "origin", které ukazuje na GitHub úložiště, které jste vytvořili dříve.
1. **Pošlete lokální soubory na GitHub**. Doposud jste vytvořili _spojení_ mezi lokálním úložištěm a GitHub úložištěm. Pošlete tyto soubory na GitHub pomocí následujícího příkazu `git push`, takto:
1. **Odešlete lokální soubory na GitHub**. Doposud jste vytvořili _spojení_ mezi lokálním úložištěm a GitHub úložištěm. Pošlete tyto soubory na GitHub pomocí následujícího příkazu `git push`, takto:
> Poznámka: Název vaší větve může být ve výchozím nastavení odlišný od ```main```.
```bash
git push -u origin main
```
Tento příkaz pošle vaše commity ve vaší větvi "main" na GitHub.
Tento příkaz odešle vaše commity ve větvi "main" na GitHub.
2. **Přidávejte další změny**. Pokud chcete pokračovat v provádění změn a jejich posílání na GitHub, budete potřebovat pouze následující tři příkazy:
2. **Přidání dalších změn**. Pokud chcete pokračovat v provádění změn a jejich odesílání na GitHub, budete potřebovat použít následující tři příkazy:
```bash
git add .
@ -164,15 +164,15 @@ Budete potřebovat složku s projektem kódu na svém lokálním počítači (no
git push
```
> Tip: Možná budete chtít přijmout soubor `.gitignore`, abyste zabránili tomu, aby se soubory, které nechcete sledovat, objevily na GitHubu – například ten soubor s poznámkami, který ukládáte ve stejné složce, ale nemá místo ve veřejném úložišti. Šablony pro soubory `.gitignore` najdete na [.gitignore templates](https://github.com/github/gitignore).
> Tip: Možná budete chtít přijmout soubor `.gitignore`, abyste zabránili tomu, aby se soubory, které nechcete sledovat, objevily na GitHubu - například ten soubor s poznámkami, který ukládáte ve stejné složce, ale nemá místo ve veřejném úložišti. Šablony pro soubory `.gitignore` najdete na [.gitignore templates](https://github.com/github/gitignore).
#### Zprávy o commitech
Skvělý předmět zprávy o commitu dokončuje následující větu:
Skvělý předmět zprávy o commitu dokončuje následující větu:
Pokud bude aplikováno, tento commit <vášpředmětzde>
Pro předmět použijte imperativní přítomný čas: "změnit" místo "změněno" nebo "změny".
Stejně jako v předmětu, i v těle (volitelném) použijte imperativní přítomný čas. Tělo by mělo zahrnovat motivaci ke změně a kontrastovat to s předchozím chováním. Vysvětlujete `proč`, ne `jak`.
Pro předmět použijte rozkazovací způsob v přítomném čase: "změnit" místo "změněno" nebo "změny".
Stejně jako v předmětu, i v těle (volitelném) použijte rozkazovací způsob v přítomném čase. Tělo by mělo zahrnovat motivaci pro změnu a kontrastovat to s předchozím chováním. Vysvětlujete `proč`, ne `jak`.
✅ Věnujte pár minut prohlížení GitHubu. Najdete opravdu skvělou zprávu o commitu? Najdete opravdu minimalistickou? Jaké informace si myslíte, že jsou nejdůležitější a nejužitečnější pro sdělení ve zprávě o commitu?
@ -182,7 +182,7 @@ Hlavním důvodem pro umístění věcí na GitHub bylo umožnit spolupráci s o
## Práce na projektech s ostatními
> Podívejte se na video
> Podívejte se na video
>
> [](https://www.youtube.com/watch?v=bFCM-PC3cu8)
@ -193,26 +193,26 @@ Ve svém úložišti přejděte na `Insights > Community`, abyste viděli, jak v
- **README**. Přidali jste README? GitHub poskytuje pokyny pro psaní [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
- **Pokyny pro přispívání**. Má váš projekt [pokyny pro přispívání](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)?
- **Kodex chování**. Má váš projekt [Kodex chování](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/)?
- **Licence**. Možná nejdůležitější, má váš projekt [licenci](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
- **Licence**. A možná nejdůležitější, má váš projekt [licenci](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
Všechny tyto zdroje budou přínosem pro onboarding nových členů týmu. A to jsou typicky věci, na které se noví přispěvatelé dívají, než se podívají na váš kód, aby zjistili, zda je váš projekt tím správným místem, kde by měli trávit svůj čas.
Všechny tyto zdroje budou přínosem pro onboarding nových členů týmu. A to jsou typicky věci, na které se noví přispěvatelé dívají, než se vůbec podívají na váš kód, aby zjistili, zda je váš projekt tím správným místem, kde by měli trávit svůj čas.
✅ README soubory, i když jejich příprava zabere čas, jsou často přehlíženy zaneprázdněnými správci. Najdete příklad obzvláště popisného README? Poznámka: existují některé [nástroje pro vytvoření dobrých README](https://www.makeareadme.com/), které byste mohli vyzkoušet.
✅ README soubory, i když jejich příprava zabere čas, jsou často opomíjeny zaneprázdněnými správci. Najdete příklad obzvláště popisného README? Poznámka: existují některé [nástroje pro vytvoření dobrých README](https://www.makeareadme.com/), které byste mohli vyzkoušet.
### Úkol: Sloučte nějaký kód
Dokumenty pro přispívání pomáhají lidem přispívat do projektu. Vysvětlují, jaké typy příspěvků hledáte a jak proces funguje. Přispěvatelé budou muset projít sérií kroků, aby mohli přispět do vašeho úložiště na GitHubu:
1. **Forkování vašeho úložiště**. Pravděpodobně budete chtít, aby lidé _forkovali_ váš projekt. Forkování znamená vytvoření repliky vašeho úložiště na jejich GitHub profilu.
1. **Klonování**. Odtud si projekt naklonují na svůj lokální počítač.
1. **Vytvoření větve**. Budete chtít požádat je, aby vytvořili _větev_ pro svou práci.
1. **Zaměření změny na jednu oblast**. Požádejte přispěvatele, aby se soustředili na jednu věc najednou – tím se zvýší šance, že budete moci jejich práci _sloučit_. Představte si, že opraví chybu, přidají novou funkci a aktualizují několik testů – co když chcete, nebo můžete implementovat pouze 2 ze 3, nebo 1 ze 3 změn?
1. **Klonování**. Odtud si projekt naklonují na svůj lokální počítač.
1. **Vytvoření větve**. Budete chtít požádat je, aby vytvořili _větev_ pro svou práci.
1. **Zaměření změny na jednu oblast**. Požádejte přispěvatele, aby se soustředili na jednu věc najednou - tím se zvýší šance, že budete moci _sloučit_ jejich práci. Představte si, že opraví chybu, přidají novou funkci a aktualizují několik testů - co když chcete, nebo můžete implementovat pouze 2 ze 3, nebo 1 ze 3 změn?
✅ Představte si situaci, kdy jsou větve obzvláště důležité pro psaní a dodávání kvalitního kódu. Jaké případy použití vás napadají?
✅ Představte si situaci, kdy jsou větve obzvláště důležité pro psaní a doručování dobrého kódu. Jaké případy použití vás napadají?
> Poznámka: Buďte změnou, kterou chcete vidět ve světě, a vytvářejte větve i pro svou vlastní práci. Jakékoliv commity, které provedete, budou provedeny na větvi, na kterou jste aktuálně "přepnuti". Použijte `git status`, abyste viděli, na které větvi právě jste.
> Poznámka: Buďte změnou, kterou chcete vidět ve světě, a vytvářejte větve i pro svou vlastní práci. Jakékoliv commity, které provedete, budou provedeny na větvi, na kterou jste aktuálně "přepnuti". Použijte `git status`, abyste viděli, na které větvi se nacházíte.
Pojďme projít workflow přispěvatele. Předpokládejme, že přispěvatel již _forkoval_ a _naklonoval_ úložiště, takže má Git úložiště připravené k práci na svém lokálním počítači:
Pojďme projít workflow přispěvatele. Předpokládejme, že přispěvatel již _forkoval_ a _klonoval_ úložiště, takže má Git úložiště připravené k práci na svém lokálním počítači:
1. **Vytvoření větve**. Použijte příkaz `git branch` k vytvoření větve, která bude obsahovat změny, které chtějí přispět:
@ -251,7 +251,7 @@ Pojďme projít workflow přispěvatele. Předpokládejme, že přispěvatel ji
Tento příkaz přinese všechny změny z `main` do vaší větve a doufejme, že můžete pokračovat. Pokud ne, VS Code vám ukáže, kde je Git _zmatený_, a vy jen upravíte dotčené soubory, abyste určili, který obsah je nejpřesnější.
1. **Pošlete svou práci na GitHub**. Poslání vaší práce na GitHub znamená dvě věci. Pushnutí vaší větve na vaše úložiště a poté otevření PR, Pull Request.
1. **Odeslání vaší práce na GitHub**. Odeslání vaší práce na GitHub znamená dvě věci. Pushnutí vaší větve do vašeho úložiště a poté otevření PR, Pull Request.
```bash
git push --set-upstream origin [branch-name]
@ -259,36 +259,36 @@ Pojďme projít workflow přispěvatele. Předpokládejme, že přispěvatel ji
Výše uvedený příkaz vytvoří větev na vašem forkovaném úložišti.
1. **Otevřete PR**. Dále chcete otevřít PR. Uděláte to tak, že přejdete na forkované úložiště na GitHubu. Uvidíte indikaci na GitHubu, kde se vás zeptá, zda chcete vytvořit nový PR, kliknete na to a budete přesměrováni na rozhraní, kde můžete změnit název zprávy o commitu, dát jí vhodnější popis. Nyní správce úložiště, které jste forkovali, uvidí tento PR a _držte palce_, že ho ocení a _sloučí_ váš PR. Nyní jste přispěvatel, hurá :)
1. **Otevření PR**. Dále chcete otevřít PR. Uděláte to tak, že přejdete na forkované úložiště na GitHubu. Na GitHubu uvidíte indikaci, kde se vás ptá, zda chcete vytvořit nový PR, kliknete na to a budete přesměrováni na rozhraní, kde můžete změnit název zprávy o commitu, dát jí vhodnější popis. Nyní správce úložiště, které jste forkovali, uvidí tento PR a _držte palce_, že ho ocení a _sloučí_ váš PR. Nyní jste přispěvatel, hurá :)
1. **Úklid**. Je považováno za dobrý zvyk _uklidit_ po úspěšném sloučení PR. Chcete uklidit jak svou lokální větev, tak větev, kterou jste pushovali na GitHub. Nejprve ji smažte lokálně pomocí následujícího příkazu:
1. **Úklid**. Je považováno za dobrý zvyk _uklidit_ po úspěšném sloučení PR. Chcete uklidit jak svou lokální větev, tak větev, kterou jste pushnuli na GitHub. Nejprve ji smažte lokálně pomocí následujícího příkazu:
```bash
git branch -d [branch-name]
```
Ujistěte se, že přejdete na stránku GitHub pro forknuté repo a odstraníte vzdálenou větev, kterou jste právě do něj nahráli.
`Pull request` se může zdát jako zvláštní termín, protože ve skutečnosti chcete své změny "pushnout" do projektu. Ale správce (vlastník projektu) nebo hlavní tým musí zvážit vaše změny, než je sloučí s "hlavní" větví projektu, takže ve skutečnosti žádáte správce o rozhodnutí ohledně změny.
Ujistěte se, že přejdete na stránku GitHubu pro forkované úložiště a odstraníte vzdálenou větev, kterou jste právě pushnuli.
`Pull request` se může zdát jako zvláštní termín, protože ve skutečnosti chcete své změny "pushnout" do projektu. Ale správce (vlastník projektu) nebo hlavní tým musí vaše změny zvážit, než je sloučí s "hlavní" větví projektu, takže ve skutečnosti žádáte správce o rozhodnutí ohledně změny.
Pull request je místo, kde můžete porovnávat a diskutovat rozdíly zavedené na větvi pomocí recenzí, komentářů, integrovaných testů a dalších nástrojů. Dobrý pull request se řídí přibližně stejnými pravidly jako zpráva o commitu. Můžete přidat odkaz na problém v trackeru problémů, například když vaše práce řeší nějaký problém. To se provádí pomocí `#` následovaného číslem vašeho problému. Například `#97`.
Pull request je místo, kde můžete porovnávat a diskutovat o rozdílech zavedených na větvi pomocí recenzí, komentářů, integrovaných testů a dalších nástrojů. Dobrý pull request se řídí přibližně stejnými pravidly jako zpráva o commitu. Můžete přidat odkaz na problém v issue trackeru, například když vaše práce řeší nějaký problém. To se provádí pomocí `#` následovaného číslem problému. Například `#97`.
🤞Držte palce, aby všechny kontroly prošly a vlastník(y) projektu sloučili vaše změny do projektu🤞
🤞Držte palce, aby všechny kontroly prošly a vlastník(y) projektu vaše změny sloučili do projektu🤞
Aktualizujte svou aktuální lokální pracovní větev všemi novými commity z odpovídající vzdálené větve na GitHubu:
Aktualizujte svou aktuální lokální pracovní větev o všechny nové commity z odpovídající vzdálené větve na GitHubu:
`git pull`
## Jak přispět do open source
Nejprve najděte na GitHubu repozitář (nebo **repo**), který vás zajímá a do kterého byste chtěli přispět změnou. Budete chtít zkopírovat jeho obsah na svůj počítač.
Nejprve si najděte na GitHubu repozitář (nebo **repo**), který vás zajímá a do kterého byste chtěli přispět změnou. Budete chtít zkopírovat jeho obsah na svůj počítač.
✅ Dobrým způsobem, jak najít repozitáře vhodné pro začátečníky, je [vyhledávání podle tagu 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/).
Existuje několik způsobů, jak zkopírovat kód. Jedním ze způsobů je "klonování" obsahu repozitáře pomocí HTTPS, SSH nebo GitHub CLI (Command Line Interface).
Existuje několik způsobů, jak zkopírovat kód. Jedním z nich je "klonování" obsahu repozitáře pomocí HTTPS, SSH nebo GitHub CLI (Command Line Interface).
Otevřete svůj terminál a klonujte repozitář takto:
Otevřete terminál a klonujte repozitář takto:
`git clone https://github.com/ProjectURL`
Pro práci na projektu přepněte do správné složky:
@ -296,44 +296,44 @@ Pro práci na projektu přepněte do správné složky:
Celý projekt můžete také otevřít pomocí [Codespaces](https://github.com/features/codespaces), integrovaného editoru kódu / cloudového vývojového prostředí GitHubu, nebo [GitHub Desktop](https://desktop.github.com/).
Nakonec můžete kód stáhnout ve formě zipovaného souboru.
Nakonec si můžete kód stáhnout v zazipované složce.
### Několik dalších zajímavých věcí o GitHubu
### Několik dalších zajímavostí o GitHubu
Na GitHubu můžete "hvězdičkovat", sledovat nebo "forkovat" jakýkoli veřejný repozitář. Své hvězdičkované repozitáře najdete v rozbalovací nabídce v pravém horním rohu. Je to jako záložky, ale pro kód.
Na GitHubu můžete "označit hvězdičkou", sledovat nebo "forknout" jakýkoli veřejný repozitář. Své označené repozitáře najdete v rozbalovací nabídce v pravém horním rohu. Je to jako záložky, ale pro kód.
Projekty mají tracker problémů, většinou na GitHubu v záložce "Issues", pokud není uvedeno jinak, kde lidé diskutují o problémech souvisejících s projektem. A záložka Pull Requests je místem, kde lidé diskutují a recenzují změny, které jsou v procesu.
Projekty mají issue tracker, většinou na GitHubu v záložce "Issues", pokud není uvedeno jinak, kde lidé diskutují o problémech souvisejících s projektem. A záložka Pull Requests je místem, kde lidé diskutují a recenzují změny, které jsou v procesu.
Projekty mohou mít také diskuse ve fórech, mailing listech nebo chatovacích kanálech jako Slack, Discord nebo IRC.
✅ Prozkoumejte svůj nový GitHub repozitář a vyzkoušejte několik věcí, jako je úprava nastavení, přidání informací do repozitáře a vytvoření projektu (například Kanban board). Je toho hodně, co můžete dělat!
✅ Prozkoumejte svůj nový GitHub repozitář a vyzkoušejte si pár věcí, jako je úprava nastavení, přidání informací do repozitáře a vytvoření projektu (například Kanban boardu). Možností je spousta!
---
## 🚀 Výzva
Spojte se s kamarádem a pracujte na kódu toho druhého. Vytvořte projekt společně, forkněte kód, vytvořte větve a sloučte změny.
Spárujte se s kamarádem a pracujte na kódu toho druhého. Vytvořte projekt společně, forkněte kód, vytvořte větve a sloučte změny.
## Kvíz po přednášce
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/4)
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/en/)
## Přehled & Samostudium
## Recenze a samostudium
Přečtěte si více o [přispívání do open source softwaru](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution).
Procvičujte, procvičujte, procvičujte. GitHub má skvělé vzdělávací cesty dostupné na [skills.github.com](https://skills.github.com):
Cvičte, cvičte, cvičte. GitHub nabízí skvělé vzdělávací cesty prostřednictvím [skills.github.com](https://skills.github.com):
- [První týden na GitHubu](https://skills.github.com/#first-week-on-github)
Najdete zde také pokročilejší kurzy.
Najdete tam i pokročilejší kurzy.
## Úkol
## Zadání
Dokončete [kurz První týden na GitHubu](https://skills.github.com/#first-week-on-github)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.


> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před lekcí
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/5)
## Kvíz před lekcí
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/)
> Síla webu spočívá v jeho univerzálnosti. Přístup pro každého, bez ohledu na postižení, je zásadní aspekt.
>
> \- Sir Timothy Berners-Lee, ředitel W3C a vynálezce World Wide Webu
> Síla webu spočívá v jeho univerzálnosti. Přístup pro všechny, bez ohledu na postižení, je zásadní aspekt.
>
> \- Sir Timothy Berners-Lee, ředitel W3C a vynálezce World Wide Webu
Tento citát dokonale zdůrazňuje důležitost vytváření přístupných webových stránek. Aplikace, která není přístupná všem, je ze své podstaty vylučující. Jako weboví vývojáři bychom měli mít přístupnost vždy na paměti. Pokud se na ni zaměříte již od začátku, budete na dobré cestě k tomu, aby vaše stránky byly přístupné pro všechny. V této lekci se naučíte, jaké nástroje vám mohou pomoci zajistit přístupnost vašich webových prostředků a jak přístupnost zohlednit při vývoji.
Tento citát dokonale zdůrazňuje důležitost vytváření přístupných webových stránek. Aplikace, která není přístupná všem, je ze své podstaty vylučující. Jako weboví vývojáři bychom měli mít přístupnost vždy na paměti. Pokud se na ni zaměříte od začátku, budete na dobré cestě k tomu, aby vaše stránky byly přístupné pro všechny. V této lekci se naučíte, jaké nástroje vám mohou pomoci zajistit přístupnost vašich webových prostředků a jak stavět s ohledem na přístupnost.
> Tuto lekci si můžete projít na [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)!
## Nástroje, které můžete použít
## Nástroje k použití
### Čtečky obrazovky
Jedním z nejznámějších nástrojů pro přístupnost jsou čtečky obrazovky.
[Čtečky obrazovky](https://en.wikipedia.org/wiki/Screen_reader) jsou běžně používané klienty pro osoby se zrakovým postižením. Stejně jako se snažíme zajistit, aby prohlížeč správně zobrazoval informace, které chceme sdílet, musíme také zajistit, aby čtečka obrazovky dělala totéž.
[Čtečky obrazovky](https://en.wikipedia.org/wiki/Screen_reader) jsou běžně používané klienty pro osoby se zrakovým postižením. Stejně jako věnujeme čas tomu, aby prohlížeč správně zobrazoval informace, které chceme sdílet, musíme zajistit, aby čtečka obrazovky dělala totéž.
V nejzákladnější podobě čtečka obrazovky čte stránku odshora dolů nahlas. Pokud je vaše stránka pouze textová, čtečka předá informace podobně jako prohlížeč. Webové stránky však zřídka obsahují pouze text; obvykle obsahují odkazy, grafiku, barvy a další vizuální prvky. Je třeba dbát na to, aby čtečka obrazovky tyto informace správně interpretovala.
V základní podobě čtečka obrazovky přečte stránku odshora dolů nahlas. Pokud je vaše stránka pouze textová, čtečka předá informace podobně jako prohlížeč. Webové stránky však zřídka obsahují pouze text; obsahují odkazy, grafiku, barvy a další vizuální prvky. Je třeba dbát na to, aby tyto informace byly čtečkou obrazovky správně přečteny.
Každý webový vývojář by se měl seznámit s čtečkou obrazovky. Jak bylo uvedeno výše, je to klient, který vaši uživatelé budou používat. Stejně jako znáte fungování prohlížeče, měli byste se naučit, jak funguje čtečka obrazovky. Naštěstí jsou čtečky obrazovky součástí většiny operačních systémů.
Některé prohlížeče mají také vestavěné nástroje a rozšíření, která dokážou číst text nahlas nebo poskytovat základní navigační funkce, například [tyto nástroje zaměřené na přístupnost v prohlížeči Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Tyto nástroje jsou také důležité, ale fungují velmi odlišně od čteček obrazovky a neměly by být zaměňovány za nástroje pro testování čteček obrazovky.
Některé prohlížeče mají také vestavěné nástroje a rozšíření, které dokážou číst text nahlas nebo poskytovat základní navigační funkce, například [tyto nástroje zaměřené na přístupnost v prohlížeči Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Tyto nástroje jsou také důležité pro přístupnost, ale fungují velmi odlišně od čteček obrazovky a neměly by být zaměňovány za nástroje pro testování čteček obrazovky.
✅ Vyzkoušejte čtečku obrazovky a čtečku textu v prohlížeči. Ve Windows je standardně zahrnuta [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon), dále lze nainstalovat [JAWS](https://webaim.org/articles/jaws/) a [NVDA](https://www.nvaccess.org/about-nvda/). Na macOS a iOS je standardně nainstalován [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10).
✅ Vyzkoušejte čtečku obrazovky a čtečku textu v prohlížeči. Ve Windows je standardně zahrnuta [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon), a také lze nainstalovat [JAWS](https://webaim.org/articles/jaws/) a [NVDA](https://www.nvaccess.org/about-nvda/). Na macOS a iOS je standardně nainstalován [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10).
### Přiblížení (Zoom)
### Zoom
Dalším nástrojem, který běžně používají lidé se zrakovým postižením, je přiblížení. Nejzákladnější typ přiblížení je statický zoom, ovládaný pomocí `Control + znaménko plus (+)` nebo snížením rozlišení obrazovky. Tento typ přiblížení zvětší celou stránku, takže použití [responsivního designu](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) je důležité pro zajištění dobrého uživatelského zážitku při vyšších úrovních přiblížení.
Dalším nástrojem, který běžně používají lidé se zrakovým postižením, je přiblížení. Nejzákladnější typ přiblížení je statické přiblížení, ovládané pomocí `Control + plus (+)` nebo snížením rozlišení obrazovky. Tento typ přiblížení způsobí, že se celá stránka zvětší, takže použití [responsivního designu](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) je důležité pro zajištění dobrého uživatelského zážitku při zvýšených úrovních přiblížení.
Další typ přiblížení spoléhá na specializovaný software, který zvětšuje jednu oblast obrazovky a posouvá ji, podobně jako při použití skutečné lupy. Ve Windows je vestavěný [Lupa](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198), zatímco [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) je software třetí strany s více funkcemi a širší uživatelskou základnou. Na macOS a iOS je vestavěný software pro zvětšení obrazovky nazvaný [Zoom](https://www.apple.com/accessibility/mac/vision/).
Další typ přiblížení spoléhá na specializovaný software, který zvětší jednu oblast obrazovky a posouvá ji, podobně jako při použití skutečné lupy. Ve Windows je vestavěný [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198), a [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) je software třetí strany s více funkcemi a větší uživatelskou základnou. Na macOS a iOS je vestavěný software pro zvětšení obrazovky nazvaný [Zoom](https://www.apple.com/accessibility/mac/vision/).
### Kontrola kontrastu
Barvy na webových stránkách je třeba pečlivě vybírat, aby vyhovovaly potřebám uživatelů s barvoslepostí nebo osob, které mají potíže s viděním barev s nízkým kontrastem.
Barvy na webových stránkách je třeba pečlivě vybírat, aby vyhovovaly potřebám uživatelů s barvoslepostí nebo lidí, kteří mají potíže s viděním barev s nízkým kontrastem.
✅ Otestujte oblíbenou webovou stránku na použití barev pomocí rozšíření prohlížeče, například [kontroloru kontrastu WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Co jste zjistili?
✅ Otestujte webovou stránku, kterou rádi používáte, z hlediska použití barev pomocí rozšíření prohlížeče, například [kontrolu kontrastu barev WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Co jste zjistili?
### Lighthouse
V oblasti vývojářských nástrojů vašeho prohlížeče najdete nástroj Lighthouse. Tento nástroj je důležitý pro získání prvního pohledu na přístupnost (a další analýzy) webové stránky. I když není vhodné spoléhat se výhradně na Lighthouse, skóre 100 % je velmi užitečné jako základní ukazatel.
V oblasti nástrojů pro vývojáře vašeho prohlížeče najdete nástroj Lighthouse. Tento nástroj je důležitý pro získání prvního pohledu na přístupnost (stejně jako na další analýzy) webové stránky. I když je důležité nespoléhat se výhradně na Lighthouse, skóre 100 % je velmi užitečné jako základní měřítko.
✅ Najděte Lighthouse v panelu vývojářských nástrojů vašeho prohlížeče a spusťte analýzu na libovolné stránce. Co jste zjistili?
✅ Najděte Lighthouse v panelu nástrojů pro vývojáře vašeho prohlížeče a proveďte analýzu libovolné stránky. Co jste zjistili?
## Navrhování pro přístupnost
Přístupnost je poměrně rozsáhlé téma. Naštěstí existuje mnoho zdrojů, které vám mohou pomoci.
Přístupnost je poměrně rozsáhlé téma. Aby vám to usnadnilo, existuje řada dostupných zdrojů.
- [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers)
I když nebudeme schopni pokrýt všechny aspekty vytváření přístupných stránek, níže jsou uvedeny některé základní principy, které byste měli implementovat. Navrhování přístupné stránky od začátku je **vždy** jednodušší než zpětné úpravy existující stránky.
I když nebudeme schopni pokrýt všechny aspekty vytváření přístupných stránek, níže jsou uvedeny některé základní principy, které byste měli implementovat. Navrhování přístupné stránky od začátku je **vždy** jednodušší než zpětné úpravy existující stránky, aby byla přístupná.
## Zásady dobrého zobrazení
## Dobré principy zobrazení
### Bezpečné barevné palety
Lidé vidí svět různými způsoby, což zahrnuje i barvy. Při výběru barevného schématu pro váš web byste měli zajistit, že bude přístupné pro všechny. Skvělým [nástrojem pro generování barevných palet je Color Safe](http://colorsafe.co/).
✅ Najděte webovou stránku, která má velké problémy s použitím barev. Proč?
✅ Identifikujte webovou stránku, která je velmi problematická ve svém použití barev. Proč?
### Používejte správné HTML
Pomocí CSS a JavaScriptu je možné vytvořit jakýkoli prvek, který vypadá jako jakýkoli typ ovládacího prvku. `<span>` by mohl být použit k vytvoření `<button>` a `<b>` by se mohl stát hypertextovým odkazem. I když to může být považováno za jednodušší pro stylování, čtečce obrazovky to nic neřekne. Používejte správné HTML při vytváření ovládacích prvků na stránce. Pokud chcete hypertextový odkaz, použijte `<a>`. Používání správného HTML pro správný ovládací prvek se nazývá využívání sémantického HTML.
Pomocí CSS a JavaScriptu je možné vytvořit jakýkoli prvek, který vypadá jako jakýkoli typ ovládacího prvku. `<span>` by mohl být použit k vytvoření `<button>` a `<b>` by se mohl stát hypertextovým odkazem. I když by to mohlo být považováno za jednodušší pro stylování, čtečce obrazovky to nic neříká. Používejte vhodné HTML při vytváření ovládacích prvků na stránce. Pokud chcete hypertextový odkaz, použijte `<a>`. Používání správného HTML pro správný ovládací prvek se nazývá využívání sémantického HTML.
✅ Navštivte libovolnou webovou stránku a zjistěte, zda designéři a vývojáři používají HTML správně. Najdete tlačítko, které by mělo být odkazem? Tip: Klikněte pravým tlačítkem a vyberte 'Zobrazit zdroj stránky' ve vašem prohlížeči, abyste se podívali na základní kód.
✅ Navštivte libovolnou webovou stránku a zjistěte, zda návrháři a vývojáři používají HTML správně. Najdete tlačítko, které by mělo být odkazem? Tip: klikněte pravým tlačítkem a vyberte 'Zobrazit zdroj stránky' ve vašem prohlížeči, abyste se podívali na základní kód.
### Vytvořte popisnou hierarchii nadpisů
Uživatelé čteček obrazovky [se silně spoléhají na nadpisy](https://webaim.org/projects/screenreadersurvey8/#finding) při hledání informací a navigaci na stránce. Psaní popisného obsahu nadpisů a používání sémantických značek nadpisů je důležité pro vytvoření snadno navigovatelné stránky pro uživatele čteček obrazovky.
Uživatelé čteček obrazovky [silně spoléhají na nadpisy](https://webaim.org/projects/screenreadersurvey8/#finding) při hledání informací a navigaci na stránce. Psát popisný obsah nadpisů a používat sémantické značky nadpisů je důležité pro vytvoření snadno navigovatelné stránky pro uživatele čteček obrazovky.
### Používejte dobré vizuální nápovědy
### Používejte dobré vizuální vodítka
CSS nabízí úplnou kontrolu nad vzhledem jakéhokoli prvku na stránce. Můžete vytvořit textová pole bez obrysu nebo hypertextové odkazy bez podtržení. Bohužel odstranění těchto nápověd může ztížit rozpoznání typu ovládacího prvku pro někoho, kdo na nich závisí.
CSS nabízí úplnou kontrolu nad vzhledem jakéhokoli prvku na stránce. Můžete vytvořit textové pole bez obrysu nebo hypertextové odkazy bez podtržení. Bohužel odstranění těchto vodítek může ztížit rozpoznání typu ovládacího prvku pro někoho, kdo na nich závisí.
## Důležitost textu odkazů
@ -93,19 +93,19 @@ Hypertextové odkazy jsou klíčové pro navigaci na webu. Proto je důležité
### Čtečky obrazovky a odkazy
Jak byste očekávali, čtečky obrazovky čtou text odkazů stejným způsobem jako jakýkoli jiný text na stránce. S tímto na paměti se může zdát, že níže uvedený text je zcela přijatelný.
Jak byste očekávali, čtečky obrazovky čtou text odkazů stejným způsobem, jakým čtou jakýkoli jiný text na stránce. S tímto na paměti se může zdát, že níže uvedený text je zcela přijatelný.
> Malý tučňák, někdy známý jako pohádkový tučňák, je nejmenší tučňák na světě. [Klikněte zde](https://en.wikipedia.org/wiki/Little_penguin) pro více informací.
> Malý tučňák, někdy známý jako pohádkový tučňák, je nejmenší tučňák na světě. Navštivte https://en.wikipedia.org/wiki/Little_penguin pro více informací.
> **NOTE** Jak se brzy dozvíte, nikdy byste neměli vytvářet odkazy, které vypadají jako výše uvedené.
> **NOTE** Jak se chystáte číst, nikdy byste neměli vytvářet odkazy, které vypadají jako výše uvedené.
Pamatujte, že čtečky obrazovky jsou jiné rozhraní než prohlížeče a mají jinou sadu funkcí.
Pamatujte, že čtečky obrazovky jsou jiné rozhraní než prohlížeče s jinou sadou funkcí.
### Problém s použitím URL
Čtečky obrazovky čtou text. Pokud se v textu objeví URL, čtečka obrazovky přečte URL. Obecně řečeno, URL nepředává smysluplné informace a může znít nepříjemně. Možná jste to zažili, pokud vám telefon někdy nahlas přečetl textovou zprávu s URL.
Čtečky obrazovky čtou text. Pokud se v textu objeví URL, čtečka obrazovky přečte URL. Obecně řečeno, URL nepředává smysluplné informace a může znít nepříjemně. Možná jste to zažili, pokud váš telefon někdy nahlas přečetl textovou zprávu s URL.
### Problém s "klikněte zde"
@ -113,7 +113,7 @@ Pamatujte, že čtečky obrazovky jsou jiné rozhraní než prohlížeče a maj
### Dobrý text odkazu
Dobrý text odkazu stručně popisuje, co je na druhé straně odkazu. V uvedeném příkladu o malých tučňácích odkazuje odkaz na stránku Wikipedie o tomto druhu. Fráze *malý tučňák* by byla ideálním textem odkazu, protože jasně říká, co se uživatel dozví, pokud na odkaz klikne - malý tučňák.
Dobrý text odkazu stručně popisuje, co je na druhé straně odkazu. V výše uvedeném příkladu o malých tučňácích odkazuje odkaz na stránku Wikipedie o druhu. Fráze *malý tučňák* by byla ideálním textem odkazu, protože jasně říká, co se někdo dozví, pokud klikne na odkaz - malý tučňák.
> [Malý tučňák](https://en.wikipedia.org/wiki/Little_penguin), někdy známý jako pohádkový tučňák, je nejmenší tučňák na světě.
@ -121,30 +121,30 @@ Dobrý text odkazu stručně popisuje, co je na druhé straně odkazu. V uveden
#### Poznámky k vyhledávačům
Jako bonus za zajištění přístupnosti vašeho webu pomůžete také vyhledávačům navigovat na vašem webu. Vyhledávače používají text odkazů k pochopení témat stránek. Používání dobrého textu odkazů tedy pomáhá všem!
Jako další bonus za zajištění přístupnosti vašeho webu pomůžete vyhledávačům navigovat na vašem webu. Vyhledávače používají text odkazů k tomu, aby se dozvěděly témata stránek. Používání dobrého textu odkazů tedy pomáhá všem!
| Super widget | [Popis](../../../../1-getting-started-lessons/3-accessibility/') | [Objednávka](../../../../1-getting-started-lessons/3-accessibility/') |
V tomto příkladu dává smysl duplikovat text "popis" a "objednat" pro někoho, kdo používá prohlížeč. Uživatel čtečky obrazovky by však slyšel pouze slova *popis* a *objednat* opakovaně bez kontextu.
V tomto příkladu dává smysl duplikovat text popisu a objednávky pro někoho, kdo používá prohlížeč. Nicméně někdo, kdo používá čtečku obrazovky, by slyšel pouze slova *popis* a *objednávka* opakovaně bez kontextu.
Pro podporu těchto scénářů HTML podporuje sadu atributů známých jako [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Tyto atributy umožňují poskytovat čtečkám obrazovky další informace.
Pro podporu těchto typů scénářů HTML podporuje sadu atributů známých jako [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Tyto atributy umožňují poskytovat další informace čtečkám obrazovky.
> **NOTE**: Stejně jako u mnoha aspektů HTML se podpora prohlížečů a čteček obrazovky může lišit. Většina hlavních klientů však atributy ARIA podporuje.
> **NOTE**: Stejně jako u mnoha aspektů HTML se podpora prohlížečů a čteček obrazovky může lišit. Nicméně většina hlavních klientů podporuje atributy ARIA.
Pomocí `aria-label` můžete popsat odkaz, když formát stránky neumožňuje jinak. Popis pro widget by mohl být nastaven jako:
Můžete použít `aria-label` k popisu odkazu, když formát stránky neumožňuje. Popis pro widget by mohl být nastaven jako
✅ Obecně platí, že používání sémantického označení, jak bylo popsáno výše, má přednost před použitím ARIA, ale někdy neexistuje sémantický ekvivalent pro různé HTML widgety. Dobrým příkladem je stromová struktura. Pro tento prvek neexistuje HTML ekvivalent, takže generický `<div>` označíte správnou rolí a hodnotami ARIA. [Dokumentace MDN o ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) obsahuje další užitečné informace.
✅ Obecně platí, že používání sémantického označení, jak je popsáno výše, má přednost před použitím ARIA, ale někdy neexistuje sémantický ekvivalent pro různé HTML widgety. Dobrým příkladem je strom. Neexistuje HTML ekvivalent pro strom, takže identifikujete generický `<div>` pro tento prvek s vhodnou rolí a hodnotami ARIA. [Dokumentace MDN o ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) obsahuje další užitečné informace.
```html
<h2id="tree-label">File Viewer</h2>
@ -155,29 +155,28 @@ Pomocí `aria-label` můžete popsat odkaz, když formát stránky neumožňuje
## Obrázky
Je samozřejmé, že čtečky obrazovky nemohou automaticky přečíst, co je na obrázku. Zajištění přístupnosti obrázků nevyžaduje mnoho práce - právě k tomu slouží atribut `alt`. Všechny smysluplné obrázky by měly mít atribut `alt`, který popisuje, co představují.
Obrázky, které jsou čistě dekorativní, by měly mít atribut `alt` nastavený na prázdný řetězec: `alt=""`. Tím se zabrání tomu, aby čtečky obrazovky zbytečně oznamovaly dekorativní obrázek.
Je samozřejmé, že čtečky obrazovky nejsou schopny automaticky přečíst, co je na obrázku. Zajištění přístupnosti obrázků nevyžaduje mnoho práce - právě k tomu slouží atribut `alt`. Všechny smysluplné obrázky by měly mít `alt`, který popisuje, co představují. Obrázky, které jsou čistě dekorativní, by měly mít atribut `alt` nastavený na prázdný řetězec: `alt=""`. Tím se zabrání tomu, aby čtečky obrazovky zbytečně oznamovaly dekorativní obrázek.
✅ Jak byste očekávali, vyhledávače také nemohou pochopit, co je na obrázku. Používají také text alt. Takže opět, zajištění přístupnosti vaší stránky přináší další výhody!
✅ Jak byste očekávali, vyhledávače také nejsou schopny pochopit, co je na obrázku. Používají také text alt. Takže opět, zajištění přístupnosti vaší stránky přináší další výhody!
## Klávesnice
Někteří uživatelé nemohou používat myš nebo trackpad a spoléhají se na interakce pomocí klávesnice, aby se mohli pohybovat mezi jednotlivými prvky. Je důležité, aby váš web prezentoval obsah v logickém pořadí, aby uživatel klávesnice mohl přistupovat ke každému interaktivnímu prvku při pohybu dolů dokumentem. Pokud vytváříte své webové stránky s použitím sémantického označení a používáte CSS k úpravě jejich vizuálního rozvržení, váš web by měl být navigovatelný pomocí klávesnice, ale je důležité tento aspekt manuálně otestovat. Další informace o [strategiích navigace pomocí klávesnice](https://webaim.org/techniques/keyboard/).
Někteří uživatelé nejsou schopni používat myš nebo trackpad, místo toho spoléhají na interakce pomocí klávesnice, aby přecházeli z jednoho prvku na druhý. Je důležité, aby váš web prezentoval obsah v logickém pořadí, aby uživatel klávesnice mohl přistupovat ke každému interaktivnímu prvku při pohybu dolů dokumentem. Pokud vytváříte své webové stránky pomocí sémantického označení a používáte CSS k stylování jejich vizuálního rozložení, váš web by měl být navigovatelný pomocí klávesnice, ale je důležité tuto vlastnost manuálně otestovat. Další informace o [strategiích navigace pomocí klávesnice](https://webaim.org/techniques/keyboard/).
✅ Navštivte libovolnou webovou stránku a zkuste ji procházet pouze pomocí klávesnice. Co funguje, co nefunguje? Proč?
✅ Navštivte libovolnou webovou stránku a zkuste ji navigovat pouze pomocí klávesnice. Co funguje, co nefunguje? Proč?
## Shrnutí
Web přístupný pouze některým není skutečně "celosvětový web". Nejlepší způsob, jak zajistit, že vámi vytvořené stránky budou přístupné, je začlenit osvědčené postupy přístupnosti již od začátku. I když to vyžaduje další kroky, začlenění těchto dovedností do vaše
Mnoho vlád má zákony týkající se požadavků na přístupnost. Přečtěte si o zákonech o přístupnosti ve vaší zemi. Co je zahrnuto a co není? Příkladem může být [tato vládní webová stránka](https://accessibility.blog.gov.uk/).
Web přístupný pouze některým není skutečně "celosvětový web". Nejlepší způsob, jak zajistit, že vámi vytvořené stránky budou přístupné, je začlenit osvědčené postupy přístupnosti od samého začátku. I když to zahrnuje další kro
Mnoho vlád má zákony týkající se požadavků na přístupnost. Zjistěte si více o zákonech týkajících se přístupnosti ve vaší zemi. Co je zahrnuto a co není? Příkladem je [tento vládní web](https://accessibility.blog.gov.uk/).
## Zadání
[Analyzujte nepřístupný web](assignment.md)
## Úkol
[Analyzujte webovou stránku, která není přístupná](assignment.md)
Poděkování: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) od Instrument
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před lekcí
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/7)
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/)
Tato lekce pokrývá základy JavaScriptu, jazyka, který zajišťuje interaktivitu na webu.
Tato lekce pokrývá základy JavaScriptu, jazyka, který přidává interaktivitu na web.
> Tuto lekci si můžete projít na [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)!
@ -29,13 +29,13 @@ Začněme s proměnnými a datovými typy, které je naplňují!
## Proměnné
Proměnné uchovávají hodnoty, které lze používat a měnit v průběhu vašeho kódu.
Proměnné ukládají hodnoty, které lze používat a měnit v průběhu vašeho kódu.
Vytvoření a **deklarace** proměnné má následující syntaxi **[klíčové slovo] [název]**. Skládá se ze dvou částí:
- **Klíčové slovo**. Klíčová slova mohou být `let` nebo `var`.
✅ Klíčové slovo `let` bylo zavedeno v ES6 a poskytuje proměnné tzv. _blokový rozsah_. Doporučuje se používat `let` místo `var`. Blokové rozsahy probereme podrobněji v dalších částech.
✅ Klíčové slovo `let` bylo představeno v ES6 a dává vaší proměnné tzv. _blokový rozsah_. Doporučuje se používat `let` místo `var`. Blokové rozsahy probereme podrobněji v dalších částech.
- **Název proměnné**, což je název, který si sami zvolíte.
### Úkol - práce s proměnnými
@ -72,13 +72,13 @@ Vytvoření a **deklarace** proměnné má následující syntaxi **[klíčové
myVariable = 321;
```
Jakmile je proměnná deklarována, můžete její hodnotu kdykoli změnit ve svém kódu pomocí operátoru `=` a nové hodnoty.
Jakmile je proměnná deklarována, můžete její hodnotu kdykoli ve svém kódu změnit pomocí operátoru `=` a nové hodnoty.
✅ Vyzkoušejte to! Můžete psát JavaScript přímo ve svém prohlížeči. Otevřete okno prohlížeče a přejděte do Nástrojů pro vývojáře. V konzoli najdete výzvu; napište `let myVariable = 123`, stiskněte Enter, poté napište `myVariable`. Co se stane? Poznámka: o těchto konceptech se dozvíte více v následujících lekcích.
✅ Vyzkoušejte to! Můžete psát JavaScript přímo ve svém prohlížeči. Otevřete okno prohlížeče a přejděte do Nástrojů pro vývojáře. V konzoli najdete výzvu; napište `let myVariable = 123`, stiskněte Enter a poté napište `myVariable`. Co se stane? Poznámka: o těchto konceptech se dozvíte více v následujících lekcích.
## Konstanty
Deklarace a inicializace konstanty se řídí stejnými principy jako u proměnné, s výjimkou klíčového slova `const`. Konstanty se obvykle deklarují velkými písmeny.
Deklarace a inicializace konstanty se řídí stejnými principy jako u proměnných, s výjimkou klíčového slova `const`. Konstanty se obvykle deklarují velkými písmeny.
```javascript
const MY_VARIABLE = 123;
@ -87,7 +87,7 @@ const MY_VARIABLE = 123;
Konstanty jsou podobné proměnným, s dvěma výjimkami:
- **Musí mít hodnotu**. Konstanty musí být inicializovány, jinak při spuštění kódu dojde k chybě.
- **Referenci nelze změnit**. Referenci konstanty nelze po inicializaci změnit, jinak při spuštění kódu dojde k chybě. Podívejme se na dva příklady:
- **Odkaz nelze změnit**. Odkaz konstanty nelze po inicializaci změnit, jinak při spuštění kódu dojde k chybě. Podívejme se na dva příklady:
- **Jednoduchá hodnota**. Následující NENÍ povoleno:
```javascript
@ -95,7 +95,7 @@ Konstanty jsou podobné proměnným, s dvěma výjimkami:
PI = 4; // not allowed
```
- **Reference objektu je chráněna**. Následující NENÍ povoleno.
- **Odkaz na objekt je chráněn**. Následující NENÍ povoleno.
```javascript
const obj = { a: 3 };
@ -109,15 +109,15 @@ Konstanty jsou podobné proměnným, s dvěma výjimkami:
obj.a = 5; // allowed
```
Výše měníte hodnotu objektu, ale ne samotnou referenci, což je povoleno.
Výše měníte hodnotu objektu, ale ne samotný odkaz, což je povoleno.
> Poznámka: `const` znamená, že reference je chráněna před přepisem. Hodnota však není _neměnná_ a může se změnit, zejména pokud jde o složitou strukturu, jako je objekt.
> Poznámka: `const` znamená, že odkaz je chráněn před přepisem. Hodnota však není _neměnná_ a může se změnit, zejména pokud jde o složitou strukturu, jako je objekt.
## Datové typy
Proměnné mohou uchovávat mnoho různých typů hodnot, jako jsou čísla a text. Tyto různé typy hodnot jsou známé jako **datový typ**. Datové typy jsou důležitou součástí vývoje softwaru, protože pomáhají vývojářům rozhodovat, jak by měl být kód napsán a jak by měl software fungovat. Navíc některé datové typy mají jedinečné vlastnosti, které pomáhají transformovat nebo extrahovat další informace z hodnoty.
Proměnné mohou ukládat různé typy hodnot, jako jsou čísla a text. Tyto různé typy hodnot jsou známé jako **datové typy**. Datové typy jsou důležitou součástí vývoje softwaru, protože pomáhají vývojářům rozhodovat, jak by měl být kód napsán a jak by měl software fungovat. Navíc některé datové typy mají jedinečné vlastnosti, které pomáhají transformovat nebo extrahovat další informace z hodnoty.
✅ Datové typy jsou také označovány jako primitivní datové typy JavaScriptu, protože jsou nejnižší úrovní datových typů poskytovaných jazykem. Existuje 7 primitivních datových typů: string, number, bigint, boolean, undefined, null a symbol. Udělejte si chvíli na představu, co každý z těchto primitivů může představovat. Co je `zebra`? A co `0`? `true`?
✅ Datové typy jsou také označovány jako primitiva JavaScriptu, protože jsou to nejnižší úrovně datových typů poskytovaných jazykem. Existuje 7 primitivních datových typů: string, number, bigint, boolean, undefined, null a symbol. Zkuste si představit, co každý z těchto primitiv může představovat. Co je `zebra`? A co `0`? `true`?
### Čísla
@ -125,11 +125,11 @@ V předchozí části byla hodnota `myVariable` datového typu číslo.
`let myVariable = 123;`
Proměnné mohou uchovávat všechny typy čísel, včetně desetinných nebo záporných čísel. Čísla lze také používat s aritmetickými operátory, které jsou popsány v [další části](../../../../2-js-basics/1-data-types).
Proměnné mohou ukládat všechny typy čísel, včetně desetinných nebo záporných čísel. Čísla lze také používat s aritmetickými operátory, které jsou popsány v [další části](../../../../2-js-basics/1-data-types).
### Aritmetické operátory
Existuje několik typů operátorů, které lze použít při provádění aritmetických funkcí, a některé z nich jsou uvedeny zde:
Existuje několik typů operátorů pro provádění aritmetických funkcí, některé z nich jsou uvedeny zde:
✅ Proč v JavaScriptu `1 + 1 = 2`, ale `'1' + '1' = 11?` Zamyslete se nad tím. A co `'1' + 1`?
✅ Proč `1 + 1 = 2` v JavaScriptu, ale `'1' + '1' = 11?` Zamyslete se nad tím. A co `'1' + 1`?
**Šablonové literály** jsou další způsob formátování řetězců, kromě uvozovek se používá zpětný apostrof. Cokoli, co není prostý text, musí být umístěno do zástupných symbolů `${ }`. To zahrnuje jakékoli proměnné, které mohou být řetězce.
**Šablonové literály** jsou další způsob, jak formátovat řetězce, kromě uvozovek se však používají zpětné apostrofy. Cokoli, co není prostý text, musí být umístěno do zástupců `${ }`. To zahrnuje jakékoli proměnné, které mohou být řetězce.
```javascript
let myString1 = "Hello";
@ -179,13 +179,13 @@ let myString2 = "World";
`${myString1}, ${myString2}!` //Hello, World!
```
Svých formátovacích cílů můžete dosáhnout oběma způsoby, ale šablonové literály budou respektovat jakékoli mezery a zalomení řádků.
Svých formátovacích cílů můžete dosáhnout oběma způsoby, ale šablonové literály budou respektovat mezery a zalomení řádků.
✅ Kdy byste použili šablonový literál místo prostého řetězce?
### Booleovské hodnoty
Booleovské hodnoty mohou mít pouze dvě hodnoty: `true` nebo `false`. Booleovské hodnoty mohou pomoci rozhodnout, které řádky kódu by se měly spustit, když jsou splněny určité podmínky. V mnoha případech [operátory](../../../../2-js-basics/1-data-types) pomáhají nastavit hodnotu booleovské hodnoty a často si všimnete a napíšete proměnné, které jsou inicializovány nebo jejich hodnoty aktualizovány pomocí operátoru.
Booleovské hodnoty mohou mít pouze dvě hodnoty: `true` nebo `false`. Booleovské hodnoty mohou pomoci rozhodnout, které řádky kódu by se měly spustit, když jsou splněny určité podmínky. V mnoha případech [operátory](../../../../2-js-basics/1-data-types) pomáhají nastavit hodnotu booleovské proměnné a často si všimnete a napíšete proměnné, které jsou inicializovány nebo jejichž hodnoty jsou aktualizovány pomocí operátoru.
- `let myTrueBool = true`
- `let myFalseBool = false`
@ -196,12 +196,12 @@ Booleovské hodnoty mohou mít pouze dvě hodnoty: `true` nebo `false`. Booleovs
## 🚀 Výzva
JavaScript je známý svými překvapivými způsoby, jak občas zacházet s datovými typy. Proveďte trochu výzkumu o těchto 'záludnostech'. Například: citlivost na velikost písmen může být zrádná! Vyzkoušejte toto ve své konzoli: `let age = 1; let Age = 2; age == Age` (vyhodnotí `false` -- proč?). Jaké další záludnosti můžete najít?
JavaScript je známý svými překvapivými způsoby, jak občas zachází s datovými typy. Proveďte trochu výzkumu o těchto 'zádrhelech'. Například: citlivost na velikost písmen vás může zaskočit! Zkuste toto ve své konzoli: `let age = 1; let Age = 2; age == Age` (výsledek `false` -- proč?). Jaké další zádrhele můžete najít?
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/8)
[Kvíz po lekci](https://ff-quizzes.netlify.app)
## Přehled & Samostudium
## Přehled a samostudium
Podívejte se na [tento seznam cvičení v JavaScriptu](https://css-tricks.com/snippets/javascript/) a zkuste jedno. Co jste se naučili?
@ -212,4 +212,4 @@ Podívejte se na [tento seznam cvičení v JavaScriptu](https://css-tricks.com/s
---
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro kritické informace se doporučuje profesionální lidský překlad. Nezodpovídáme za jakékoli nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před přednáškou
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/9)
[Kvíz před přednáškou](https://ff-quizzes.netlify.app)
Když přemýšlíme o psaní kódu, vždy chceme zajistit, aby byl náš kód čitelný. I když to může znít paradoxně, kód se čte mnohem častěji, než se píše. Jedním zezákladních nástrojů v arzenálu vývojáře pro zajištění udržovatelného kódu je **funkce**.
Když přemýšlíme o psaní kódu, vždy chceme zajistit, aby byl náš kód čitelný. I když to může znít paradoxně, kód se čte mnohem častěji, než se píše. Jedním z klíčových nástrojů v arzenálu vývojáře pro zajištění udržitelného kódu je **funkce**.
[](https://youtube.com/watch?v=XgKsD6Zwvlc "Metody a funkce")
@ -25,9 +25,9 @@ Když přemýšlíme o psaní kódu, vždy chceme zajistit, aby byl náš kód
## Funkce
Funkce je v podstatě blok kódu, který můžeme spustit na vyžádání. To je ideální pro situace, kdy potřebujeme provést stejný úkol vícekrát; místo duplicity logiky na různých místech (což by bylo obtížné aktualizovat, až přijde čas), ji můžeme centralizovat na jednom místě a volat ji, kdykoli potřebujeme operaci provést - funkce můžete dokonce volat z jiných funkcí!
Funkce je v podstatě blok kódu, který můžeme spustit na vyžádání. To je ideální pro situace, kdy potřebujeme provést stejný úkol vícekrát; místo toho, abychom logiku duplikovali na více místech (což by bylo obtížné aktualizovat, až nastane čas), ji můžeme centralizovat na jednom místě a volat ji, kdykoli potřebujeme operaci provést – funkce můžete dokonce volat z jiných funkcí!
Neméně důležitá je schopnost pojmenovat funkci. I když se to může zdát triviální, název poskytuje rychlý způsob dokumentace části kódu. Můžete si to představit jako štítek na tlačítku. Pokud kliknu na tlačítko s nápisem "Zrušit časovač", vím, že zastaví běžící hodiny.
Neméně důležitá je schopnost pojmenovat funkci. I když se to může zdát triviální, název poskytuje rychlý způsob dokumentace části kódu. Můžete si to představit jako štítek na tlačítku. Pokud kliknu na tlačítko s nápisem „Zrušit časovač“, vím, že zastaví běžící hodiny.
## Vytvoření a volání funkce
@ -47,14 +47,14 @@ function displayGreeting() {
}
```
Kdykoli chceme funkci volat (nebo ji spustit), použijeme název funkce následovaný `()`. Stojí za zmínku, že funkce může být definována před nebo po jejím volání; JavaScriptový kompilátor ji pro vás najde.
Kdykoli chceme funkci volat (nebo ji vyvolat), použijeme název funkce následovaný `()`. Stojí za zmínku, že naše funkce může být definována před nebo po jejím volání; JavaScriptový kompilátor ji pro vás najde.
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** Existuje speciální typ funkce známý jako **metoda**, kterou už používáte! Ve skutečnosti jsme to viděli v našem příkladu výše, když jsme použili `console.log`. Rozdíl mezi metodou a funkcí je v tom, že metoda je připojena k objektu (v našem příkladu `console`), zatímco funkce je volně plovoucí. Mnoho vývojářů tyto termíny používá zaměnitelně.
> **NOTE:** Existuje speciální typ funkce známý jako **metoda**, kterou už používáte! Ve skutečnosti jsme to viděli v našem demo výše, když jsme použili `console.log`. Rozdíl mezi metodou a funkcí je v tom, že metoda je připojena k objektu (v našem příkladu `console`), zatímco funkce je volně plovoucí. Mnoho vývojářů tyto termíny používá zaměnitelně.
### Nejlepší postupy pro funkce
@ -62,11 +62,11 @@ Existuje několik osvědčených postupů, které je třeba mít na paměti při
- Vždy používejte popisné názvy, abyste věděli, co funkce dělá
- Používejte **camelCasing** pro spojování slov
- Udržujte funkce zaměřené na konkrétní úkol
- Udržujte své funkce zaměřené na konkrétní úkol
## Předávání informací funkci
## Předávání informací do funkce
Aby byla funkce více použitelná, často do ní budete chtít předat informace. Pokud vezmeme náš příklad `displayGreeting` výše, zobrazí pouze **Hello, world!**. Není to zrovna nejpraktičtější funkce, kterou byste mohli vytvořit. Pokud ji chceme udělat trochu flexibilnější, například umožnit někomu specifikovat jméno osoby, kterou chceme pozdravit, můžeme přidat **parametr**. Parametr (někdy nazývaný také**argument**) je dodatečná informace zaslaná funkci.
Aby byla funkce více použitelná, často do ní budete chtít předat informace. Pokud vezmeme náš příklad `displayGreeting` výše, zobrazí pouze **Hello, world!**. Není to zrovna nejpraktičtější funkce, kterou by někdo mohl vytvořit. Pokud ji chceme udělat trochu flexibilnější, například umožnit někomu specifikovat jméno osoby, kterou chceme pozdravit, můžeme přidat **parametr**. Parametr (někdy také nazývaný **argument**) je dodatečná informace zaslaná funkci.
Parametry jsou uvedeny v části definice v závorkách a jsou odděleny čárkami, například takto:
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## Výchozí hodnoty
Funkci můžeme udělat ještě flexibilnější přidáním více parametrů. Ale co když nechceme, aby bylo nutné zadat každou hodnotu? Pokud zůstaneme u našeho příkladu pozdravu, můžeme ponechat jméno jako povinné (potřebujeme vědět, koho zdravíme), ale chceme umožnit, aby byl samotný pozdrav přizpůsoben podle potřeby. Pokud někdo nechce pozdrav přizpůsobit, poskytneme místo toho výchozí hodnotu. Výchozí hodnotu parametru nastavíme podobně jako hodnotu proměnné - `parameterName = 'defaultValue'`. Celý příklad:
Naši funkci můžeme udělat ještě flexibilnější přidáním více parametrů. Ale co když nechceme, aby bylo nutné zadávat každou hodnotu? Pokud zůstaneme u našeho příkladu pozdravu, můžeme ponechat jméno jako povinné (potřebujeme vědět, koho zdravíme), ale chceme umožnit, aby byl samotný pozdrav přizpůsoben podle potřeby. Pokud někdo nechce pozdrav přizpůsobit, poskytneme místo toho výchozí hodnotu. Výchozí hodnotu parametru nastavíme podobně jako hodnotu proměnné - `parameterName = 'defaultValue'`. Celý příklad:
```javascript
function displayGreeting(name, salutation='Hello') {
@ -102,7 +102,7 @@ function displayGreeting(name, salutation='Hello') {
}
```
Když funkci voláme, můžeme se rozhodnout, zda chceme nastavit hodnotu pro `salutation`.
Když voláme funkci, můžeme se rozhodnout, zda chceme nastavit hodnotu pro `salutation`.
Doposud funkce, kterou jsme vytvořili, vždy vypíše výstup do [konzole](https://developer.mozilla.org/docs/Web/API/console). Někdy to může být přesně to, co hledáme, zejména když vytváříme funkce, které budou volat jiné služby. Ale co když chci vytvořit pomocnou funkci pro provedení výpočtu a vrátit hodnotu zpět, abych ji mohl použít jinde?
Až dosud funkce, kterou jsme vytvořili, vždy vypisovala výstup do [konzole](https://developer.mozilla.org/docs/Web/API/console). Někdy to může být přesně to, co hledáme, zejména když vytváříme funkce, které budou volat jiné služby. Ale co když chci vytvořit pomocnou funkci pro provedení výpočtu a vrátit hodnotu zpět, abych ji mohl použít jinde?
To můžeme udělat pomocí **návratové hodnoty**. Návratová hodnota je vrácena funkcí a může být uložena do proměnné stejně jako bychom mohli uložit literální hodnotu, například řetězec nebo číslo.
Toho můžeme dosáhnout pomocí **návratové hodnoty**. Návratová hodnota je vrácena funkcí a může být uložena do proměnné stejně jako bychom mohli uložit literální hodnotu, například řetězec nebo číslo.
Pokud funkce něco vrací, použije se klíčové slovo `return`. Klíčové slovo `return` očekává hodnotu nebo referenci toho, co se vrací, například takto:
@ -124,7 +124,7 @@ Pokud funkce něco vrací, použije se klíčové slovo `return`. Klíčové slo
return myVariable;
```
Můžeme vytvořit funkci pro vytvoření pozdravu a vrátit hodnotu zpět volajícímu.
Můžeme vytvořit funkci pro vytvoření pozdravné zprávy a vrátit hodnotu zpět volajícímu.
```javascript
function createGreetingMessage(name) {
@ -133,7 +133,7 @@ function createGreetingMessage(name) {
}
```
Při volání této funkce uložíme hodnotu do proměnné. Je to velmi podobné tomu, jak bychom nastavili proměnnou na statickou hodnotu (například `const name = 'Christopher'`).
Když tuto funkci voláme, uložíme hodnotu do proměnné. Je to velmi podobné tomu, jak bychom nastavili proměnnou na statickou hodnotu (například `const name = 'Christopher'`).
Podívejme se znovu na to, co jsme vytvořili. Vytváříme funkci s názvem, která bude použita pouze jednou. Jak se naše aplikace stává složitější, můžeme si představit, že budeme vytvářet mnoho funkcí, které budou volány pouze jednou. To není ideální. Jak se ukazuje, ne vždy musíme poskytovat název!
Podívejme se znovu na to, co jsme vytvořili. Vytváříme funkci s názvem, která bude použita pouze jednou. Jak se naše aplikace stává složitější, můžeme si představit, že budeme vytvářet spoustu funkcí, které budou volány pouze jednou. To není ideální. Jak se ukazuje, ne vždy musíme poskytovat název!
Když předáváme funkci jako parametr, můžeme obejít její předchozí vytvoření a místo toho ji vytvořit jako součást parametru. Používáme stejné klíčové slovo `function`, ale místo toho ji vytvoříme jako parametr.
Když předáváme funkci jako parametr, můžeme se vyhnout jejímu předchozímu vytvoření a místo toho ji vytvořit jako součást parametru. Používáme stejné klíčové slovo `function`, ale místo toho ji vytvoříme jako parametr.
Přepišme výše uvedený kód tak, aby používal anonymní funkci:
@ -173,7 +173,7 @@ Pokud spustíte náš nový kód, všimnete si, že dostaneme stejné výsledky.
### Funkce s tučnou šipkou
Jednou z běžných zkratek v mnoha programovacích jazycích (včetně JavaScriptu) je schopnost používat tzv. **arrow** nebo **fat arrow** funkce. Používá speciální indikátor `=>`, který vypadá jako šipka - odtud název! Použitím `=>` můžeme přeskočit klíčové slovo `function`.
Jednou z běžných zkratek v mnoha programovacích jazycích (včetně JavaScriptu) je schopnost používat tzv. **arrow** nebo **fat arrow** funkce. Používá speciální indikátor `=>`, který vypadá jako šipka – odtud název! Použitím `=>` můžeme přeskočit klíčové slovo `function`.
Přepišme náš kód ještě jednou, tentokrát s použitím funkce s tučnou šipkou:
@ -185,7 +185,7 @@ setTimeout(() => {
### Kdy použít kterou strategii
Nyní jste viděli, že máme tři způsoby, jak předat funkci jako parametr, a možná se ptáte, kdy použít který. Pokud víte, že budete funkci používat více než jednou, vytvořte ji normálně. Pokud ji budete používat pouze na jednom místě, je obecně nejlepší použít anonymní funkci. Zda použijete funkci s tučnou šipkou nebo tradiční syntaxi `function`, je na vás, ale všimnete si, že většina moderních vývojářů preferuje `=>`.
Nyní jste viděli, že máme tři způsoby, jak předat funkci jako parametr, a možná vás zajímá, kdy použít který. Pokud víte, že funkci budete používat více než jednou, vytvořte ji normálně. Pokud ji budete používat pouze na jednom místě, je obecně nejlepší použít anonymní funkci. Zda použijete funkci s tučnou šipkou nebo tradiční syntaxi `function`, je na vás, ale všimnete si, že většina moderních vývojářů preferuje `=>`.
---
@ -194,7 +194,7 @@ Nyní jste viděli, že máme tři způsoby, jak předat funkci jako parametr, a
Dokážete jednou větou vysvětlit rozdíl mezi funkcemi a metodami? Zkuste to!
## Kvíz po přednášce
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/10)
[Kvíz po přednášce](https://ff-quizzes.netlify.app)
## Přehled a samostudium
@ -207,4 +207,4 @@ Stojí za to [přečíst si něco více o funkcích s tučnou šipkou](https://d
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
## Kvíz před lekcí
## Kvíz před přednáškou
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/11)
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/11)
Rozhodování a řízení pořadí, ve kterém váš kód běží, činí váš kód znovupoužitelným a robustním. Tato sekce pokrývá syntaxi pro řízení toku dat v JavaScriptu a její význam při použití s datovými typy Boolean.
@ -42,12 +42,12 @@ Operátory se používají k vyhodnocení podmínek porovnáním, které vytvoř
| `<` | **Menší než**: Porovná dvě hodnoty a vrátí hodnotu `true`, pokud je hodnota na levé straně menší než na pravé | `5 < 6 // true` |
| `<=` | **Menší nebo rovno**: Porovná dvě hodnoty a vrátí hodnotu `true`, pokud je hodnota na levé straně menší nebo rovna pravé | `5 <= 6 // true` |
| `>` | **Větší než**: Porovná dvě hodnoty a vrátí hodnotu `true`, pokud je hodnota na levé straně větší než na pravé | `5 > 6 // false` |
| `>=` | **Větší nebo rovno**: Porovná dvě hodnoty a vrátí hodnotu `true`, pokud je hodnota na levé straně větší nebo rovna pravé | `5 >= 6 // false` |
| `===` | **Striktní rovnost**: Porovná dvě hodnoty a vrátí hodnotu `true`, pokud jsou hodnoty na pravé a levé straně stejné A mají stejný datový typ | `5 === 6 // false` |
| `!==` | **Nerovnost**: Porovná dvě hodnoty a vrátí opačnou hodnotu Boolean, než by vrátil operátor striktní rovnosti | `5 !== 6 // true` |
| `<` | **Menší než**: Porovná dvě hodnoty a vrátí hodnotu Boolean `true`, pokud je hodnota na levé straně menší než na pravé | `5 < 6 // true` |
| `<=` | **Menší nebo rovno**: Porovná dvě hodnoty a vrátí hodnotu Boolean `true`, pokud je hodnota na levé straně menší nebo rovna pravé | `5 <= 6 // true` |
| `>` | **Větší než**: Porovná dvě hodnoty a vrátí hodnotu Boolean `true`, pokud je hodnota na levé straně větší než na pravé | `5 > 6 // false` |
| `>=` | **Větší nebo rovno**: Porovná dvě hodnoty a vrátí hodnotu Boolean `true`, pokud je hodnota na levé straně větší nebo rovna pravé | `5 >= 6 // false` |
| `===` | **Striktní rovnost**: Porovná dvě hodnoty a vrátí hodnotu Boolean `true`, pokud jsou hodnoty na pravé a levé straně stejné A mají stejný datový typ | `5 === 6 // false` |
| `!==` | **Nerovnost**: Porovná dvě hodnoty a vrátí opačnou hodnotu Boolean, než by vrátil operátor striktní rovnosti | `5 !== 6 // true` |
✅ Ověřte si své znalosti tím, že napíšete několik porovnání do konzole vašeho prohlížeče. Překvapí vás některá vrácená data?
@ -135,8 +135,8 @@ Rozhodování může vyžadovat více než jedno porovnání a může být spoje
| `&&` | **Logické AND**: Porovná dvě Boolean výrazy. Vrátí true **pouze**, pokud jsou obě strany pravdivé | `(5 > 6) && (5 < 6 ) //Jedna strana je nepravdivá, druhá je pravdivá. Vrací false` |
| `\|\|` | **Logické OR**: Porovná dvě Boolean výrazy. Vrátí true, pokud je alespoň jedna strana pravdivá | `(5 > 6) \|\| (5 < 6) //Jedna strana je nepravdivá, druhá je pravdivá. Vrací true` |
| `&&` | **Logické AND**: Porovná dvě Boolean výrazy. Vrátí true **pouze**, pokud jsou obě strany pravdivé | `(5 > 6) && (5 < 6 ) //Jedna strana je nepravdivá, druhá je pravdivá. Vrátí false` |
| `\|\|` | **Logické OR**: Porovná dvě Boolean výrazy. Vrátí true, pokud je alespoň jedna strana pravdivá | `(5 > 6) \|\| (5 < 6) //Jedna strana je nepravdivá, druhá je pravdivá. Vrátí true` |
| `!` | **Logické NOT**: Vrátí opačnou hodnotu Boolean výrazu | `!(5 > 6) // 5 není větší než 6, ale "!" vrátí true` |
## Podmínky a rozhodování s logickými operátory
@ -185,7 +185,7 @@ let secondNumber = 10;
let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
```
✅ Věnujte chvíli čtení tohoto kódu několikrát. Rozumíte tomu, jak tyto operátory fungují?
✅ Udělejte si chvíli na přečtení tohoto kódu několikrát. Rozumíte tomu, jak tyto operátory fungují?
Výše uvedené říká:
@ -208,19 +208,19 @@ if (firstNumber > secondNumber) {
## 🚀 Výzva
Vytvořte program, který je nejprve napsán s logickými operátory, a poté ho přepište pomocí ternárního výrazu. Která syntaxe vám vyhovuje více?
Vytvořte program, který je nejprve napsán s logickými operátory, a poté ho přepište pomocí ternárního výrazu. Jaká syntaxe vám vyhovuje více?
---
## Kvíz po lekci
## Kvíz po přednášce
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/12)
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/12)
## Přehled & Samostudium
Přečtěte si více o mnoha operátorech dostupných uživateli [na MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators).
Projděte si skvělý [přehled operátorů](https://joshwcomeau.com/operator-lookup/) od Joshe Comeaua!
Projděte si skvělý [operator lookup](https://joshwcomeau.com/operator-lookup/) od Joshe Comeaua!
## Úkol
@ -229,4 +229,4 @@ Projděte si skvělý [přehled operátorů](https://joshwcomeau.com/operator-lo
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
@ -27,7 +27,7 @@ Tato lekce se zabývá základy JavaScriptu, jazyka, který zajišťuje interakt
## Pole
Práce s daty je běžným úkolem v každém programovacím jazyce, a je mnohem jednodušší, když jsou data organizována ve strukturovaném formátu, jako jsou pole. V polích jsou data uložena ve struktuře podobné seznamu. Jednou z hlavních výhod polí je, že můžete uložit různé typy dat do jednoho pole.
Práce s daty je běžný úkol v každém programovacím jazyce, a je mnohem jednodušší, když jsou data organizována ve strukturovaném formátu, jako jsou pole. V polích jsou data uložena ve struktuře podobné seznamu. Jednou z hlavních výhod polí je, že můžete uložit různé typy dat do jednoho pole.
✅ Pole jsou všude kolem nás! Dokážete si představit příklad pole z reálného života, například pole solárních panelů?
@ -43,9 +43,9 @@ Toto je prázdné pole, ale pole mohou být deklarována již naplněná daty. V
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
Hodnotám v poli je přiřazena jedinečná hodnota nazývaná **index**, což je celé číslo, které je přiřazeno na základě jeho vzdálenosti od začátku pole. V příkladu výše má řetězcová hodnota "Chocolate" index 0 a index "Rocky Road" je 4. Pomocí indexu a hranatých závorek můžete získat, změnit nebo vložit hodnoty pole.
Hodnotám v poli je přiřazena jedinečná hodnota nazývaná **index**, což je celé číslo, které je přiřazeno na základě jeho vzdálenosti od začátku pole. V příkladu výše má řetězcová hodnota "Chocolate" index 0 a index "Rocky Road" je 4. Použijte index s hranatými závorkami k získání, změně nebo vložení hodnot pole.
✅ Překvapuje vás, že pole začínají na indexu nula? V některých programovacích jazycích začínají indexy na 1. Je za tím zajímavá historie, kterou si můžete [přečíst na Wikipedii](https://en.wikipedia.org/wiki/Zero-based_numbering).
✅ Překvapuje vás, že pole začínají na indexu nula? V některých programovacích jazycích začínají indexy na 1. Existuje zajímavá historie kolem tohoto, kterou si můžete [přečíst na Wikipedii](https://en.wikipedia.org/wiki/Zero-based_numbering).
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -81,9 +81,9 @@ Cykly nám umožňují provádět opakující se nebo **iterativní** úkoly a m
### For cyklus
Cyklus `for` vyžaduje 3 části pro iteraci:
- `counter` Proměnná, která je obvykle inicializována číslem a počítá počet iterací
- `condition` Výraz, který používá operátory porovnání a způsobí zastavení cyklu, když je `false`
Cyklus `for` vyžaduje 3 části k iteraci:
- `counter` Proměnná, která je obvykle inicializována číslem, které počítá počet iterací
- `condition` Výraz, který používá operátory porovnání k zastavení cyklu, když je `false`
- `iteration-expression` Spouští se na konci každé iterace, obvykle se používá ke změně hodnoty counteru
```javascript
@ -93,7 +93,7 @@ for (let i = 0; i < 10; i++) {
}
```
✅ Spusťte tento kód v konzoli prohlížeče. Co se stane, když provedete malé změny v counteru, podmínce nebo výrazu iterace? Dokážete ho spustit pozpátku, vytvořit odpočítávání?
✅ Spusťte tento kód v konzoli prohlížeče. Co se stane, když provedete malé změny v counteru, podmínce nebo iterativním výrazu? Dokážete ho spustit pozpátku, vytvořit odpočítávání?
### While cyklus
@ -128,12 +128,12 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
## 🚀 Výzva
Existují i jiné způsoby procházení polí než pomocí for a while cyklů. Jsou to [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) a [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Přepište svůj cyklus pole pomocí jedné z těchto technik.
Existují i jiné způsoby procházení polí než pomocí for a while cyklů. Existují [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) a [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Přepište svůj cyklus pole pomocí jedné z těchto technik.
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/14)
## Přehled a samostudium
## Přehled & Samostudium
Pole v JavaScriptu mají mnoho metod, které jsou velmi užitečné pro manipulaci s daty. [Přečtěte si o těchto metodách](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) a vyzkoušejte některé z nich (jako push, pop, slice a splice) na poli podle svého návrhu.
@ -144,4 +144,4 @@ Pole v JavaScriptu mají mnoho metod, které jsou velmi užitečné pro manipula
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.

> Sketchnote od [Tomomi Imura](https://twitter.com/girlie_mac)
@ -23,15 +23,15 @@ CO_OP_TRANSLATOR_METADATA:
### Úvod
HTML, neboli HyperText Markup Language, je „kostra“ webu. Pokud CSS „obléká“ váš HTML a JavaScript mu vdechuje život, HTML je tělo vaší webové aplikace. Syntaxe HTML dokonce tuto myšlenku odráží, protože obsahuje značky jako „head“, „body“ a „footer“.
HTML, neboli HyperText Markup Language, je „kostra“ webu. Pokud CSS „obléká“ váš HTML a JavaScript mu vdechuje život, HTML je tělo vaší webové aplikace. Syntaxe HTML tuto myšlenku dokonce odráží, protože obsahuje značky jako „head“, „body“ a „footer“.
V této lekci použijeme HTML k vytvoření „kostry“ rozhraní našeho virtuálního terária. Bude mít název a tři sloupce: pravý a levý sloupec, kde budou umístěny přetahovatelné rostliny, a střední oblast, která bude samotné terárium vypadající jako sklo. Na konci této lekce budete schopni vidět rostliny ve sloupcích, ale rozhraní bude vypadat trochu zvláštně; nebojte se, v další části přidáte CSS styly, aby rozhraní vypadalo lépe.
V této lekci použijeme HTML k vytvoření „kostry“ rozhraní našeho virtuálního terária. Bude mít název a tři sloupce: pravý a levý sloupec, kde budou umístěny přetahovatelné rostliny, a střední oblast, která bude představovat samotné skleněné terárium. Na konci této lekce uvidíte rostliny ve sloupcích, ale rozhraní bude vypadat trochu zvláštně; nebojte se, v další části přidáte do rozhraní CSS styly, aby vypadalo lépe.
### Úkol
Na svém počítači vytvořte složku nazvanou „terrarium“ a uvnitř ní soubor nazvaný „index.html“. Můžete to udělat ve Visual Studio Code po vytvoření složky terrarium tak, že otevřete nové okno VS Code, kliknete na „otevřít složku“ a přejdete do své nové složky. Klikněte na malé tlačítko „soubor“ v panelu Průzkumníka a vytvořte nový soubor:
Na svém počítači vytvořte složku s názvem 'terrarium' a uvnitř ní soubor s názvem 'index.html'. Můžete to udělat ve Visual Studio Code po vytvoření složky terária tak, že otevřete nové okno VS Code, kliknete na 'open folder' a přejdete do své nové složky. Klikněte na malé tlačítko 'file' v panelu Explorer a vytvořte nový soubor:


Nebo
@ -41,17 +41,17 @@ Použijte tyto příkazy v git bash:
* `touch index.html`
* `code index.html` nebo `nano index.html`
> Soubor index.html označuje prohlížeči, že se jedná o výchozí soubor ve složce; URL jako `https://anysite.com/test` může být vytvořena pomocí struktury složek, která zahrnuje složku nazvanou`test` s `index.html` uvnitř; `index.html` nemusí být vidět v URL.
> Soubory index.html označují prohlížeči, že se jedná o výchozí soubor ve složce; URL jako `https://anysite.com/test` může být vytvořena pomocí struktury složek, která zahrnuje složku s názvem`test` s `index.html` uvnitř; `index.html` nemusí být v URL vidět.
---
## DocType a značky html
První řádek souboru HTML je jeho doctype. Je trochu překvapivé, že tento řádek musí být na úplném vrcholu souboru, ale říká starším prohlížečům, že stránka musí být vykreslena ve standardním režimu podle aktuální specifikace HTML.
První řádek souboru HTML je jeho doctype. Je trochu překvapivé, že tento řádek musí být na úplném vrcholu souboru, ale říká starším prohlížečům, že stránka má být vykreslena ve standardním režimu podle aktuální specifikace HTML.
> Tip: ve VS Code můžete najet myší na značku a získat informace o jejím použití z referenčních příruček MDN.
Druhý řádek by měl být otevírací značka `<html>`, následovaná její zavírací značkou `</html>`. Tyto značky jsou kořenovými prvky vašeho rozhraní.
Druhý řádek by měl být otevírací značkou `<html>`, následovanou uzavírací značkou `</html>`. Tyto značky jsou kořenovými prvky vašeho rozhraní.
### Úkol
@ -66,19 +66,19 @@ Přidejte tyto řádky na začátek svého souboru `index.html`:
---
## Dokumentová část 'head'
## 'Head' dokumentu
Oblast 'head' dokumentu HTML obsahuje klíčové informace o vaší webové stránce, známé také jako [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta). V našem případě sdělujeme webovému serveru, na který bude tato stránka odeslána k vykreslení, tyto čtyři věci:
- název stránky
- metadata stránky včetně:
- 'character set', který informuje o tom, jaké kódování znaků je na stránce použito
- informace o prohlížeči, včetně `x-ua-compatible`, což naznačuje, že je podporován prohlížeč IE=edge
- 'character set', který říká, jaké kódování znaků je na stránce použito
- informace o prohlížeči, včetně `x-ua-compatible`, což označuje, že je podporován prohlížeč IE=edge
- informace o tom, jak by se měl viewport chovat při načtení. Nastavení viewportu na počáteční měřítko 1 ovládá úroveň přiblížení při prvním načtení stránky.
### Úkol
Přidejte blok 'head' do svého dokumentu mezi otevírací a zavírací značky `<html>`.
Přidejte blok 'head' do svého dokumentu mezi otevírací a uzavírací značky `<html>`.
```html
<head>
@ -93,11 +93,11 @@ Přidejte blok 'head' do svého dokumentu mezi otevírací a zavírací značky
---
## Dokumentová část `body`
## 'Body' dokumentu
### Značky HTML
### HTML značky
V HTML přidáváte značky do svého .html souboru, abyste vytvořili prvky webové stránky. Každá značka obvykle má otevírací a zavírací značku, například: `<p>ahoj</p>` pro označení odstavce. Vytvořte tělo svého rozhraní přidáním sady značek `<body>` uvnitř páru značek `<html>`; váš kód nyní vypadá takto:
V HTML přidáváte značky do svého .html souboru, abyste vytvořili prvky webové stránky. Každá značka obvykle má otevírací a uzavírací značku, například: `<p>ahoj</p>` pro označení odstavce. Vytvořte tělo svého rozhraní přidáním sady značek `<body>` uvnitř páru značek `<html>`; váš kód nyní vypadá takto:
### Úkol
@ -118,9 +118,9 @@ Nyní můžete začít vytvářet svou stránku. Obvykle používáte značky `<
### Obrázky
Jedna značka HTML, která nepotřebuje zavírací značku, je `<img>`, protože má prvek `src`, který obsahuje všechny informace, které stránka potřebuje k vykreslení položky.
Jedna HTML značka, která nepotřebuje uzavírací značku, je `<img>`, protože má atribut `src`, který obsahuje všechny informace potřebné k vykreslení položky na stránce.
Vytvořte ve své aplikaci složku nazvanou `images` a do ní přidejte všechny obrázky ze složky [source code folder](../../../../3-terrarium/solution/images); (je tam 14 obrázků rostlin).
Vytvořte ve své aplikaci složku s názvem `images` a do ní přidejte všechny obrázky ze [složky se zdrojovým kódem](../../../../3-terrarium/solution/images); (je tam 14 obrázků rostlin).
### Úkol
@ -179,9 +179,9 @@ Přidejte tyto obrázky rostlin do dvou sloupců mezi značky `<body></body>`:
> Poznámka: Spany vs. Divy. Divy jsou považovány za 'blokové' prvky, zatímco Spany jsou 'řádkové'. Co by se stalo, kdybyste tyto divy změnili na spany?
S tímto kódem se rostliny nyní zobrazují na obrazovce. Vypadá to dost špatně, protože ještě nejsou stylizovány pomocí CSS, což uděláme v další lekci.
S tímto kódem se rostliny nyní zobrazí na obrazovce. Vypadá to dost špatně, protože ještě nejsou stylizovány pomocí CSS, což uděláme v další lekci.
Každý obrázek má alternativní text, který se zobrazí, i když obrázek nemůžete vidět nebo vykreslit. Toto je důležitý atribut pro zajištění přístupnosti. Více o přístupnosti se dozvíte v budoucích lekcích; prozatím si pamatujte, že atribut alt poskytuje alternativní informace o obrázku, pokud uživatel z nějakého důvodu nemůže obrázek zobrazit (kvůli pomalému připojení, chybě v atributu src nebo pokud uživatel používá čtečku obrazovky).
Každý obrázek má alternativní text, který se zobrazí, i když obrázek nemůžete vidět nebo vykreslit. Tento atribut je důležitý pro přístupnost. Více o přístupnosti se dozvíte v budoucích lekcích; prozatím si zapamatujte, že atribut alt poskytuje alternativní informace o obrázku, pokud uživatel z nějakého důvodu nemůže obrázek zobrazit (kvůli pomalému připojení, chybě v atributu src nebo pokud uživatel používá čtečku obrazovky).
✅ Všimli jste si, že každý obrázek má stejný alt tag? Je to dobrá praxe? Proč ano nebo ne? Můžete tento kód vylepšit?
@ -189,7 +189,7 @@ Každý obrázek má alternativní text, který se zobrazí, i když obrázek ne
## Sémantické značky
Obecně je lepší používat smysluplnou 'sémantiku' při psaní HTML. Co to znamená? Znamená to, že používáte značky HTML k reprezentaci typu dat nebo interakce, pro které byly navrženy. Například hlavní textový nadpis na stránce by měl používat značku `<h1>`.
Obecně je lepší používat smysluplné 'sémantiky' při psaní HTML. Co to znamená? Znamená to, že používáte HTML značky k reprezentaci typu dat nebo interakce, pro které byly navrženy. Například hlavní název textu na stránce by měl používat značku `<h1>`.
Přidejte následující řádek hned pod otevírací značku `<body>`:
@ -197,7 +197,7 @@ Přidejte následující řádek hned pod otevírací značku `<body>`:
<h1>My Terrarium</h1>
```
Používání sémantických značek, jako je použití nadpisů `<h1>` a neseřazených seznamů jako `<ul>`, pomáhá čtečkám obrazovky navigovat na stránce. Obecně by tlačítka měla být napsána jako `<button>` a seznamy jako `<li>`. I když je _možné_ použít speciálně stylizované prvky `<span>` s obslužnými funkcemi kliknutí k napodobení tlačítek, je lepší pro uživatele s omezením používat technologie k určení, kde na stránce se tlačítko nachází, a interagovat s ním, pokud se prvek objeví jako tlačítko. Z tohoto důvodu se snažte používat sémantické značky co nejvíce.
Používání sémantických značek, jako je například použití `<h1>` pro nadpisy a `<ul>` pro nečíslované seznamy, pomáhá čtečkám obrazovky navigovat na stránce. Obecně by tlačítka měla být psána jako `<button>` a seznamy jako `<li>`. I když je _možné_ použít speciálně stylizované `<span>`prvky s obslužnými funkcemi kliknutí k napodobení tlačítek, je lepší, aby uživatelé s postižením mohli pomocí technologií určit, kde se na stránce nachází tlačítko, a interagovat s ním, pokud se prvek zobrazuje jako tlačítko. Z tohoto důvodu se snažte používat sémantické značky co nejvíce.
✅ Podívejte se na čtečku obrazovky a [jak interaguje s webovou stránkou](https://www.youtube.com/watch?v=OUDV1gqs9GA). Vidíte, proč by nesémantické značky mohly uživatele frustrovat?
@ -221,21 +221,21 @@ Přidejte tento kód nad poslední značku `</div>`:
</div>
```
✅ I když jste přidali tento kód na obrazovku, nevidíte vůbec nic vykresleného. Proč?
✅ I když jste tento kód přidali na obrazovku, nevidíte, že by se něco vykreslilo. Proč?
---
## 🚀Výzva
Existují některé „divoké“ starší značky v HTML, které je stále zábavné používat, i když byste neměli používat zastaralé značky, jako jsou [tyto značky](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) ve svém kódu. Přesto, můžete použít starou značku `<marquee>` k tomu, aby se nadpis h1 posouval horizontálně? (pokud ano, nezapomeňte ji poté odstranit)
Existují některé staré 'zastaralé' značky v HTML, které je stále zábavné si vyzkoušet, i když byste neměli používat zastaralé značky jako [tyto značky](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) ve svém kódu. Přesto, můžete použít starou značku `<marquee>` k tomu, aby se nadpis h1 posouval horizontálně? (pokud ano, nezapomeňte ji poté odstranit)
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/16)
## Přehled & Samostudium
## Přehled a samostudium
HTML je „osvědčený“ systém stavebních bloků, který pomohl vytvořit web takový, jaký je dnes. Naučte se něco o jeho historii studiem starých i nových značek. Dokážete zjistit, proč byly některé značky zastaralé a jiné přidány? Jaké značky by mohly být zavedeny v budoucnu?
HTML je „osvědčený“ stavební systém, který pomohl vytvořit web takový, jaký je dnes. Naučte se něco o jeho historii studiem starých a nových značek. Dokážete zjistit, proč byly některé značky zastaralé a jiné přidány? Jaké značky by mohly být zavedeny v budoucnu?
Zjistěte více o vytváření webů pro web a mobilní zařízení na [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
@ -246,4 +246,4 @@ Zjistěte více o vytváření webů pro web a mobilní zařízení na [Microsof
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
CSS, neboli Cascading Style Sheets, řeší důležitý problém webového vývoje: jak udělat, aby váš web vypadal hezky. Stylování aplikací je činí uživatelsky přívětivějšími a vizuálně atraktivnějšími; pomocí CSS můžete také vytvořit responzivní webový design (RWD) – díky tomu budou vaše aplikace vypadat dobře bez ohledu na velikost obrazovky, na které jsou zobrazeny. CSS není jen o vzhledu aplikace; jeho specifikace zahrnuje animace a transformace, které umožňují sofistikované interakce. CSS Working Group pomáhá udržovat aktuální specifikace CSS; jejich práci můžete sledovat na [stránkách World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
CSS, neboli Cascading Style Sheets, řeší důležitý problém webového vývoje: jak udělat, aby váš web vypadal hezky. Stylování vašich aplikací je činí uživatelsky přívětivějšími a vizuálně atraktivnějšími; pomocí CSS můžete také vytvořit responzivní webový design (RWD) – díky tomu budou vaše aplikace vypadat dobře bez ohledu na velikost obrazovky, na které jsou zobrazeny. CSS není jen o tom, aby vaše aplikace vypadala hezky; jeho specifikace zahrnuje animace a transformace, které umožňují sofistikované interakce ve vašich aplikacích. CSS Working Group pomáhá udržovat aktuální specifikace CSS; jejich práci můžete sledovat na [stránkách World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
> Poznámka: CSS je jazyk, který se vyvíjí, stejně jako vše na webu, a ne všechny prohlížeče podporují novější části specifikace. Vždy ověřte své implementace na [CanIUse.com](https://caniuse.com).
> Poznámka: CSS je jazyk, který se vyvíjí, stejně jako vše na webu, a ne všechny prohlížeče podporují novější části specifikace. Vždy ověřte své implementace konzultací na [CanIUse.com](https://caniuse.com).
V této lekci přidáme styly do našeho online terrária a naučíme se více o několika konceptech CSS: kaskádě, dědičnosti, použití selektorů, pozicování a využití CSS k tvorbě rozvržení. V průběhu vytvoříme rozvržení terrária a samotné terrárium.
V této lekci přidáme styly do našeho online terrária a naučíme se více o několika konceptech CSS: kaskádě, dědičnosti, použití selektorů, pozicování a využití CSS pro tvorbu rozvržení. Během procesu vytvoříme rozvržení terrária a samotné terrárium.
### Předpoklady
Měli byste mít připravený HTML pro vaše terrárium, který je připravený ke stylování.
Měli byste mít připravený HTML pro vaše terrárium, aby bylo možné jej stylovat.
> Podívejte se na video
@ -35,7 +35,7 @@ Měli byste mít připravený HTML pro vaše terrárium, který je připravený
### Úkol
Ve složce terrária vytvořte nový soubor s názvem `style.css`. Importujte tento soubor do sekce `<head>`:
Ve složce s vaším terráriem vytvořte nový soubor s názvem `style.css`. Importujte tento soubor do sekce `<head>`:
```html
<linkrel="stylesheet"href="./style.css"/>
@ -45,11 +45,11 @@ Ve složce terrária vytvořte nový soubor s názvem `style.css`. Importujte te
## Kaskáda
Cascading Style Sheets zahrnují myšlenku, že styly "kaskádují", což znamená, že aplikace stylu je řízena jeho prioritou. Styly nastavené autorem webu mají přednost před těmi, které nastaví prohlížeč. Styly nastavené "inline" mají přednost před těmi, které jsou nastaveny v externím stylovém souboru.
Cascading Style Sheets zahrnují myšlenku, že styly „kaskádují“, což znamená, že aplikace stylu je řízena jeho prioritou. Styly nastavené autorem webu mají přednost před těmi, které nastaví prohlížeč. Styly nastavené „inline“ mají přednost před těmi, které jsou nastaveny v externím stylovém souboru.
### Úkol
Přidejte inline styl "color: red" do vašeho tagu `<h1>`:
Přidejte inline styl „color: red“ do vašeho tagu `<h1>`:
```HTML
<h1style="color: red">My Terrarium</h1>
@ -63,17 +63,17 @@ h1 {
}
```
✅ Která barva se zobrazí ve vaší webové aplikaci? Proč? Dokážete najít způsob, jak přepsat styly? Kdy byste to chtěli udělat, nebo proč ne?
✅ Jaká barva se zobrazí ve vaší webové aplikaci? Proč? Dokážete najít způsob, jak přepsat styly? Kdy byste to chtěli udělat, nebo proč ne?
---
## Dědičnost
Styly se dědí od předka k potomkovi, takže vnořené prvky dědí styly svých rodičů.
Styly se dědí od nadřazeného stylu k podřízenému, takže vnořené prvky dědí styly svých rodičů.
### Úkol
Nastavte font těla na daný font a zkontrolujte font vnořeného prvku:
Nastavte font těla na daný font a zkontrolujte, zda vnořený prvek zdědí tento font:
```CSS
body {
@ -81,11 +81,11 @@ body {
}
```
Otevřete konzoli prohlížeče na záložce 'Elements' a pozorujte font H1. Dědí svůj font z těla, jak je uvedeno v prohlížeči:
Otevřete konzoli vašeho prohlížeče na záložce „Elements“ a sledujte font H1. Dědí svůj font z těla, jak je uvedeno v prohlížeči:
✅ Dokážete nastavit vnořenému stylu jinou vlastnost?
✅ Dokážete udělat, aby vnořený styl zdědil jinou vlastnost?
---
@ -108,7 +108,7 @@ h1 {
Tento způsob stylování tagu vám dává kontrolu nad unikátními prvky, ale potřebujete kontrolovat styly mnoha rostlin ve vašem terráriu. K tomu musíte využít selektory CSS.
### Ids
### Id
Přidejte nějaký styl pro rozvržení levého a pravého kontejneru. Protože existuje pouze jeden levý kontejner a jeden pravý kontejner, jsou v označení HTML označeny id. Pro jejich stylování použijte `#`:
@ -134,9 +134,9 @@ Přidejte nějaký styl pro rozvržení levého a pravého kontejneru. Protože
}
```
Zde jste umístili tyto kontejnery absolutním pozicováním na krajní levý a pravý okraj obrazovky a použili procenta pro jejich šířku, aby se mohly přizpůsobit malým mobilním obrazovkám.
Zde jste umístili tyto kontejnery s absolutním pozicováním na krajní levý a pravý okraj obrazovky a použili procenta pro jejich šířku, aby se mohly přizpůsobit malým mobilním obrazovkám.
✅ Tento kód je dost opakující se, tedy není "DRY" (Don't Repeat Yourself); dokážete najít lepší způsob, jak stylovat tyto id, možná pomocí id a třídy? Museli byste změnit označení HTML a refaktorovat CSS:
✅ Tento kód je poměrně opakující se, a tedy ne „DRY“ (Don't Repeat Yourself); dokážete najít lepší způsob, jak stylovat tato id, třeba pomocí id a třídy? Museli byste změnit označení a refaktorovat CSS:
```html
<divid="left-container"class="container"></div>
@ -144,9 +144,9 @@ Zde jste umístili tyto kontejnery absolutním pozicováním na krajní levý a
### Třídy
V předchozím příkladu jste stylovali dva unikátní prvky na obrazovce. Pokud chcete, aby styly platily pro mnoho prvků na obrazovce, můžete použít CSS třídy. Udělejte to pro rozvržení rostlin v levém a pravém kontejneru.
V předchozím příkladu jste stylovali dva unikátní prvky na obrazovce. Pokud chcete, aby se styly aplikovaly na mnoho prvků na obrazovce, můžete použít třídy CSS. Udělejte to pro rozvržení rostlin v levém a pravém kontejneru.
Všimněte si, že každá rostlina v označení HTML má kombinaci id a tříd. Id jsou zde používány JavaScriptem, který přidáte později, aby manipuloval s umístěním rostlin v terráriu. Třídy však dávají všem rostlinám daný styl.
Všimněte si, že každá rostlina v označení HTML má kombinaci id a tříd. Id jsou zde používána JavaScriptem, který přidáte později, pro manipulaci s umístěním rostlin v terráriu. Třídy však dávají všem rostlinám daný styl.
```html
<divclass="plant-holder">
@ -171,35 +171,35 @@ Přidejte následující do vašeho souboru `style.css`:
}
```
Pozoruhodné v tomto úryvku je směs relativního a absolutního pozicování, které pokryjeme v další sekci. Podívejte se na způsob, jakým jsou výšky zpracovány pomocí procent:
Pozoruhodné v tomto úryvku je míchání relativního a absolutního pozicování, které si podrobněji vysvětlíme v další části. Podívejte se na způsob, jakým jsou výšky řešeny pomocí procent:
Nastavili jste výšku držáku rostlin na 13 %, což je dobré číslo, aby všechny rostliny byly zobrazeny v každém vertikálním kontejneru bez nutnosti posouvání.
Nastavili jste výšku držáku rostlin na 13 %, což je dobré číslo, aby byly všechny rostliny zobrazeny v každém vertikálním kontejneru bez nutnosti posouvání.
Držák rostlin je posunut doleva, aby rostliny byly více vycentrovány v jejich kontejneru. Obrázky mají velké množství průhledného pozadí, aby byly lépe přetahovatelné, takže je třeba je posunout doleva, aby lépe seděly na obrazovce.
Držák rostlin je posunut doleva, aby byly rostliny více vycentrovány v jejich kontejneru. Obrázky mají velké množství průhledného pozadí, aby byly lépe přetahovatelné, takže je třeba je posunout doleva, aby lépe zapadly na obrazovku.
Poté je samotné rostlině dána maximální šířka 150 %. To jí umožňuje zmenšit se, jak se prohlížeč zmenšuje. Zkuste změnit velikost prohlížeče; rostliny zůstávají ve svých kontejnerech, ale zmenšují se, aby se vešly.
Rostlina samotná má maximální šířku 150 %. To jí umožňuje zmenšovat se, jak se zmenšuje prohlížeč. Zkuste změnit velikost prohlížeče; rostliny zůstávají ve svých kontejnerech, ale zmenšují se, aby se přizpůsobily.
Také je pozoruhodné použití z-indexu, který ovládá relativní výšku prvku (takže rostliny sedí na vrcholu kontejneru a vypadají, že sedí uvnitř terrária).
Pozoruhodné je také použití z-indexu, který ovládá relativní výšku prvku (takže rostliny sedí na kontejneru a vypadají, že jsou uvnitř terrária).
✅ Proč potřebujete jak selektor pro držák rostlin, tak selektor pro rostlinu?
✅ Proč potřebujete jak selektor `plant-holder`, tak selektor `plant`?
## Pozicování CSS
Míchání vlastností pozicování (existují statické, relativní, pevné, absolutní a lepivé pozice) může být trochu složité, ale pokud je provedeno správně, dává vám dobrou kontrolu nad prvky na vašich stránkách.
Míchání vlastností pozicování (existují statické, relativní, pevné, absolutní a lepivé pozice) může být trochu složité, ale pokud je provedeno správně, poskytuje vám dobrou kontrolu nad prvky na vašich stránkách.
Absolutně pozicované prvky jsou pozicovány relativně k jejich nejbližším pozicovaným předkům, a pokud žádní nejsou, jsou pozicovány podle těla dokumentu.
Absolutně pozicované prvky jsou umístěny relativně k jejich nejbližšímu pozicovanému předkovi, a pokud žádný není, jsou umístěny podle těla dokumentu.
Relativně pozicované prvky jsou pozicovány na základě pokynů CSS, které upravují jejich umístění od jejich počáteční pozice.
Relativně pozicované prvky jsou umístěny na základě pokynů CSS, aby se posunuly od své původní pozice.
V našem příkladu je `plant-holder` relativně pozicovaný prvek, který je pozicován uvnitř absolutně pozicovaného kontejneru. Výsledné chování je, že postranní kontejnery jsou připnuty vlevo a vpravo, a `plant-holder` je vnořený, upravující se uvnitř postranních kontejnerů, čímž vytváří prostor pro rostliny, aby byly umístěny ve vertikálním sloupci.
V našem příkladu je `plant-holder` relativně pozicovaný prvek, který je umístěn v absolutně pozicovaném kontejneru. Výsledné chování je, že postranní kontejnery jsou připnuty vlevo a vpravo, a `plant-holder` je vnořený, přizpůsobující se v rámci postranních kontejnerů, čímž vytváří prostor pro rostliny, aby byly umístěny ve vertikálním sloupci.
> Samotná `plant` má také absolutní pozicování, což je nezbytné pro její přetahovatelnost, jak zjistíte v další lekci.
> Samotná `plant` má také absolutní pozicování, což je nezbytné pro to, aby byla přetahovatelná, jak zjistíte v další lekci.
✅ Experimentujte s přepínáním typů pozicování postranních kontejnerů a `plant-holder`. Co se stane?
## Rozvržení CSS
Nyní použijete, co jste se naučili, k vytvoření samotného terrária, vše pomocí CSS!
Nyní použijete to, co jste se naučili, k vytvoření samotného terrária, a to vše pomocí CSS!
Nejprve stylujte děti divu `.terrarium` jako zaoblený obdélník pomocí CSS:
@ -250,17 +250,17 @@ Nejprve stylujte děti divu `.terrarium` jako zaoblený obdélník pomocí CSS:
}
```
Všimněte si použití procent zde. Pokud zmenšíte svůj prohlížeč, můžete vidět, jak se nádoba také zmenšuje. Také si všimněte šířek a výšek procent pro prvky nádoby a jak je každý prvek absolutně pozicován ve středu, připnutý ke spodní části viewportu.
Všimněte si použití procent zde. Pokud zmenšíte svůj prohlížeč, můžete vidět, jak se sklenice také zmenšuje. Všimněte si také šířek a výšek v procentech pro prvky sklenice a jak je každý prvek absolutně umístěn ve středu, připnutý ke spodní části zobrazení.
Používáme také `rem` pro border-radius, což je délka relativní k fontu. Přečtěte si více o tomto typu relativního měření ve [specifikaci CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
✅ Zkuste změnit barvy nádoby a její průhlednost oproti barvám hlíny. Co se stane? Proč?
✅ Zkuste změnit barvy a průhlednost sklenice oproti těm u hlíny. Co se stane? Proč?
---
## 🚀Výzva
Přidejte "bublinkový" lesk do levé spodní oblasti nádoby, aby vypadala více jako skleněná. Budete stylovat `.jar-glossy-long` a `.jar-glossy-short`, aby vypadaly jako odražený lesk. Takto by to mělo vypadat:
Přidejte „bublinkový“ lesk do levé spodní části sklenice, aby vypadala více jako sklo. Budete stylovat `.jar-glossy-long` a `.jar-glossy-short`, aby vypadaly jako odražený lesk. Takto by to mělo vypadat:
@ -272,13 +272,13 @@ Pro dokončení kvízu po lekci projděte tento modul Learn: [Stylování HTML a
## Recenze a samostudium
CSS se zdá být klamně jednoduché, ale existuje mnoho výzev při pokusu o stylování aplikace dokonale pro všechny prohlížeče a všechny velikosti obrazovek. CSS-Grid a Flexbox jsou nástroje, které byly vyvinuty, aby byla práce trochu strukturovanější a spolehlivější. Naučte se o těchto nástrojích hraním [Flexbox Froggy](https://flexboxfroggy.com/) a [Grid Garden](https://codepip.com/games/grid-garden/).
CSS se může zdát klamně jednoduché, ale při pokusu o dokonalé stylování aplikace pro všechny prohlížeče a všechny velikosti obrazovek se objevuje mnoho výzev. CSS-Grid a Flexbox jsou nástroje, které byly vyvinuty, aby tuto práci učinily strukturovanější a spolehlivější. Naučte se o těchto nástrojích hraním [Flexbox Froggy](https://flexboxfroggy.com/) a [Grid Garden](https://codepip.com/games/grid-garden/).
## Zadání
[Refaktorování CSS](assignment.md)
[Refaktoring CSS](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby AI pro překlady [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za závazný zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Manipulace s DOM, neboli "Document Object Model", je klíčovým aspektem vývoje webu. Podle [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) je "Document Object Model (DOM) datovou reprezentací objektů, které tvoří strukturu a obsah dokumentu na webu." Výzvy spojené s manipulací s DOM na webu často vedly k používání JavaScriptových frameworků namísto čistého JavaScriptu pro správu DOM, ale my si vystačíme sami!
Kromě toho tato lekce představí koncept [JavaScriptového uzávěru](https://developer.mozilla.org/docs/Web/JavaScript/Closures), který si můžete představit jako funkci uzavřenou jinou funkcí, takže vnitřní funkce má přístup k rozsahu vnější funkce.
Kromě toho tato lekce představí koncept [JavaScriptového uzávěru](https://developer.mozilla.org/docs/Web/JavaScript/Closures), což si můžete představit jako funkci uzavřenou jinou funkcí, takže vnitřní funkce má přístup k rozsahu vnější funkce.
> JavaScriptové uzávěry jsou rozsáhlé a složité téma. Tato lekce se dotýká pouze základní myšlenky, že v kódu tohoto terrária najdete uzávěr: vnitřní funkci a vnější funkci, které jsou konstruovány tak, aby vnitřní funkce měla přístup k rozsahu vnější funkce. Pro mnohem více informací o tom, jak to funguje, navštivte [rozsáhlou dokumentaci](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
@ -40,7 +40,7 @@ Měli byste mít vytvořený HTML a CSS pro vaše terrárium. Na konci této lek
### Úkol
Ve složce terrária vytvořte nový soubor s názvem `script.js`. Tento soubor importujte do sekce `<head>`:
Ve složce terrária vytvořte nový soubor s názvem `script.js`. Importujte tento soubor do sekce `<head>`:
Co se zde děje? Odkazujete na dokument a procházíte jeho DOM, abyste našli prvek s konkrétním Id. Pamatujete si, že jste v první lekci o HTML přiřadili jednotlivá Id ke každému obrázku rostliny (`id="plant1"`)? Nyní tuto práci využijete. Po identifikaci každého prvku předáte tento prvek funkci `dragElement`, kterou za chvíli vytvoříte. Tím se prvek v HTML stane přetahovatelným, nebo brzy bude.
Co se zde děje? Odkazujete na dokument a procházíte jeho DOM, abyste našli prvek s konkrétním Id. Pamatujete si, že jste v první lekci o HTML přiřadili jednotlivá Id každému obrázku rostliny (`id="plant1"`)? Nyní tuto práci využijete. Po identifikaci každého prvku předáte tuto položku funkci `dragElement`, kterou za chvíli vytvoříte. Tím se prvek v HTML stane přetahovatelným, nebo brzy bude.
✅ Proč odkazujeme na prvky podle Id? Proč ne podle jejich CSS třídy? Můžete se vrátit k předchozí lekci o CSS, abyste na tuto otázku odpověděli.
@ -80,7 +80,7 @@ Co se zde děje? Odkazujete na dokument a procházíte jeho DOM, abyste našli p
## Uzávěr
Nyní jste připraveni vytvořit uzávěr `dragElement`, což je vnější funkce, která uzavírá vnitřní funkci nebo funkce (v našem případě budou tři).
Nyní jste připraveni vytvořit uzávěr `dragElement`, což je vnější funkce, která uzavírá vnitřní funkci nebo funkce (v našem případě budeme mít tři).
Uzávěry jsou užitečné, když jedna nebo více funkcí potřebuje přístup k rozsahu vnější funkce. Zde je příklad:
@ -115,11 +115,11 @@ function dragElement(terrariumElement) {
}
```
`dragElement` získá svůj objekt `terrariumElement` z deklarací na začátku skriptu. Poté nastavíte některé lokální pozice na `0` pro objekt předaný do funkce. Tyto lokální proměnné budou manipulovány pro každý prvek, jakmile přidáte funkčnost přetahování a upouštění v rámci uzávěru pro každý prvek. Terrárium bude naplněno těmito přetaženými prvky, takže aplikace musí sledovat, kam jsou umístěny.
`dragElement` získá svůj objekt `terrariumElement` z deklarací na začátku skriptu. Poté nastavíte některé lokální pozice na `0` pro objekt předaný do funkce. Tyto lokální proměnné budou manipulovány pro každý prvek, jakmile přidáte funkčnost přetahování a upouštění v rámci uzávěru pro každý prvek. Terrárium bude naplněno těmito přetahovanými prvky, takže aplikace musí sledovat, kam jsou umístěny.
Kromě toho je prvku `terrariumElement`, který je předán této funkci, přiřazena událost `pointerdown`, která je součástí [webových API](https://developer.mozilla.org/docs/Web/API) navržených pro správu DOM. `onpointerdown` se spustí, když je stisknuto tlačítko nebo v našem případě je dotčen přetahovatelný prvek. Tento obslužný program událostí funguje jak na [webových, tak mobilních prohlížečích](https://caniuse.com/?search=onpointerdown), s několika výjimkami.
Kromě toho je prvku `terrariumElement`, který je předán této funkci, přiřazena událost `pointerdown`, která je součástí [webových API](https://developer.mozilla.org/docs/Web/API) navržených pro pomoc s manipulací s DOM. `onpointerdown` se spustí, když je stisknuto tlačítko, nebo v našem případě, když je dotčen přetahovatelný prvek. Tento obslužný program událostí funguje jak na [webových, tak mobilních prohlížečích](https://caniuse.com/?search=onpointerdown), s několika výjimkami.
✅ [Obslužný program událostí `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) má mnohem větší podporu napříč prohlížeči; proč byste jej zde nepoužili? Zamyslete se nad konkrétním typem interakce, kterou se snažíte vytvořit.
✅ [Obslužný program událostí `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) má mnohem větší podporu napříč prohlížeči; proč byste jej zde nepoužili? Přemýšlejte o přesném typu interakce, kterou se snažíte vytvořit.
---
@ -140,13 +140,13 @@ function pointerDrag(e) {
Děje se několik věcí. Nejprve zabráníte výchozím událostem, které by normálně nastaly při pointerdown, pomocí `e.preventDefault();`. Tím získáte větší kontrolu nad chováním rozhraní.
> Vraťte se k tomuto řádku, až budete mít skript kompletně vytvořen, a zkuste to bez `e.preventDefault()` - co se stane?
> Vraťte se k tomuto řádku, až budete mít skriptový soubor kompletně vytvořený, a zkuste to bez `e.preventDefault()` - co se stane?
Za druhé, otevřete `index.html` v okně prohlížeče a zkontrolujte rozhraní. Když kliknete na rostlinu, můžete vidět, jak je událost 'e' zachycena. Prozkoumejte událost a podívejte se, kolik informací je shromážděno jednou událostí pointerdown!
Za druhé, otevřete `index.html` v okně prohlížeče a zkontrolujte rozhraní. Když kliknete na rostlinu, můžete vidět, jak je událost 'e' zachycena. Prozkoumejte událost, abyste viděli, kolik informací je shromážděno jednou událostí pointerdown!
Dále si všimněte, jak jsou lokální proměnné `pos3` a `pos4` nastaveny na e.clientX. Tyto hodnoty můžete najít v inspekčním panelu. Tyto hodnoty zachycují souřadnice x a y rostliny v okamžiku, kdy na ni kliknete nebo se jí dotknete. Budete potřebovat jemnou kontrolu nad chováním rostlin při jejich klikání a přetahování, takže sledujete jejich souřadnice.
✅ Je stále jasnější, proč je celá tato aplikace postavena na jednom velkém uzávěru? Pokud by tomu tak nebylo, jak byste udrželi rozsah pro každou ze 14 přetahovatelných rostlin?
✅ Je stále jasnější, proč je celá tato aplikace postavena na jednom velkém uzávěru? Pokud by tomu tak nebylo, jak byste udrželi rozsah pro každou z 14 přetahovatelných rostlin?
Dokončete počáteční funkci přidáním dalších dvou manipulací událostí pointer pod `pos4 = e.clientY`:
@ -154,11 +154,11 @@ Dokončete počáteční funkci přidáním dalších dvou manipulací událost
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
Nyní naznačujete, že chcete, aby se rostlina pohybovala spolu s ukazatelem, jakmile ji přetáhnete, a aby se gesto přetahování zastavilo, když rostlinu odznačíte. `onpointermove` a `onpointerup` jsou všechny součástí stejného API jako `onpointerdown`. Rozhraní nyní bude házet chyby, protože jste dosud nedefinovali funkce `elementDrag` a `stopElementDrag`, takže je vytvořte jako další.
Nyní naznačujete, že chcete, aby se rostlina přetahovala spolu s ukazatelem, jakmile ji přesunete, a aby se gesto přetahování zastavilo, když rostlinu odznačíte. `onpointermove` a `onpointerup` jsou všechny součástí stejného API jako `onpointerdown`. Rozhraní nyní bude házet chyby, protože jste dosud nedefinovali funkce `elementDrag` a `stopElementDrag`, takže je vytvořte jako další.
## Funkce elementDrag a stopElementDrag
Uzávěr dokončíte přidáním dalších dvou vnitřních funkcí, které budou řešit, co se stane, když přetahujete rostlinu a přestanete ji přetahovat. Chování, které chcete, je, že můžete kdykoli přetáhnout jakoukoli rostlinu a umístit ji kamkoli na obrazovku. Toto rozhraní je poměrně neomezené (například zde není žádná zóna pro upuštění), aby vám umožnilo navrhnout vaše terrárium přesně podle vašich představ přidáváním, odebíráním a přemisťováním rostlin.
Uzávěr dokončíte přidáním dalších dvou vnitřních funkcí, které budou řešit, co se stane, když přetahujete rostlinu a přestanete ji přetahovat. Chování, které chcete, je, že můžete kdykoli přetáhnout jakoukoli rostlinu a umístit ji kamkoli na obrazovku. Toto rozhraní je poměrně neomezující (například neexistuje žádná zóna pro upuštění), aby vám umožnilo navrhnout vaše terrárium přesně podle vašich představ přidáváním, odstraňováním a přemísťováním rostlin.
### Úkol
@ -177,7 +177,7 @@ function elementDrag(e) {
```
V této funkci provádíte mnoho úprav počátečních pozic 1-4, které jste nastavili jako lokální proměnné ve vnější funkci. Co se zde děje?
Při přetahování znovu přiřazujete `pos1` tak, že jej nastavíte na hodnotu `pos3` (kterou jste dříve nastavili jako `e.clientX`) minus aktuální hodnotu `e.clientX`. Podobnou operaci provádíte s `pos2`. Poté resetujete `pos3` a `pos4` na nové souřadnice X a Y prvku. Tyto změny můžete sledovat v konzoli při přetahování. Poté manipulujete s CSS stylem rostliny, abyste nastavili její novou pozici na základě nových pozic `pos1` a `pos2`, přičemž vypočítáváte souřadnice X a Y rostliny na základě porovnání jejího offsetu s těmito novými pozicemi.
Při přetahování znovu přiřazujete `pos1` tak, že jej nastavíte na `pos3` (které jste dříve nastavili jako `e.clientX`) minus aktuální hodnotu `e.clientX`. Podobnou operaci provádíte s `pos2`. Poté resetujete `pos3` a `pos4` na nové souřadnice X a Y prvku. Tyto změny můžete sledovat v konzoli při přetahování. Poté manipulujete s CSS stylem rostliny, abyste nastavili její novou pozici na základě nových pozic `pos1` a `pos2`, přičemž vypočítáváte horní a levé souřadnice X a Y rostliny na základě porovnání jejího offsetu s těmito novými pozicemi.
> `offsetTop` a `offsetLeft` jsou vlastnosti CSS, které nastavují pozici prvku na základě jeho rodiče; jeho rodičem může být jakýkoli prvek, který není pozicován jako `static`.
@ -206,13 +206,13 @@ Nyní jste dokončili svůj projekt!
## 🚀Výzva
Přidejte nový obslužný program událostí do svého uzávěru, aby rostliny dělaly něco navíc; například dvojitým kliknutím na rostlinu ji přesuňte do popředí. Buďte kreativní!
Přidejte nový obslužný program událostí do svého uzávěru, aby rostliny dělaly něco dalšího; například dvojitým kliknutím na rostlinu ji přesuňte do popředí. Buďte kreativní!
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/20)
## Přehled a samostudium
## Recenze a samostudium
I když se přetahování prvků po obrazovce může zdát triviální, existuje mnoho způsobů, jak to udělat, a mnoho úskalí, v závislosti na efektu, kterého chcete dosáhnout. Ve skutečnosti existuje celé [API pro přetahování a upouštění](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API), které můžete vyzkoušet. V tomto modulu jsme jej nepoužili, protože efekt, který jsme chtěli, byl poněkud odlišný, ale zkuste toto API na svém vlastním projektu a uvidíte, čeho můžete dosáhnout.
@ -227,4 +227,4 @@ Vždy kontrolujte schopnosti prohlížečů pomocí [CanIUse.com](https://canius
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/21)
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/21)
## Programování řízené událostmi
Při vytváření aplikace pro prohlížeč poskytujeme grafické uživatelské rozhraní (GUI), které uživatel používá při interakci s tím, co jsme vytvořili. Nejčastějším způsobem interakce s prohlížečem je klikání a psaní do různých prvků. Výzvou pro nás jako vývojáře je, že nevíme, kdy uživatel tyto operace provede!
Při vytváření aplikace prohlížeče poskytujeme uživateli grafické uživatelské rozhraní (GUI), které může použít při interakci s tím, co jsme vytvořili. Nejčastějším způsobem interakce s prohlížečem je klikání a psaní do různých prvků. Výzvou, které čelíme jako vývojáři, je, že nevíme, kdy tyto operace provedou!
[Programování řízené událostmi](https://en.wikipedia.org/wiki/Event-driven_programming) je název pro typ programování, který potřebujeme k vytvoření našeho GUI. Pokud tento termín trochu rozebereme, zjistíme, že klíčovým slovem je **událost**. [Událost](https://www.merriam-webster.com/dictionary/event), podle Merriam-Webster, je definována jako „něco, co se stane“. To dokonale popisuje naši situaci. Víme, že se něco stane, na co chceme reagovat spuštěním kódu, ale nevíme, kdy k tomu dojde.
[Programování řízené událostmi](https://en.wikipedia.org/wiki/Event-driven_programming) je název pro typ programování, který potřebujeme k vytvoření našeho GUI. Pokud tuto frázi trochu rozebereme, zjistíme, že klíčovým slovem je zde **událost**. [Událost](https://www.merriam-webster.com/dictionary/event) je podle Merriam-Webster definována jako „něco, co se stane“. To dokonale popisuje naši situaci. Víme, že se něco stane, na co chceme reagovat spuštěním kódu, ale nevíme, kdy k tomu dojde.
Část kódu, kterou chceme spustit, označíme vytvořením funkce. Když přemýšlíme o [procedurálním programování](https://en.wikipedia.org/wiki/Procedural_programming), funkce se volají v konkrétním pořadí. Totéž platí pro programování řízené událostmi. Rozdíl je v tom, **jak** se funkce volají.
Část kódu, kterou chceme spustit, označíme vytvořením funkce. Když přemýšlíme o [procedurálním programování](https://en.wikipedia.org/wiki/Procedural_programming), funkce se volají ve specifickém pořadí. Totéž platí i pro programování řízené událostmi. Rozdíl je v tom, **jak** budou funkce volány.
Pro zpracování událostí (klikání na tlačítka, psaní atd.) registrujeme **posluchače událostí**. Posluchač událostí je funkce, která čeká na to, až dojde k události, a poté se spustí. Posluchači událostí mohou aktualizovat uživatelské rozhraní, provádět volání na server nebo dělat cokoli jiného, co je potřeba v reakci na akci uživatele. Posluchače událostí přidáváme pomocí [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) a poskytujeme funkci, která se má spustit.
Pro zpracování událostí (klikání na tlačítka, psaní atd.) registrujeme **posluchače událostí**. Posluchač událostí je funkce, která čeká na výskyt události a reaguje na ni spuštěním kódu. Posluchači událostí mohou aktualizovat uživatelské rozhraní, provádět volání na server nebo cokoliv jiného, co je potřeba udělat v reakci na akci uživatele. Posluchače událostí přidáváme pomocí [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) a poskytnutím funkce, která se má spustit.
> **NOTE:** Stojí za zmínku, že existuje mnoho způsobů, jak vytvořit posluchače událostí. Můžete použít anonymní funkce nebo vytvořit pojmenované. Můžete použít různé zkratky, jako je nastavení vlastnosti `click`, nebo použít `addEventListener`. V našem cvičení se zaměříme na `addEventListener` a anonymní funkce, protože je to pravděpodobně nejběžnější technika, kterou weboví vývojáři používají. Je také nejflexibilnější, protože `addEventListener` funguje pro všechny události a název události lze poskytnout jako parametr.
> **NOTE:** Stojí za zmínku, že existuje mnoho způsobů, jak vytvořit posluchače událostí. Můžete použít anonymní funkce nebo vytvořit pojmenované. Můžete použít různé zkratky, jako je nastavení vlastnosti `click`, nebo použít `addEventListener`. V našem cvičení se zaměříme na `addEventListener` a anonymní funkce, protože je to pravděpodobně nejběžnější technika, kterou weboví vývojáři používají. Je také nejflexibilnější, protože `addEventListener` funguje pro všechny události a název události lze zadat jako parametr.
### Běžné události
Existuje [desítky událostí](https://developer.mozilla.org/docs/Web/Events), které můžete použít při vytváření aplikace. Prakticky vše, co uživatel na stránce udělá, vyvolá událost, což vám dává velkou moc zajistit, že dostane požadovaný zážitek. Naštěstí obvykle budete potřebovat jen několik málo událostí. Zde je několik běžných (včetně dvou, které použijeme při vytváření naší hry):
Existuje [desítky událostí](https://developer.mozilla.org/docs/Web/Events), které můžete poslouchat při vytváření aplikace. Prakticky cokoliv, co uživatel na stránce udělá, vyvolá událost, což vám dává velkou moc zajistit, že dostane požadovaný zážitek. Naštěstí obvykle budete potřebovat jen malý počet událostí. Zde je několik běžných (včetně dvou, které použijeme při vytváření naší hry):
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): Uživatel kliknul na něco, obvykle na tlačítko nebo odkaz
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): Uživatel označil nějaký text
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): Uživatel zadal nějaký text
## Vytvoření hry
Vytvoříme hru, abychom prozkoumali, jak události fungují v JavaScriptu. Naše hra otestuje schopnost hráče psát na klávesnici, což je jedna z nejvíce podceňovaných dovedností, kterou by měl mít každý vývojář. Všichni bychom měli trénovat psaní! Obecný průběh hry bude vypadat takto:
Vytvoříme hru, abychom prozkoumali, jak události fungují v JavaScriptu. Naše hra otestuje schopnost hráče psát, což je jedna z nejvíce podceňovaných dovedností, kterou by měl mít každý vývojář. Všichni bychom měli trénovat psaní! Obecný průběh hry bude vypadat takto:
- Hráč klikne na tlačítko start a zobrazí se mu citát, který má napsat
- Hráč klikne na tlačítko start a zobrazí se mu citát k opsání
- Hráč co nejrychleji napíše citát do textového pole
- Jakmile dokončí každé slovo, další se zvýrazní
- Pokud hráč udělá chybu, textové pole se zbarví červeně
- Jakmile dokončí jedno slovo, další se zvýrazní
- Pokud hráč udělá překlep, textové pole se zbarví červeně
- Když hráč dokončí citát, zobrazí se zpráva o úspěchu s uplynulým časem
Pojďme hru vytvořit a naučit se něco o událostech!
Pojďme vytvořit naši hru a naučit se něco o událostech!
### Struktura souborů
Budeme potřebovat celkem tři soubory: **index.html**, **script.js** a **style.css**. Začněme jejich nastavením, abychom si práci trochu usnadnili.
Budeme potřebovat celkem tři soubory: **index.html**, **script.js** a **style.css**. Začněme jejich nastavením, abychom si usnadnili práci.
- Vytvořte novou složku pro svou práci otevřením konzole nebo terminálového okna a zadáním následujícího příkazu:
- Vytvořte novou složku pro svou práci otevřením konzole nebo terminálu a zadáním následujícího příkazu:
```bash
# Linux or macOS
@ -75,12 +75,12 @@ code .
Pokud prozkoumáme požadavky, víme, že budeme potřebovat několik prvků na naší HTML stránce. Je to něco jako recept, kde potřebujeme nějaké ingredience:
- Místo pro zobrazení citátu, který má uživatel napsat
- Místo pro zobrazení zpráv, například zprávy o úspěchu
- Místo pro zobrazení citátu, který má uživatel opsat
- Místo pro zobrazení zpráv, jako je zpráva o úspěchu
- Textové pole pro psaní
- Tlačítko start
Každý z těchto prvků bude potřebovat ID, abychom s nimi mohli pracovat v našem JavaScriptu. Také přidáme odkazy na CSS a JavaScriptové soubory, které vytvoříme.
Každý z těchto prvků bude potřebovat ID, abychom s nimi mohli pracovat v našem JavaScriptu. Přidáme také odkazy na soubory CSS a JavaScript, které vytvoříme.
Vytvořte nový soubor s názvem **index.html**. Přidejte následující HTML:
@ -107,10 +107,10 @@ Vytvořte nový soubor s názvem **index.html**. Přidejte následující HTML:
### Spuštění aplikace
Vždy je nejlepší vyvíjet iterativně, abychom viděli, jak věci vypadají. Spusťme naši aplikaci. Ve Visual Studio Code je skvělý rozšíření nazvané [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), které bude hostovat vaši aplikaci lokálně a aktualizovat prohlížeč pokaždé, když uložíte.
Vždy je nejlepší vyvíjet iterativně, abychom viděli, jak věci vypadají. Spusťme naši aplikaci. Existuje skvělý doplněk pro Visual Studio Code s názvem [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), který bude hostovat vaši aplikaci lokálně a aktualizovat prohlížeč pokaždé, když uložíte.
- Nainstalujte [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) podle odkazu a klikněte na **Install**
- Prohlížeč vás vyzve k otevření Visual Studio Code, a poté vás Visual Studio Code vyzve k provedení instalace
- Nainstalujte [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) podle odkazu a kliknutím na **Install**
- Prohlížeč vás vyzve k otevření Visual Studio Code a poté vás Visual Studio Code vyzve k provedení instalace
- Restartujte Visual Studio Code, pokud budete vyzváni
- Po instalaci klikněte ve Visual Studio Code na Ctrl-Shift-P (nebo Cmd-Shift-P) pro otevření příkazové palety
- Zadejte **Live Server: Open with Live Server**
@ -118,13 +118,13 @@ Vždy je nejlepší vyvíjet iterativně, abychom viděli, jak věci vypadají.
- Otevřete prohlížeč a přejděte na **https://localhost:5500**
- Nyní byste měli vidět stránku, kterou jste vytvořili!
Přidejme nějakou funkčnost.
Přidejme nějakou funkcionalitu.
## Přidání CSS
S naším HTML vytvořeným přidáme CSS pro základní stylování. Potřebujeme zvýraznit slovo, které by měl hráč psát, a zbarvit textové pole, pokud to, co napsal, není správné. Uděláme to pomocí dvou tříd.
S naším HTML vytvořeným přidáme CSS pro základní stylování. Potřebujeme zvýraznit slovo, které by měl hráč psát, a obarvit textové pole, pokud to, co napsal, není správné. To uděláme pomocí dvou tříd.
Vytvořte nový soubor s názvem **style.css** a přidejte následující syntax.
Vytvořte nový soubor s názvem **style.css** a přidejte následující syntaxi.
```css
/* inside style.css */
@ -138,10 +138,10 @@ Vytvořte nový soubor s názvem **style.css** a přidejte následující syntax
}
```
✅ Co se týče CSS, můžete si stránku uspořádat podle svého. Věnujte trochu času tomu, aby stránka vypadala atraktivněji:
✅ Co se týče CSS, můžete si stránku rozvrhnout, jak chcete. Věnujte trochu času a udělejte stránku vizuálně přitažlivější:
- Vyberte jiný font
- Zbarvěte nadpisy
- Obarvěte nadpisy
- Změňte velikost prvků
## JavaScript
@ -152,18 +152,18 @@ S naším uživatelským rozhraním vytvořeným je čas zaměřit naši pozorno
- [Posluchač událostí pro spuštění hry](../../../../4-typing-game/typing-game)
- [Posluchač událostí pro psaní](../../../../4-typing-game/typing-game)
Nejprve však vytvořte nový soubor s názvem **script.js**.
Nejprve ale vytvořte nový soubor s názvem **script.js**.
### Přidání konstant
Budeme potřebovat několik položek, které nám usnadní programování. Opět, podobně jako recept, zde je, co budeme potřebovat:
Budeme potřebovat několik položek, které nám usnadní programování. Opět, podobně jako recept, zde je to, co budeme potřebovat:
- Pole se seznamem všech citátů
- Prázdné pole pro uložení všech slov aktuálního citátu
- Prostor pro uložení indexu slova, které hráč právě píše
- Čas, kdy hráč kliknul na start
- Prostor pro uložení indexu slova, které hráč aktuálně píše
- Čas, kdy hráč klikl na start
Také budeme chtít odkazy na prvky uživatelského rozhraní:
Budeme také chtít odkazy na prvky uživatelského rozhraní:
> **NOTE:** Prvky můžeme kdykoli v kódu získat pomocí `document.getElementById`. Protože tyto prvky budeme pravidelně odkazovat, vyhneme se překlepům v řetězcových literálech použitím konstant. Frameworky jako [Vue.js](https://vuejs.org/) nebo [React](https://reactjs.org/) vám mohou pomoci lépe centralizovat váš kód.
> **NOTE:** Prvky můžeme kdykoliv v kódu získat pomocí `document.getElementById`. Protože se na tyto prvky budeme pravidelně odkazovat, vyhneme se překlepům ve stringových literálech použitím konstant. Frameworky jako [Vue.js](https://vuejs.org/) nebo [React](https://reactjs.org/) vám mohou pomoci lépe centralizovat váš kód.
Věnujte chvíli sledování videa o používání `const`, `let` a `var`
Podívejte se na video o používání `const`, `let` a `var`
@ -204,9 +204,9 @@ Věnujte chvíli sledování videa o používání `const`, `let` a `var`
### Přidání logiky spuštění
Pro zahájení hry hráč klikne na start. Samozřejmě nevíme, kdy klikne na start. Zde přichází na řadu [posluchač událostí](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Posluchač událostí nám umožní čekat na to, až se něco stane (událost), a spustit kód v reakci. V našem případě chceme spustit kód, když uživatel klikne na start.
Pro spuštění hry hráč klikne na start. Samozřejmě nevíme, kdy na start klikne. Zde přichází na řadu [posluchač událostí](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Posluchač událostí nám umožní poslouchat, kdy se něco stane (událost), a reagovat na to spuštěním kódu. V našem případě chceme spustit kód, když uživatel klikne na start.
Když uživatel klikne na **start**, musíme vybrat citát, nastavit uživatelské rozhraní a nastavit sledování aktuálního slova a času. Níže je JavaScript, který budete potřebovat přidat; rozebereme ho hned po bloku skriptu.
Když uživatel klikne na **start**, musíme vybrat citát, nastavit uživatelské rozhraní a připravit sledování aktuálního slova a času. Níže je JavaScript, který budete muset přidat; rozebereme ho hned po bloku skriptu.
- Použití [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) a [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random) nám umožní náhodně vybrat citát z pole `quotes`
- Citát převedeme na pole `words`, abychom mohli sledovat slovo, které hráč právě píše
- `wordIndex` nastavíme na 0, protože hráč začne na prvním slově
- Převádíme `quote` na pole `words`, abychom mohli sledovat slovo, které hráč aktuálně píše
- `wordIndex`je nastaven na 0, protože hráč začne na prvním slově
- Nastavení uživatelského rozhraní
- Vytvoříme pole `spanWords`, které obsahuje každé slovo uvnitř prvku `span`
- To nám umožní zvýraznit slovo na displeji
- `join` pole vytvoří řetězec, který můžeme použít k aktualizaci `innerHTML` na `quoteElement`
- `join` pole pro vytvoření řetězce, který můžeme použít k aktualizaci `innerHTML` na `quoteElement`
- To zobrazí citát hráči
- Nastavíme `className` prvního prvku `span` na `highlight`, aby byl zvýrazněn žlutě
- Vyčistíme `messageElement` nastavením `innerText` na `''`
@ -261,7 +261,7 @@ Rozeberme kód!
### Přidání logiky psaní
Jak hráč píše, vyvolá se událost `input`. Tento posluchač událostí zkontroluje, zda hráč píše slovo správně, a zpracuje aktuální stav hry. Vraťte se do **script.js** a přidejte následující kód na konec. Rozebereme ho hned poté.
Jak hráč píše, bude vyvolána událost `input`. Tento posluchač událostí zkontroluje, zda hráč píše slovo správně, a zpracuje aktuální stav hry. Vraťte se do **script.js** a přidejte následující kód na konec. Rozebereme ho poté.
Rozeberme kód! Začneme tím, že získáme aktuální slovo a hodnotu, kterou hráč dosud napsal. Poté máme logiku typu „vodopád“, kde kontrolujeme, zda je citát dokončen, slovo je dokončeno, slovo je správné, nebo (nakonec), zda je chyba.
Rozeberme si kód! Začínáme tím, že získáme aktuální slovo a hodnotu, kterou hráč dosud napsal. Poté máme logiku ve stylu vodopádu, kde kontrolujeme, zda je citát dokončen, slovo dokončeno, slovo správné nebo (nakonec), zda je tam chyba.
- Citát je dokončen, což je indikováno tím, že `typedValue` je rovno `currentWord` a `wordIndex` je rovno jednomu méně než `length``words`
- Vypočítáme `elapsedTime` odečtením `startTime` od aktuálního času
- `elapsedTime` vydělíme 1 000, abychom převedli z milisekund na sekundy
- Dělíme `elapsedTime` 1 000, abychom převedli z milisekund na sekundy
- Zobrazíme zprávu o úspěchu
- Slovo je dokončeno, což je indikováno tím, že `typedValue` končí mezerou (konec slova) a `typedValue` je rovno `currentWord`
- Nastavíme `value` na `typedElement` na `''`, aby bylo možné napsat další slovo
- Nastavíme `value` na `typedElement` na `''`, abychom umožnili psaní dalšího slova
- Zvýšíme `wordIndex`, abychom přešli na další slovo
- Projdeme všechny `childNodes``quoteElement` a nastavíme `className` na `''`, abychom obnovili výchozí zobrazení
- Nastavíme `className` aktuálního slova na `highlight`, abychom ho označili jako další slovo k napsání
@ -318,9 +318,9 @@ Rozeberme kód! Začneme tím, že získáme aktuální slovo a hodnotu, kterou
## Otestujte svou aplikaci
Dostali jste se na konec! Posledním krokem je zajistit, aby naše aplikace fungovala. Vyzkoušejte ji! Nebojte se, pokud jsou tam chyby; **všichni vývojáři** mají chyby. Prozkoumejte zprávy a laděte podle potřeby.
Dostali jste se na konec! Posledním krokem je zajistit, aby naše aplikace fungovala. Vyzkoušejte ji! Nebojte se, pokud se objeví chyby; **všichni vývojáři** mají chyby. Prozkoumejte zprávy a laděte podle potřeby.
Klikněte na **start** a začněte psát! Mělo by to vypadat trochu jako animace, kterou jsme viděli předtím.
Klikněte na **start** a začněte psát! Mělo by to vypadat trochu jako animace, kterou jsme viděli dříve.

@ -328,20 +328,19 @@ Klikněte na **start** a začněte psát! Mělo by to vypadat trochu jako animac
## 🚀 Výzva
Přidejte více funkcí
Přidejte více funkcionality
- Deaktivujte posluchač událostí `input` po dokončení a znovu ho aktivujte, když se klikne na tlačítko
- Deaktivujte posluchač událostí `input` po dokončení a znovu ho aktivujte, když je kliknuto na tlačítko
- Deaktivujte textové pole, když hráč dokončí citát
- Zobrazte modální dialogové okno se zprávou o úspěchu
- Ukládejte nejvyšší skóre pomocí [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
- Ukládejte nejlepší skóre pomocí [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
## Kvíz po přednášce
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/22)
## Přehled & Samostudium
## Přehled a samostudium
Přečtěte si o [všech dostupných událostech](https://developer.mozilla.org/docs/Web/Events) pro vývojáře prostřednictvím webového prohlížeče a zamyslete se nad scénáři, ve kterých byste každou z nich použili.
Projděte si [všechny dostupné události](https://developer.mozilla.org/docs/Web/Events), které má vývojář k dispozici prostřednictvím webového prohlížeče, a zamyslete se nad situacemi, ve kterých byste každou z nich použili.
## Úkol
@ -350,4 +349,4 @@ Přečtěte si o [všech dostupných událostech](https://developer.mozilla.org/
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby AI pro překlady [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby AI pro překlady [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
> Sketchnote od [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
## Kvíz před přednáškou
## Kvíz před lekcí
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/23)
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/23)
### Úvod
@ -22,90 +22,90 @@ Rozšíření prohlížeče přidávají do prohlížeče další funkce. Než v
### O prohlížeči
V této sérii lekcí se naučíte, jak vytvořit rozšíření prohlížeče, které bude fungovat v prohlížečích Chrome, Firefox a Edge. V této části zjistíte, jak prohlížeče fungují, a vytvoříte základní prvky rozšíření prohlížeče.
V této sérii lekcí se naučíte, jak vytvořit rozšíření prohlížeče, které bude fungovat v prohlížečích Chrome, Firefox a Edge. V této části zjistíte, jak prohlížeče fungují, a vytvoříte základní strukturu rozšíření prohlížeče.
Co je vlastně prohlížeč? Je to softwarová aplikace, která umožňuje koncovému uživateli přistupovat k obsahu ze serveru a zobrazovat jej na webových stránkách.
Co je to vlastně prohlížeč? Je to softwarová aplikace, která umožňuje koncovému uživateli přistupovat k obsahu ze serveru a zobrazovat jej na webových stránkách.
✅ Trocha historie: první prohlížeč se jmenoval 'WorldWideWeb' a byl vytvořen Sirem Timothym Berners-Leem v roce 1990.
> Některé rané prohlížeče, via [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
Když se uživatel připojí k internetu pomocí adresy URL (Uniform Resource Locator), obvykle prostřednictvím protokolu Hypertext Transfer Protocol přes adresu`http` nebo `https`, prohlížeč komunikuje s webovým serverem a načte webovou stránku.
Když se uživatel připojí k internetu pomocí adresy URL (Uniform Resource Locator), obvykle prostřednictvím Hypertext Transfer Protocol pomocí adresy`http` nebo `https`, prohlížeč komunikuje s webovým serverem a načte webovou stránku.
V tomto okamžiku zobrazovací engine prohlížeče zobrazí stránku na zařízení uživatele, což může být mobilní telefon, stolní počítač nebo notebook.
V tomto okamžiku zobrazovací modul prohlížeče stránku vykreslí na zařízení uživatele, což může být mobilní telefon, stolní počítač nebo notebook.
Prohlížeče také dokážou ukládat obsah do mezipaměti, aby jej nemusely pokaždé načítat ze serveru. Mohou zaznamenávat historii prohlížení uživatele, ukládat 'cookies', což jsou malé datové soubory obsahující informace o aktivitě uživatele, a mnoho dalšího.
Prohlížeče také dokážou ukládat obsah do mezipaměti, takže jej není nutné pokaždé načítat ze serveru. Mohou zaznamenávat historii prohlížení uživatele, ukládat 'cookies', což jsou malé datové soubory obsahující informace o aktivitě uživatele, a mnoho dalšího.
Je velmi důležité si uvědomit, že prohlížeče nejsou všechny stejné! Každý prohlížeč má své silné a slabé stránky, a profesionální webový vývojář musí rozumět tomu, jak zajistit, aby webové stránky fungovaly dobře napříč různými prohlížeči. To zahrnuje přizpůsobení malým obrazovkám, jako je mobilní telefon, stejně jako uživatelům, kteří jsou offline.
Je velmi důležité si uvědomit, že prohlížeče nejsou všechny stejné! Každý prohlížeč má své silné a slabé stránky a profesionální webový vývojář musí rozumět tomu, jak zajistit, aby webové stránky fungovaly dobře napříč různými prohlížeči. To zahrnuje přizpůsobení malým obrazovkám, jako jsou mobilní telefony, i uživatelům, kteří jsou offline.
Velmi užitečná webová stránka, kterou byste si měli uložit do záložek v preferovaném prohlížeči, je [caniuse.com](https://www.caniuse.com). Při vytváření webových stránek je velmi užitečné používat seznamy podporovaných technologií na caniuse, abyste mohli co nejlépe podpořit své uživatele.
Velmi užitečná webová stránka, kterou byste si měli uložit do záložek v jakémkoli prohlížeči, který preferujete, je [caniuse.com](https://www.caniuse.com). Při vytváření webových stránek je velmi užitečné používat seznamy podporovaných technologií na caniuse, abyste mohli co nejlépe podpořit své uživatele.
✅ Jak zjistíte, které prohlížeče jsou nejpopulárnější mezi uživateli vašeho webu? Zkontrolujte své analytické nástroje - můžete nainstalovat různé balíčky analytiky jako součást procesu vývoje webu, které vám řeknou, jaké prohlížeče jsou nejvíce používané.
✅ Jak zjistíte, které prohlížeče jsou nejpopulárnější mezi uživateli vašeho webu? Zkontrolujte svou analytiku – můžete nainstalovat různé analytické nástroje jako součást svého vývojového procesu a ty vám ukážou, které prohlížeče jsou nejvíce používány.
## Rozšíření prohlížeče
Proč byste chtěli vytvořit rozšíření prohlížeče? Je to praktický nástroj, který se připojí k vašemu prohlížeči, když potřebujete rychlý přístup k úkolům, které často opakujete. Například pokud často kontrolujete barvy na různých webových stránkách, můžete si nainstalovat rozšíření prohlížeče s výběrem barev. Pokud máte potíže s pamatováním hesel, můžete použít rozšíření pro správu hesel.
Proč byste chtěli vytvořit rozšíření prohlížeče? Je to užitečný nástroj, který si můžete připojit k prohlížeči, když potřebujete rychlý přístup k úkolům, které často opakujete. Například pokud často potřebujete kontrolovat barvy na různých webových stránkách, můžete si nainstalovat rozšíření pro výběr barev. Pokud máte potíže s pamatováním hesel, můžete použít rozšíření pro správu hesel.
Vývoj rozšíření prohlížeče je také zábavný. Obvykle se zaměřují na omezený počet úkolů, které zvládají velmi dobře.
Vytváření rozšíření prohlížeče je také zábavné. Obvykle se zaměřují na omezený počet úkolů, které zvládají velmi dobře.
✅ Jaká jsou vaše oblíbená rozšíření prohlížeče? Jaké úkoly plní?
### Instalace rozšíření
Než začnete vytvářet, podívejte se na proces vytváření a nasazení rozšíření prohlížeče. I když se každý prohlížeč trochu liší v tom, jak tento úkol spravuje, proces je podobný v Chrome a Firefoxu jako v tomto příkladu na Edge:
Než začnete vytvářet, podívejte se na proces vytváření a nasazení rozšíření prohlížeče. I když se jednotlivé prohlížeče v tomto procesu mírně liší, postup je podobný v Chrome a Firefoxu jako v tomto příkladu pro Edge:
> Poznámka: Ujistěte se, že jste zapnuli režim pro vývojáře a povolili rozšíření z jiných obchodů.
> Poznámka: Ujistěte se, že jste zapnuli režim vývojáře a povolili rozšíření z jiných obchodů.
V podstatě bude proces následující:
- vytvořte své rozšíření pomocí `npm run build`
- v prohlížeči přejděte na panel rozšíření pomocí tlačítka "Nastavení a další" (ikona `...`) v pravém horním rohu
- pokud jde o novou instalaci, vyberte `load unpacked`, abyste nahráli nové rozšíření z jeho složky sestavení (v našem případě je to `/dist`)
- pokud jde o novou instalaci, zvolte `load unpacked` pro nahrání nového rozšíření z jeho složky sestavení (v našem případě je to `/dist`)
- nebo klikněte na `reload`, pokud znovu načítáte již nainstalované rozšíření
✅ Tyto pokyny se týkají rozšíření, která si sami vytvoříte; pokud chcete nainstalovat rozšíření, která byla vydána v obchodě s rozšířeními prohlížeče, měli byste přejít na tyto [obchody](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) a nainstalovat rozšíření podle svého výběru.
✅ Tyto pokyny se týkají rozšíření, která si sami vytvoříte; pro instalaci rozšíření, která byla vydána v obchodě s rozšířeními prohlížeče, byste měli přejít do těchto [obchodů](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) a nainstalovat rozšíření dle vašeho výběru.
### Začněte
Budete vytvářet rozšíření prohlížeče, které zobrazí uhlíkovou stopu vašeho regionu, včetně spotřeby energie a zdroje energie. Rozšíření bude obsahovat formulář, který shromáždí API klíč, abyste mohli přistupovat k API CO2 Signal.
Vytvoříte rozšíření prohlížeče, které zobrazí uhlíkovou stopu vašeho regionu, včetně spotřeby energie a zdroje této energie. Rozšíření bude obsahovat formulář, který shromáždí API klíč, abyste mohli přistupovat k API CO2 Signal.
**Potřebujete:**
- [API klíč](https://www.co2signal.com/); zadejte svůj e-mail do pole na této stránce a klíč vám bude zaslán
- [kód vašeho regionu](http://api.electricitymap.org/v3/zones) odpovídající [Electricity Map](https://www.electricitymap.org/map) (například v Bostonu používám 'US-NEISO').
- [výchozí kód](../../../../5-browser-extension/start). Stáhněte si složku `start`; budete doplňovat kód v této složce.
- [NPM](https://www.npmjs.com) - NPM je nástroj pro správu balíčků; nainstalujte jej lokálně a balíčky uvedené ve vašem souboru `package.json` budou připraveny k použití
- [NPM](https://www.npmjs.com) - NPM je nástroj pro správu balíčků; nainstalujte jej lokálně a balíčky uvedené ve vašem souboru `package.json` budou připraveny k použití ve vašem webovém projektu
✅ Více o správě balíčků se dozvíte v tomto [vynikajícím modulu Learn](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
Věnujte chvíli prozkoumání kódové základny:
Věnujte chvíli prozkoumání kódu:
dist
-|manifest.json (výchozí nastavení zde)
-|index.html (HTML značení front-endu zde)
-|background.js (JS na pozadí zde)
-|manifest.json (zde jsou nastaveny výchozí hodnoty)
-|index.html (zde je HTML front-endu)
-|background.js (zde je background JS)
-|main.js (sestavený JS)
src
-|index.js (váš JS kód sem)
-|index.js (zde bude váš JS kód)
✅ Jakmile budete mít svůj API klíč a kód regionu připravený, uložte je někam do poznámky pro budoucí použití.
✅ Jakmile budete mít svůj API klíč a kód regionu připravený, uložte si je někam do poznámek pro budoucí použití.
### Vytvořte HTML pro rozšíření
Toto rozšíření má dvě zobrazení. Jedno pro shromáždění API klíče a kódu regionu:
Toto rozšíření má dvě zobrazení. Jedno pro zadání API klíče a kódu regionu:

A druhé pro zobrazení uhlíkové spotřeby regionu:
A druhé pro zobrazení uhlíkové stopy regionu:


Začněme vytvořením HTML pro formulář a jeho stylováním pomocí CSS.
Ve složce `/dist` vytvořte formulář a oblast výsledků. V souboru `index.html` vyplňte vymezenou oblast formuláře:
Ve složce `/dist` vytvořte formulář a oblast pro výsledky. V souboru `index.html` vyplňte vyznačenou oblast formuláře:
```HTML
<formclass="form-data"autocomplete="on">
@ -125,7 +125,7 @@ Ve složce `/dist` vytvořte formulář a oblast výsledků. V souboru `index.ht
```
Toto je formulář, kde budou vaše uložené informace zadány a uloženy do místního úložiště.
Dále vytvořte oblast výsledků; pod poslední značku formuláře přidejte několik divů:
Dále vytvořte oblast pro výsledky; pod poslední značku formuláře přidejte několik divů:
```HTML
<divclass="result">
@ -140,17 +140,17 @@ Dále vytvořte oblast výsledků; pod poslední značku formuláře přidejte n
<buttonclass="clear-btn">Change region</button>
</div>
```
V tomto bodě můžete zkusit sestavení. Ujistěte se, že jste nainstalovali závislosti balíčků tohoto rozšíření:
V tomto okamžiku můžete zkusit sestavení. Ujistěte se, že jste nainstalovali závislosti balíčků tohoto rozšíření:
```
npm install
```
Tento příkaz použije npm, správce balíčků Node, k instalaci webpacku pro proces sestavení vašeho rozšíření. Výstup tohoto procesu můžete vidět v `/dist/main.js` - uvidíte, že kód byl zkompilován.
Tento příkaz použije npm, správce balíčků Node, k instalaci webpacku pro proces sestavení vašeho rozšíření. Výstup tohoto procesu můžete vidět v `/dist/main.js` - uvidíte, že kód byl sloučen.
Prozatím by se rozšíření mělo sestavit a pokud jej nasadíte do Edge jako rozšíření, uvidíte čistě zobrazený formulář.
Prozatím by se mělo rozšíření sestavit a pokud jej nasadíte do Edge jako rozšíření, zobrazí se vám formulář úhledně zobrazený.
Gratulujeme, udělali jste první kroky k vytvoření rozšíření prohlížeče. V následujících lekcích jej učiníte funkčnějším a užitečnějším.
Gratulujeme, udělali jste první kroky k vytvoření rozšíření prohlížeče. V dalších lekcích jej uděláte funkčnějším a užitečnějším.
---
@ -158,13 +158,13 @@ Gratulujeme, udělali jste první kroky k vytvoření rozšíření prohlížeč
Podívejte se na obchod s rozšířeními prohlížeče a nainstalujte si jedno do svého prohlížeče. Můžete zkoumat jeho soubory zajímavými způsoby. Co objevíte?
## Kvíz po přednášce
## Kvíz po lekci
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/24)
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/24)
## Přehled & Samostudium
## Přehled a samostudium
V této lekci jste se dozvěděli něco o historii webového prohlížeče; využijte této příležitosti k tomu, abyste se dozvěděli více o tom, jak si vynálezci World Wide Webu představovali jeho využití, a přečtěte si více o jeho historii. Některé užitečné stránky zahrnují:
V této lekci jste se dozvěděli něco o historii webového prohlížeče; využijte této příležitosti k tomu, abyste se dozvěděli více o tom, jak si vynálezci World Wide Webu představovali jeho využití, přečtením dalších informací o jeho historii. Některé užitečné stránky zahrnují:
@ -172,11 +172,11 @@ V této lekci jste se dozvěděli něco o historii webového prohlížeče; vyu
[Rozhovor s Timem Berners-Leem](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
## Úkol
## Zadání
[Upravte styl svého rozšíření](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
V této lekci budete volat API odesláním formuláře vašeho rozšíření prohlížeče a zobrazovat výsledky v rozšíření. Navíc se naučíte, jak ukládat data do místního úložiště prohlížeče pro budoucí použití.
V této lekci budete volat API odesláním formuláře vašeho rozšíření prohlížeče a zobrazovat výsledky v rozšíření. Kromě toho se naučíte, jak ukládat data do místního úložiště prohlížeče pro budoucí použití a odkazování.
✅ Postupujte podle očíslovaných segmentů v příslušných souborech, abyste věděli, kam umístit svůj kód.
✅ Postupujte podle očíslovaných segmentů ve vhodných souborech, abyste věděli, kam umístit svůj kód.
### Nastavení prvků pro manipulaci v rozšíření:
Do této chvíle jste vytvořili HTML pro formulář a `<div>` pro výsledky vašeho rozšíření prohlížeče. Od této chvíle budete pracovat v souboru `/src/index.js` a postupně rozšiřovat své rozšíření. Odkazujte na [předchozí lekci](../1-about-browsers/README.md) ohledně nastavení projektu a procesu sestavení.
Do této chvíle jste vytvořili HTML pro formulář a `<div>` pro výsledky vašeho rozšíření prohlížeče. Od této chvíle budete pracovat v souboru `/src/index.js` a postupně budovat své rozšíření. Odkazujte na [předchozí lekci](../1-about-browsers/README.md) pro nastavení projektu a proces sestavení.
Pracujte ve svém souboru `index.js` a začněte vytvořením několika `const` proměnných, které budou držet hodnoty spojené s různými poli:
Pracujte ve svém souboru `index.js` a začněte vytvořením několika `const` proměnných, které budou uchovávat hodnoty spojené s různými poli:
```JavaScript
// form fields
@ -45,7 +45,7 @@ Všechna tato pole jsou odkazována podle jejich CSS třídy, jak jste je nastav
### Přidání posluchačů událostí
Dále přidejte posluchače událostí pro formulář a tlačítko pro vymazání, které resetuje formulář, aby se při odeslání formuláře nebo kliknutí na tlačítko reset něco stalo. Na konec souboru přidejte volání inicializace aplikace:
Dále přidejte posluchače událostí pro formulář a tlačítko pro vymazání, které resetuje formulář, aby se při odeslání formuláře nebo kliknutí na tlačítko něco stalo. Na konci souboru přidejte volání pro inicializaci aplikace:
✅ Všimněte si zkráceného zápisu pro poslouchání událostí odeslání nebo kliknutí a jak je událost předána funkcím handleSubmit nebo reset. Dokážete napsat ekvivalent tohoto zkráceného zápisu v delším formátu? Který preferujete?
✅ Všimněte si zkráceného zápisu pro poslouchání událostí odeslání nebo kliknutí a toho, jak je událost předána funkcím `handleSubmit` nebo `reset`. Dokážete napsat ekvivalent tohoto zkráceného zápisu v delším formátu? Který způsob preferujete?
### Vytvoření funkcí init() a reset():
### Vytvoření funkcí `init()` a `reset()`:
Nyní vytvoříte funkci, která inicializuje rozšíření, nazvanou init():
Nyní vytvoříte funkci, která inicializuje rozšíření, nazvanou `init()`:
```JavaScript
function init() {
@ -92,30 +92,31 @@ function reset(e) {
}
```
V této funkci je zajímavá logika. Při jejím čtení, vidíte, co se děje?
- jsou nastaveny dvě `const`, které kontrolují, zda uživatel uložil APIKey a regionální kód do místního úložiště.
- pokud je některá z těchto hodnot null, zobrazí se formulář změnou jeho stylu na 'block'.
- skryjí se výsledky, načítání a clearBtn a nastaví se jakýkoli chybový text na prázdný řetězec.
- pokud existuje klíč a region, spustí se rutina:
- volání API pro získání dat o uhlíkové spotřebě
- skrytí oblasti výsledků
- skrytí formuláře
- zobrazení tlačítka reset
V této funkci je zajímavá logika. Při jejím čtení dokážete pochopit, co se děje?
Než budete pokračovat, je užitečné se naučit o velmi důležitém konceptu dostupném v prohlížečích: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage je užitečný způsob ukládání řetězců v prohlížeči jako `key-value` pár. Tento typ webového úložiště lze manipulovat pomocí JavaScriptu pro správu dat v prohlížeči. LocalStorage nevyprší, zatímco SessionStorage, jiný typ webového úložiště, se vymaže při zavření prohlížeče. Různé typy úložišť mají své výhody a nevýhody.
- Jsou nastaveny dvě `const`, které kontrolují, zda uživatel uložil APIKey a regionální kód do místního úložiště.
- Pokud je některá z těchto hodnot `null`, zobrazí se formulář změnou jeho stylu na 'block'.
- Skryjí se výsledky, načítání a tlačítko pro vymazání a jakýkoli text chyby se nastaví na prázdný řetězec.
- Pokud existuje klíč a region, spustí se rutina:
- zavolá API pro získání dat o uhlíkové stopě,
- skryje oblast výsledků,
- skryje formulář,
- zobrazí tlačítko pro reset.
Než budete pokračovat, je užitečné se seznámit s velmi důležitým konceptem dostupným v prohlížečích: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage je užitečný způsob, jak ukládat řetězce v prohlížeči jako páry `klíč-hodnota`. Tento typ webového úložiště lze manipulovat pomocí JavaScriptu pro správu dat v prohlížeči. LocalStorage nevyprší, zatímco SessionStorage, jiný typ webového úložiště, se vymaže při zavření prohlížeče. Různé typy úložiště mají své výhody a nevýhody.
> Poznámka - vaše rozšíření prohlížeče má své vlastní místní úložiště; hlavní okno prohlížeče je jiná instance a chová se odděleně.
Nastavíte hodnotu APIKey jako řetězec, například, a můžete vidět, že je nastavena v Edge tím, že "inspektujete" webovou stránku (můžete kliknout pravým tlačítkem na prohlížeč a inspektovat) a přejdete na kartu Aplikace, kde uvidíte úložiště.
Nastavte hodnotu APIKey jako řetězec, například, a můžete vidět, že je nastavena v Edge, když "zkoumáte" webovou stránku (můžete kliknout pravým tlačítkem na prohlížeč a zvolit "zkoumat") a přejdete na kartu Aplikace, kde uvidíte úložiště.

✅ Zamyslete se nad situacemi, kdy byste NECHTĚLI ukládat některá data do LocalStorage. Obecně je umístění API klíčů do LocalStorage špatný nápad! Vidíte proč? V našem případě, protože naše aplikace je čistě pro učení a nebude nasazena do obchodu s aplikacemi, použijeme tuto metodu.
✅ Zamyslete se nad situacemi, kdy byste NECHTĚLI ukládat některá data do LocalStorage. Obecně je špatný nápad ukládat API klíče do LocalStorage! Vidíte proč? V našem případě, protože naše aplikace je čistě pro výuku a nebude nasazena do obchodu s aplikacemi, použijeme tuto metodu.
Všimněte si, že používáte Web API pro manipulaci s LocalStorage, buď pomocí `getItem()`, `setItem()`, nebo `removeItem()`. Je široce podporováno napříč prohlížeči.
Všimněte si, že používáte Web API pro manipulaci s LocalStorage, buď pomocí `getItem()`, `setItem()` nebo `removeItem()`. Je široce podporováno napříč prohlížeči.
Než vytvoříte funkci `displayCarbonUsage()`, která je volána v `init()`, vytvořte funkci pro zpracování počátečního odeslání formuláře.
Než vytvoříte funkci `displayCarbonUsage()`, která je volána v `init()`, vytvořte funkčnost pro zpracování počátečního odeslání formuláře.
### Zpracování odeslání formuláře
@ -127,11 +128,12 @@ function handleSubmit(e) {
setUpUser(apiKey.value, region.value);
}
```
✅ Osvěžte si paměť - HTML, které jste nastavili v poslední lekci, má dvě vstupní pole, jejichž `hodnoty` jsou zachyceny prostřednictvím `const`, které jste nastavili na začátku souboru, a obě jsou `povinné`, takže prohlížeč zastaví uživatele od zadání null hodnot.
✅ Osvěžte si paměť - HTML, které jste nastavili v poslední lekci, má dvě vstupní pole, jejichž `hodnoty` jsou zachyceny prostřednictvím `const`, které jste nastavili na začátku souboru, a obě jsou `povinné`, takže prohlížeč zabrání uživatelům zadat prázdné hodnoty.
### Nastavení uživatele
Pokračujeme funkcí `setUpUser`, zde nastavíte hodnoty místního úložiště pro apiKey a regionName. Přidejte novou funkci:
Pokračujte funkcí `setUpUser`, kde nastavíte hodnoty místního úložiště pro apiKey a regionName. Přidejte novou funkci:
```JavaScript
function setUpUser(apiKey, regionName) {
@ -144,17 +146,18 @@ function setUpUser(apiKey, regionName) {
displayCarbonUsage(apiKey, regionName);
}
```
Tato funkce nastaví zprávu o načítání, která se zobrazí během volání API. V tomto bodě jste dospěli k vytvoření nejdůležitější funkce tohoto rozšíření prohlížeče!
### Zobrazení uhlíkové spotřeby
Tato funkce nastaví zprávu o načítání, která se zobrazí během volání API. V tuto chvíli jste se dostali k vytvoření nejdůležitější funkce tohoto rozšíření prohlížeče!
### Zobrazení uhlíkové stopy
Konečně je čas dotázat se API!
Nakonec je čas dotázat se API!
Než budeme pokračovat, měli bychom diskutovat o API. API, nebo [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html), jsou klíčovým prvkem nástrojů webového vývojáře. Poskytují standardní způsoby, jak programy interagují a komunikují mezi sebou. Například pokud vytváříte webovou stránku, která potřebuje dotazovat databázi, někdo mohl vytvořit API, které můžete použít. Zatímco existuje mnoho typů API, jedním z nejpopulárnějších je [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
Než budeme pokračovat, měli bychom si promluvit o API. API, nebo [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html), jsou klíčovým prvkem nástrojů webového vývojáře. Poskytují standardní způsoby, jak programy interagují a komunikují mezi sebou. Například pokud vytváříte webovou stránku, která potřebuje dotazovat databázi, někdo mohl vytvořit API, které můžete použít. Zatímco existuje mnoho typů API, jedním z nejpopulárnějších je [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
✅ Termín 'REST' znamená 'Representational State Transfer' a zahrnuje použití různě konfigurovaných URL pro získání dat. Udělejte si malý průzkum o různých typech API dostupných vývojářům. Který formát vás oslovuje?
✅ Termín 'REST' znamená 'Representational State Transfer' a zahrnuje použití různě nakonfigurovaných URL pro získání dat. Proveďte malý průzkum o různých typech API dostupných vývojářům. Který formát vás oslovuje?
Existují důležité věci, které je třeba poznamenat o této funkci. Nejprve si všimněte klíčového slova [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Psát své funkce tak, aby běžely asynchronně, znamená, že čekají na dokončení akce, jako je vrácení dat, než budou pokračovat.
Existují důležité věci, na které je třeba si u této funkce dát pozor. Nejprve si všimněte klíčového slova [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Psaní funkcí tak, aby běžely asynchronně, znamená, že čekají na dokončení akce, jako je vrácení dat, než budou pokračovat.
Zde je rychlé video o `async`:
@ -162,7 +165,7 @@ Zde je rychlé video o `async`:
> 🎥 Klikněte na obrázek výše pro video o async/await.
Vytvořte novou funkci pro dotazování API C02Signal:
Vytvořte novou funkci pro dotazování na API C02Signal:
```JavaScript
import axios from '../node_modules/axios';
@ -204,12 +207,12 @@ async function displayCarbonUsage(apiKey, region) {
Toto je velká funkce. Co se zde děje?
- podle osvědčených postupů používáte klíčové slovo `async`, aby se tato funkce chovala asynchronně. Funkce obsahuje blok `try/catch`, protože vrátí slib, když API vrátí data. Protože nemáte kontrolu nad rychlostí, jakou API odpoví (může vůbec neodpovědět!), musíte tuto nejistotu řešit voláním asynchronně.
- dotazujete API co2signal, abyste získali data o vašem regionu, pomocí vašeho API klíče. K použití tohoto klíče musíte použít typ autentizace v parametrech hlavičky.
- jakmile API odpoví, přiřadíte různé prvky jeho odpovědi k částem obrazovky, které jste nastavili pro zobrazení těchto dat.
- pokud dojde k chybě nebo pokud neexistuje žádný výsledek, zobrazíte chybovou zprávu.
- Podle osvědčených postupů používáte klíčové slovo `async`, aby se tato funkce chovala asynchronně. Funkce obsahuje blok `try/catch`, protože vrátí slib, když API vrátí data. Protože nemáte kontrolu nad rychlostí, jakou API odpoví (může vůbec neodpovědět!), musíte tuto nejistotu zvládnout voláním asynchronně.
- Dotazujete se na API co2signal, abyste získali data o vašem regionu, pomocí vašeho API klíče. Pro použití tohoto klíče musíte použít typ autentizace v parametrech hlavičky.
- Jakmile API odpoví, přiřadíte různé prvky jeho odpovědi k částem obrazovky, které jste nastavili pro zobrazení těchto dat.
- Pokud dojde k chybě nebo pokud neexistuje žádný výsledek, zobrazíte chybovou zprávu.
✅ Použití asynchronních programovacích vzorů je další velmi užitečný nástroj ve vašem arzenálu. Přečtěte si [o různých způsobech](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function), jak můžete tento typ kódu konfigurovat.
✅ Používání asynchronních programovacích vzorů je další velmi užitečný nástroj ve vaší sadě nástrojů. Přečtěte si [o různých způsobech](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function), jak můžete tento typ kódu nakonfigurovat.
Gratulujeme! Pokud sestavíte své rozšíření (`npm run build`) a obnovíte jej v panelu rozšíření, máte funkční rozšíření! Jediná věc, která nefunguje, je ikona, a to opravíte v další lekci.
@ -217,7 +220,7 @@ Gratulujeme! Pokud sestavíte své rozšíření (`npm run build`) a obnovíte j
## 🚀 Výzva
Diskutovali jsme o několika typech API v těchto lekcích. Vyberte webové API a podrobně prozkoumejte, co nabízí. Například se podívejte na API dostupná v prohlížečích, jako je [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Co podle vás dělá skvělé API?
V těchto lekcích jsme diskutovali o několika typech API. Vyberte si webové API a podrobně prozkoumejte, co nabízí. Například se podívejte na API dostupná v prohlížečích, jako je [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Co podle vás dělá API skvělým?
## Kvíz po lekci
@ -227,11 +230,11 @@ Diskutovali jsme o několika typech API v těchto lekcích. Vyberte webové API
V této lekci jste se naučili o LocalStorage a API, obojí velmi užitečné pro profesionálního webového vývojáře. Dokážete si představit, jak tyto dvě věci spolupracují? Přemýšlejte o tom, jak byste navrhli webovou stránku, která by ukládala položky pro použití API.
## Úkol
## Zadání
[Adoptujte API](assignment.md)
---
**Prohlášení**:
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
V posledních dvou lekcích tohoto modulu jste se naučili, jak vytvořit formulář a zobrazovací oblast pro data získaná z API. To je velmi standardní způsob, jak vytvořit webovou prezentaci. Dokonce jste se naučili, jak asynchronně získávat data. Vaše rozšíření prohlížeče je téměř hotové.
Zbývá spravovat některé úlohy na pozadí, včetně aktualizace barvy ikony rozšíření, takže je to skvělý čas probrat, jak prohlížeč tyto úlohy spravuje. Pojďme se na tyto úlohy podívat v kontextu výkonu vašich webových prostředků při jejich vytváření.
Zbývá spravovat některé úlohy na pozadí, včetně aktualizace barvy ikony rozšíření, takže je to skvělý čas probrat, jak prohlížeč tyto úlohy spravuje. Pojďme se na tyto úlohy podívat v kontextu výkonu vašich webových prostředků během jejich vývoje.
## Základy webového výkonu
@ -25,45 +25,45 @@ Zbývá spravovat některé úlohy na pozadí, včetně aktualizace barvy ikony
Téma, jak udělat vaše webové stránky extrémně rychlé na všech typech zařízení, pro všechny typy uživatelů a ve všech situacích, je pochopitelně rozsáhlé. Zde je několik bodů, které je třeba mít na paměti při vytváření standardního webového projektu nebo rozšíření prohlížeče.
První věc, kterou musíte udělat, abyste zajistili efektivní běh vašeho webu, je shromáždit data o jeho výkonu. Prvním místem, kde to můžete udělat, jsou vývojářské nástroje vašeho webového prohlížeče. V Edge můžete vybrat tlačítko „Nastavení a další“ (ikona tří teček v pravém horním rohu prohlížeče), poté přejít na Další nástroje > Nástroje pro vývojáře a otevřít kartu Výkon. Klávesové zkratky `Ctrl` + `Shift` + `I` na Windows nebo `Option` + `Command` + `I` na Macu také otevřou vývojářské nástroje.
První věc, kterou musíte udělat, abyste zajistili efektivní běh vašeho webu, je shromáždit data o jeho výkonu. Prvním místem, kde to můžete udělat, jsou vývojářské nástroje vašeho webového prohlížeče. V Edge můžete vybrat tlačítko "Nastavení a další" (ikona tří teček v pravém horním rohu prohlížeče), poté přejít na Další nástroje > Vývojářské nástroje a otevřít kartu Výkon. Klávesové zkratky `Ctrl` + `Shift` + `I` na Windows nebo `Option` + `Command` + `I` na Macu také otevřou vývojářské nástroje.
Karta Výkon obsahuje nástroj Profilování. Otevřete webovou stránku (zkuste například [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) a klikněte na tlačítko „Záznam“, poté stránku obnovte. Záznam můžete kdykoli zastavit a uvidíte rutiny, které byly vytvořeny pro „skriptování“, „vykreslování“ a „malování“ stránky:
Karta Výkon obsahuje nástroj pro profilování. Otevřete webovou stránku (zkuste například [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) a klikněte na tlačítko 'Záznam', poté stránku obnovte. Záznam můžete kdykoli zastavit a zobrazí se vám rutiny generované pro 'skriptování', 'vykreslování' a 'malování' stránky:
✅ Navštivte [dokumentaci Microsoftu](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) o panelu Výkon v Edge.
> Tip: Chcete-li získat přesné údaje o době spuštění vašeho webu, vymažte mezipaměť prohlížeče.
> Tip: Abyste získali přesné údaje o době spuštění vašeho webu, vymažte mezipaměť prohlížeče.
Vyberte prvky časové osy profilu, abyste přiblížili události, které se odehrávají během načítání stránky.
Získejte snímek výkonu vaší stránky výběrem části časové osy profilu a pohledem na panel souhrnu:
Získejte snímek výkonu vaší stránky výběrem části časové osy profilu a pohledem na souhrnný panel:
✅ Seznamte se s vaším profilerem! Otevřete vývojářské nástroje na této stránce a zjistěte, zda existují nějaká úzká místa. Který prostředek se načítá nejpomaleji? Nejrychleji?
✅ Seznamte se s vaším profilerem! Otevřete vývojářské nástroje na této stránce a zjistěte, zda existují nějaká úzká místa. Který prostředek se načítá nejpomaleji? Který nejrychleji?
## Kontroly profilování
Obecně existují některé „problémové oblasti“, na které by si měl každý webový vývojář dávat pozor při vytváření webu, aby se vyhnul nepříjemným překvapením při nasazení do produkce.
Obecně existují některé "problémové oblasti", na které by si měl každý webový vývojář dávat pozor při vytváření webu, aby se vyhnul nepříjemným překvapením při nasazení do produkce.
**Velikosti prostředků**: Web se v posledních letech stal „těžším“ a tím pádem pomalejším. Část této zátěže souvisí s používáním obrázků.
**Velikosti prostředků**: Web se v posledních letech stal "těžším" a tím pádem pomalejším. Část této zátěže souvisí s používáním obrázků.
✅ Prohlédněte si [Internetový archiv](https://httparchive.org/reports/page-weight) pro historický pohled na váhu stránek a další informace.
Dobrou praxí je zajistit, aby vaše obrázky byly optimalizované a dodávané ve správné velikosti a rozlišení pro vaše uživatele.
**Procházení DOM**: Prohlížeč musí vytvořit svůj model objektů dokumentu (DOM) na základě kódu, který napíšete, takže je v zájmu dobrého výkonu stránky udržovat značky minimální a používat a stylovat pouze to, co stránka potřebuje. V tomto ohledu by bylo možné optimalizovat přebytečné CSS spojené se stránkou; styly, které je třeba použít pouze na jedné stránce, nemusí být zahrnuty v hlavním stylovém souboru.
**Procházení DOM**: Prohlížeč musí vytvořit svůj model objektů dokumentu (DOM) na základě kódu, který napíšete, takže je v zájmu dobrého výkonu stránky udržovat značky minimální a používat a stylovat pouze to, co stránka potřebuje. Například přebytečné CSS spojené se stránkou by mohlo být optimalizováno; styly, které je třeba použít pouze na jedné stránce, nemusí být zahrnuty v hlavním stylovém souboru.
**JavaScript**: Každý vývojář JavaScriptu by měl dávat pozor na „skripty blokující vykreslování“, které musí být načteny před tím, než může být zbytek DOM procházen a vykreslen do prohlížeče. Zvažte použití `defer` u vašich inline skriptů (jak je to provedeno v modulu Terrarium).
**JavaScript**: Každý vývojář JavaScriptu by měl dávat pozor na skripty blokující vykreslování, které musí být načteny před tím, než může být zbytek DOM procházen a vykreslen do prohlížeče. Zvažte použití `defer` u vašich inline skriptů (jak je to provedeno v modulu Terrarium).
✅ Vyzkoušejte některé stránky na [webu pro testování rychlosti stránek](https://www.webpagetest.org/), abyste se dozvěděli více o běžných kontrolách, které se provádějí pro určení výkonu stránek.
Nyní, když máte představu o tom, jak prohlížeč vykresluje prostředky, které mu posíláte, podívejme se na posledních pár věcí, které musíte udělat, abyste dokončili své rozšíření:
Nyní, když máte představu o tom, jak prohlížeč vykresluje prostředky, které mu posíláte, podívejme se na poslední věci, které musíte udělat, abyste dokončili své rozšíření:
### Vytvořte funkci pro výpočet barvy
@ -88,19 +88,19 @@ function calculateColor(value) {
}
```
Co se zde děje? Předáte hodnotu (intenzitu uhlíku) z volání API, které jste dokončili v předchozí lekci, a poté vypočítáte, jak blízko je její hodnota indexu uvedenému v poli barev. Poté tuto nejbližší hodnotu barvy odešlete do runtime prostředí Chrome.
Co se zde děje? Předáte hodnotu (intenzitu uhlíku) z API volání, které jste dokončili v poslední lekci, a poté vypočítáte, jak blízko je její hodnota indexu uvedenému v poli barev. Poté pošlete tuto nejbližší hodnotu barvy do runtime prostředí Chrome.
Runtime prostředí Chrome má [API](https://developer.chrome.com/extensions/runtime), které zpracovává všechny druhy úloh na pozadí, a vaše rozšíření toho využívá:
Chrome.runtime má [API](https://developer.chrome.com/extensions/runtime), které zpracovává všechny druhy úloh na pozadí, a vaše rozšíření toho využívá:
> „Použijte API chrome.runtime pro získání stránky na pozadí, vrácení podrobností o manifestu a naslouchání a reagování na události v životním cyklu aplikace nebo rozšíření. Toto API můžete také použít k převodu relativní cesty URL na plně kvalifikované URL.“
> "Použijte chrome.runtime API pro získání stránky na pozadí, vrácení podrobností o manifestu a naslouchání a reagování na události v životním cyklu aplikace nebo rozšíření. Toto API můžete také použít pro převod relativní cesty URL na plně kvalifikované URL."
✅ Pokud toto rozšíření prohlížeče vyvíjíte pro Edge, může vás překvapit, že používáte API Chrome. Novější verze prohlížeče Edge běží na jádře prohlížeče Chromium, takže můžete využívat tyto nástroje.
✅ Pokud vyvíjíte toto rozšíření pro Edge, může vás překvapit, že používáte API Chrome. Novější verze prohlížeče Edge běží na jádře prohlížeče Chromium, takže můžete tyto nástroje využít.
> Poznámka: Pokud chcete profilovat rozšíření prohlížeče, spusťte vývojářské nástroje přímo v rámci rozšíření, protože se jedná o samostatnou instanci prohlížeče.
> Poznámka: Pokud chcete profilovat rozšíření prohlížeče, spusťte vývojářské nástroje přímo v rámci rozšíření, protože je to samostatná instance prohlížeče.
### Nastavte výchozí barvu ikony
Nyní v rámci funkce `init()` nastavte ikonu na obecnou zelenou barvu tím, že znovu zavoláte akci `updateIcon`prostředí Chrome:
Nyní v rámci funkce `init()` nastavte ikonu na obecnou zelenou barvu tím, že znovu zavoláte akci `updateIcon`v Chrome:
```JavaScript
chrome.runtime.sendMessage({
@ -113,7 +113,7 @@ chrome.runtime.sendMessage({
### Zavolejte funkci, proveďte volání
Dále zavolejte funkci, kterou jste právě vytvořili, přidáním do promise vráceného API C02Signal:
Dále zavolejte funkci, kterou jste právě vytvořili, přidáním do slibu vráceného API C02Signal:
```JavaScript
//let CO2...
@ -173,4 +173,4 @@ Prozkoumejte některé způsoby, jak prohlížeče měří výkon webu, prohléd
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/29)
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/29)
### Dědičnost a kompozice ve vývoji her
V předchozích lekcích nebylo třeba příliš řešit návrhovou architekturu aplikací, které jste vytvářeli, protože projekty byly velmi malé. Jakmile však vaše aplikace rostou co do velikosti a rozsahu, stávají se architektonická rozhodnutí důležitějšími. Existují dva hlavní přístupy k vytváření větších aplikací v JavaScriptu: *kompozice* nebo *dědičnost*. Oba přístupy mají své výhody a nevýhody, ale pojďme si je vysvětlit v kontextu hry.
V předchozích lekcích nebylo potřeba příliš řešit architekturu aplikací, které jste vytvářeli, protože projekty byly velmi malé. Jakmile však vaše aplikace rostou co do velikosti a rozsahu, stávají se architektonická rozhodnutí důležitějšími. Existují dva hlavní přístupy k vytváření větších aplikací v JavaScriptu: *kompozice* nebo *dědičnost*. Oba mají své výhody a nevýhody, ale pojďme si je vysvětlit v kontextu hry.
✅ Jedna z nejslavnějších knih o programování se zabývá [návrhovými vzory](https://en.wikipedia.org/wiki/Design_Patterns).
✅ Jedna z nejslavnějších knih o programování se zabývá [designovými vzory](https://en.wikipedia.org/wiki/Design_Patterns).
Ve hře máte `herní objekty`, což jsou objekty, které existují na obrazovce. To znamená, že mají umístění v kartézském souřadnicovém systému, charakterizované souřadnicemi `x` a `y`. Při vývoji hry si všimnete, že všechny vaše herní objekty mají standardní vlastnosti, které jsou společné pro každou hru, kterou vytvoříte, konkrétně prvky, které jsou:
Ve hře máte `herní objekty`, což jsou objekty, které existují na obrazovce. To znamená, že mají umístění v kartézském souřadnicovém systému, charakterizované souřadnicemi `x` a `y`. Jakmile začnete vyvíjet hru, všimnete si, že všechny vaše herní objekty mají standardní vlastnosti, které jsou společné pro každou hru, kterou vytvoříte. Tyto prvky jsou:
- **založené na umístění** Většina, ne-li všechny herní prvky, jsou založené na umístění. To znamená, že mají souřadnice`x` a `y`.
- **pohyblivé** Jedná se o objekty, které se mohou přesunout na nové místo. Typicky jde o hrdinu, monstrum nebo NPC (nehratelnou postavu), ale například ne o statický objekt, jako je strom.
- **sebedestruktivní** Tyto objekty existují pouze po určitou dobu, než se nastaví k odstranění. Obvykle je to reprezentováno booleanem `dead` nebo `destroyed`, který signalizuje hernímu enginu, že tento objekt by již neměl být vykreslován.
- **s časovým omezením** 'Časové omezení' je typická vlastnost krátkodobých objektů. Typickým příkladem je text nebo grafický efekt, jako je exploze, který by měl být viditelný jen několik milisekund.
- **založené na umístění** Většina, ne-li všechny herní prvky, jsou založené na umístění. To znamená, že mají umístění,`x` a `y`.
- **pohyblivé** Jsou to objekty, které se mohou přesunout na nové místo. Typicky jde o hrdinu, monstrum nebo NPC (nehráčskou postavu), ale ne například o statický objekt, jako je strom.
- **samodestrukční** Tyto objekty existují pouze po určitou dobu, než se připraví na odstranění. Obvykle je to reprezentováno booleanem `dead` nebo `destroyed`, který signalizuje hernímu enginu, že tento objekt by již neměl být vykreslován.
- **cool-down** 'Cool-down' je typická vlastnost krátkodobých objektů. Typickým příkladem je kus textu nebo grafický efekt, jako je exploze, který by měl být viditelný jen několik milisekund.
✅ Přemýšlejte o hře jako Pac-Man. Dokážete v této hře identifikovat čtyři výše uvedené typy objektů?
✅ Zamyslete se nad hrou jako Pac-Man. Dokážete identifikovat čtyři typy objektů uvedené výše v této hře?
### Vyjádření chování
Vše, co jsme popsali výše, jsou chování, která mohou herní objekty mít. Jak je tedy zakódujeme? Toto chování můžeme vyjádřit jako metody spojené buď s třídami, nebo objekty.
Vše, co jsme popsali výše, jsou chování, která mohou mít herní objekty. Jak je tedy zakódujeme? Toto chování můžeme vyjádřit jako metody spojené buď s třídami, nebo objekty.
**Třídy**
Myšlenkou je použít `třídy` ve spojení s `dědičností`, abychom přidali určité chování třídě.
Myšlenka je použít `třídy` ve spojení s `dědičností`, abychom přidali určité chování do třídy.
✅ Dědičnost je důležitý koncept k pochopení. Přečtěte si více v [článku MDN o dědičnosti](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
✅ Dědičnost je důležitý koncept, který je třeba pochopit. Více se dozvíte v [článku MDN o dědičnosti](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
Vyjádřeno pomocí kódu, herní objekt může typicky vypadat takto:
@ -139,7 +139,7 @@ const tree = createStatic(0,0, 'Tree');
**Který vzor bych měl použít?**
Je na vás, který vzor si vyberete. JavaScript podporuje oba tyto přístupy.
Je na vás, který vzor si vyberete. JavaScript podporuje oba tyto paradigmy.
--
@ -149,13 +149,13 @@ Další vzor běžný ve vývoji her řeší problém správy uživatelského z
✅ Pub/Sub znamená 'publish-subscribe' (publikovat-odebírat)
Tento vzor se zabývá myšlenkou, že různé části vaší aplikace by o sobě neměly vědět. Proč? Protože je mnohem snazší pochopit, co se obecně děje, pokud jsou jednotlivé části oddělené. Také je snazší náhle změnit chování, pokud je to potřeba. Jak toho dosáhneme? Zavedením několika konceptů:
Tento vzor se zabývá myšlenkou, že různé části vaší aplikace by o sobě neměly vědět. Proč? Usnadňuje to obecný přehled o tom, co se děje, pokud jsou různé části oddělené. Také to usnadňuje náhlou změnu chování, pokud je to potřeba. Jak toho dosáhneme? Zavedením několika konceptů:
- **zpráva**: Zpráva je obvykle textový řetězec doplněný volitelným obsahem (daty, která upřesňují, o čem zpráva je). Typická zpráva ve hře může být `KEY_PRESSED_ENTER`.
- **vydavatel**: Tento prvek *publikuje* zprávu a odesílá ji všem odběratelům.
- **odběratel**: Tento prvek *naslouchá* konkrétním zprávám a provádí určitou akci v důsledku přijetí této zprávy, například vystřelení laseru.
- **zpráva**: Zpráva je obvykle textový řetězec doplněný volitelným obsahem (daty, která objasňují, o čem zpráva je). Typická zpráva ve hře může být `KEY_PRESSED_ENTER`.
- **vydavatel**: Tento prvek *publikuje* zprávu a posílá ji všem odběratelům.
- **odběratel**: Tento prvek *poslouchá* konkrétní zprávy a provádí nějaký úkol jako výsledek přijetí této zprávy, například vystřelení laseru.
Implementace je poměrně malá, ale jde o velmi silný vzor. Zde je ukázka, jak může být implementován:
Implementace je poměrně malá, ale je to velmi silný vzor. Zde je, jak může být implementován:
```javascript
//set up an EventEmitter class that contains listeners
Výše propojujeme událost klávesnice, `ArrowLeft`, a odesíláme zprávu `HERO_MOVE_LEFT`. Nasloucháme této zprávě a v důsledku toho pohybujeme `hrdinou`. Síla tohoto vzoru spočívá v tom, že posluchač událostí a hrdina o sobě navzájem nevědí. Můžete přemapovat `ArrowLeft` na klávesu `A`. Navíc by bylo možné udělat něco úplně jiného na `ArrowLeft` provedením několika úprav funkce `on` v eventEmitteru:
Výše propojujeme událost klávesnice, `ArrowLeft`, a posíláme zprávu `HERO_MOVE_LEFT`. Posloucháme tuto zprávu a jako výsledek pohybujeme `hrdinou`. Síla tohoto vzoru spočívá v tom, že posluchač událostí a hrdina o sobě navzájem nevědí. Můžete přemapovat `ArrowLeft` na klávesu `A`. Navíc by bylo možné udělat něco úplně jiného na `ArrowLeft` provedením několika úprav funkce `on` v eventEmitteru:
Jakmile se vaše hra stane složitější, tento vzor zůstává stejně jednoduchý a váš kód zůstává čistý. Je opravdu doporučeno tento vzor přijmout.
Jakmile se věci stanou složitějšími, když vaše hra roste, tento vzor zůstává stejně složitý a váš kód zůstává čistý. Je opravdu doporučeno tento vzor přijmout.
---
## 🚀 Výzva
Přemýšlejte o tom, jak může vzor pub-sub vylepšit hru. Které části by měly emitovat události a jak by na ně měla hra reagovat? Teď máte šanci být kreativní a přemýšlet o nové hře a o tom, jak by se její části mohly chovat.
Zamyslete se nad tím, jak může vzor pub-sub vylepšit hru. Které části by měly emitovat události a jak by na ně měla hra reagovat? Teď máte šanci být kreativní, přemýšlet o nové hře a o tom, jak by se její části mohly chovat.
## Kvíz po lekci
## Kvíz po přednášce
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/30)
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/30)
## Recenze a samostudium
## Přehled a samostudium
Zjistěte více o Pub/Sub [přečtením tohoto článku](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon).
Zjistěte více o Pub/Sub [čtením o něm](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon).
## Zadání
## Úkol
[Navrhněte koncept hry](assignment.md)
[Navrhněte hru](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Plátno je HTML prvek, který nemá ve výchozím nastavení žádný obsah; je to prázdná plocha. Musíte na něj kreslit, abyste něco přidali.
Plátno je HTML prvek, který nemá ve výchozím nastavení žádný obsah; je to prázdná plocha. Musíte na něj něco nakreslit.
✅ Přečtěte si [více o Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) na MDN.
@ -27,13 +27,13 @@ Takto se obvykle deklaruje jako součást těla stránky:
Výše nastavujeme `id`, `width` a `height`.
- `id`: nastavte toto, abyste mohli získat referenci, když s tím budete potřebovat pracovat.
- `id`: nastavte, abyste mohli získat referenci, když s ním budete chtít pracovat.
- `width`: šířka prvku.
- `height`: výška prvku.
## Kreslení jednoduché geometrie
Plátno používá kartézský souřadnicový systém pro kreslení objektů. Používá tedy osu x a osu y k vyjádření, kde se něco nachází. Poloha `0,0` je v levém horním rohu a pravý dolní roh odpovídá šířce a výšce plátna, které jste nastavili.
Plátno používá kartézský souřadnicový systém pro kreslení objektů. Používá tedy osu x a osu y k určení, kde se něco nachází. Pozice `0,0` je v levém horním rohu a pravý dolní roh odpovídá hodnotám WIDTH a HEIGHT plátna.
> Obrázek z [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
@ -41,8 +41,8 @@ Plátno používá kartézský souřadnicový systém pro kreslení objektů. Po
Pro kreslení na prvek plátna musíte projít následujícími kroky:
1. **Získat referenci** na prvek plátna.
1. **Získat referenci** na prvek kontextu, který se nachází na plátně.
1. **Provést kreslící operaci** pomocí prvku kontextu.
2. **Získat referenci** na kontextový prvek, který je na plátně.
3. **Proveďte kreslící operaci** pomocí kontextového prvku.
Kód pro výše uvedené kroky obvykle vypadá takto:
@ -61,17 +61,17 @@ ctx.fillStyle = 'red';
ctx.fillRect(0,0, 200, 200) // x,y,width, height
```
✅ Canvas API se většinou zaměřuje na 2D tvary, ale můžete také kreslit 3D objekty na webovou stránku; k tomu můžete použít [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
✅ Canvas API se většinou zaměřuje na 2D tvary, ale můžete také kreslit 3D prvky na webovou stránku; k tomu můžete použít [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
S Canvas API můžete kreslit různé věci, například:
- **Geometrické tvary**, už jsme ukázali, jak nakreslit obdélník, ale je toho mnohem více, co můžete nakreslit.
- **Text**, můžete kreslit text s libovolným fontem a barvou.
- **Obrázky**, můžete kreslit obrázky na základě obrazových souborů, jako je .jpg nebo .png.
- **Geometrické tvary**, už jsme ukázali, jak nakreslit obdélník, ale můžete kreslit mnohem více.
- **Text**, můžete kreslit text s libovolným písmem a barvou.
- **Obrázky**, můžete kreslit obrázky na základě obrazových souborů, jako jsou .jpg nebo .png.
✅ Vyzkoušejte to! Už víte, jak nakreslit obdélník, dokážete nakreslit kruh na stránku? Podívejte se na některé zajímavé kresby na plátně na CodePen. Tady je [zvláště působivý příklad](https://codepen.io/dissimulate/pen/KrAwx).
✅ Vyzkoušejte to! Už víte, jak nakreslit obdélník, dokážete nakreslit kruh na stránku? Podívejte se na některé zajímavé kresby na plátně na CodePen. Zde je [zvláště působivý příklad](https://codepen.io/dissimulate/pen/KrAwx).
## Načtení a kreslení obrazového souboru
## Načtení a vykreslení obrazového souboru
Obrazový soubor načtete vytvořením objektu `Image` a nastavením jeho vlastnosti `src`. Poté posloucháte událost `load`, abyste věděli, kdy je připraven k použití. Kód vypadá takto:
@ -85,9 +85,9 @@ img.onload = () => {
}
```
### Vzor pro načtení souboru
### Vzor načítání souboru
Doporučuje se zabalit výše uvedené do konstrukce, jako je tato, aby bylo snazší jej použít a manipulovat s ním pouze tehdy, když je plně načten:
Doporučuje se zabalit výše uvedené do konstruktu, jako je tento, aby bylo snazší jej používat a abyste se pokusili s ním manipulovat pouze tehdy, když je plně načten:
```javascript
function loadAsset(path) {
@ -110,7 +110,7 @@ async function run() {
```
Pro vykreslení herních souborů na obrazovku by váš kód vypadal takto:
Pro vykreslení herních prvků na obrazovku by váš kód vypadal takto:
```javascript
async function run() {
@ -124,17 +124,17 @@ async function run() {
}
```
## Nyní je čas začít vytvářet vaši hru
## Teď je čas začít stavět vaši hru
### Co vytvořit
Vytvoříte webovou stránku s prvkem plátna. Měla by zobrazovat černou obrazovku `1024*768`. Poskytli jsme vám dva obrázky:
Vytvoříte webovou stránku s prvkem plátna. Měla by vykreslit černou obrazovku `1024*768`. Poskytli jsme vám dva obrázky:
@ -151,9 +151,9 @@ Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měla
-| package.json
```
Otevřete kopii této složky ve Visual Studio Code. Měli byste mít nastavené lokální vývojové prostředí, nejlépe s Visual Studio Code, NPM a Node. Pokud nemáte na svém počítači nastavený `npm`, [zde je návod, jak to udělat](https://www.npmjs.com/get-npm).
Otevřete kopii této složky ve Visual Studio Code. Měli byste mít nastavené lokální vývojové prostředí, nejlépe s Visual Studio Code s NPM a Node nainstalovanými. Pokud nemáte `npm` nastavený na svém počítači, [zde je návod, jak to udělat](https://www.npmjs.com/get-npm).
Začněte svůj projekt navigací do složky `your_work`:
Spusťte svůj projekt navigací do složky `your_work`:
```bash
cd your-work
@ -162,22 +162,22 @@ npm start
Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu. Zatím je to prázdná stránka, ale to se změní.
> Poznámka: abyste viděli změny na obrazovce, obnovte prohlížeč.
> Poznámka: pro zobrazení změn na obrazovce obnovte prohlížeč.
### Přidání kódu
Přidejte potřebný kód do `your-work/app.js`, abyste vyřešili následující:
1. **Nakreslete** plátno s černým pozadím
> tip: přidejte dva řádky pod příslušné TODO v `/app.js`, nastavte prvek `ctx` na černou barvu a souřadnice nahoře/vlevo na 0,0 a výšku a šířku na hodnoty plátna.
> tip: přidejte dva řádky pod příslušný TODO v `/app.js`, nastavte prvek `ctx` na černou barvu a souřadnice nahoře/vlevo na 0,0 a výšku a šířku na hodnoty plátna.
2. **Načtěte** textury
> tip: přidejte obrázky hráče a nepřítele pomocí `await loadTexture` a předáním cesty k obrázku. Zatím je na obrazovce neuvidíte!
3. **Nakreslete** hrdinu do středu obrazovky ve spodní polovině
> tip: použijte API `drawImage` k nakreslení heroImg na obrazovku, nastavte `canvas.width / 2 - 45` a `canvas.height - canvas.height / 4)`;
> tip: použijte API `drawImage` k vykreslení heroImg na obrazovku, nastavte `canvas.width / 2 - 45` a `canvas.height - canvas.height / 4)`;
4. **Nakreslete** 5*5 monster
> tip: Nyní můžete odkomentovat kód pro vykreslení nepřátel na obrazovku. Poté přejděte do funkce `createEnemies` a vytvořte ji.
> tip: Nyní můžete odkomentovat kód pro vykreslení nepřátel na obrazovku. Dále přejděte do funkce `createEnemies` a doplňte ji.
Nejprve nastavte některé konstanty:
Nejprve nastavte několik konstant:
```javascript
const MONSTER_TOTAL = 5;
@ -186,7 +186,7 @@ Přidejte potřebný kód do `your-work/app.js`, abyste vyřešili následujíc
const STOP_X = START_X + MONSTER_WIDTH;
```
poté vytvořte smyčku pro vykreslení pole monster na obrazovku:
poté vytvořte smyčku pro vykreslení pole monster na obrazovku:
```javascript
for (let x = START_X; x <STOP_X;x+=98){
@ -216,15 +216,15 @@ Naučili jste se kreslit pomocí Canvas API zaměřeného na 2D; podívejte se n
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/32)
## Přehled a samostudium
## Recenze a samostudium
Zjistěte více o Canvas API [čtením o něm](https://developer.mozilla.org/docs/Web/API/Canvas_API).
## Úkol
## Zadání
[Vyzkoušejte si práci s Canvas API](assignment.md)
[Hrajte si s Canvas API](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/33)
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/33)
Hry nejsou moc zábavné, dokud se na obrazovce nezačnou pohybovat mimozemšťané! V této hře využijeme dva typy pohybu:
- **Pohyb pomocí klávesnice/myši**: když uživatel interaguje s klávesnicí nebo myší, aby přesunul objekt na obrazovce.
- **Pohyb vyvolaný hrou**: když hra pohybuje objektem v určitém časovém intervalu.
- **Pohyb pomocí klávesnice/myši**: když uživatel interaguje s klávesnicí nebo myší, aby pohyboval objektem na obrazovce.
- **Pohyb řízený hrou**: když hra pohybuje objektem v určitých časových intervalech.
Jak tedy pohybujeme objekty na obrazovce? Vše je o kartézských souřadnicích: změníme polohu (x, y) objektu a poté obrazovku znovu vykreslíme.
Jak tedy pohybujeme objekty na obrazovce? Vše je o kartézských souřadnicích: změníme polohu objektu (x, y) a poté obrazovku překreslíme.
Obvykle potřebujete následující kroky k dosažení*pohybu* na obrazovce:
Obvykle potřebujete následující kroky, abyste dosáhli*pohybu* na obrazovce:
1. **Nastavit novou polohu** objektu; to je nutné, aby se objekt jevil jako pohybující se.
2. **Vyčistit obrazovku**, obrazovka musí být mezi jednotlivými vykresleními vyčištěna. Můžeme ji vyčistit vykreslením obdélníku, který vyplníme barvou pozadí.
3. **Znovu vykreslit objekt** na nové poloze. Tímto konečně dosáhneme přesunu objektu z jednoho místa na druhé.
1. **Nastavte novou polohu** objektu; to je nutné, aby se zdálo, že se objekt pohybuje.
2. **Vymažte obrazovku**, obrazovka musí být mezi jednotlivými vykresleními vymazána. Toho dosáhneme vykreslením obdélníku, který vyplníme barvou pozadí.
3. **Znovu vykreslete objekt** na nové poloze. Tímto způsobem nakonec dosáhneme pohybu objektu z jednoho místa na druhé.
Takto to může vypadat v kódu:
@ -39,15 +39,15 @@ ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
✅ Dokážete si představit důvod, proč by opakované vykreslování vašeho hrdiny mnohokrát za sekundu mohlo způsobit výkonové problémy? Přečtěte si o [alternativách k tomuto vzoru](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
✅ Dokážete si představit, proč by překreslování vašeho hrdiny mnohokrát za sekundu mohlo způsobit výkonové problémy? Přečtěte si o [alternativách k tomuto vzoru](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
## Zpracování událostí klávesnice
Události zpracováváte tak, že kódu připojíte konkrétní události. Události klávesnice se spouštějí na celém okně, zatímco události myši, jako je `click`, mohou být připojeny ke kliknutí na konkrétní prvek. V tomto projektu budeme používat události klávesnice.
Události zpracováváte připojením konkrétních událostí ke kódu. Události klávesnice se spouštějí na celém okně, zatímco události myši, jako je `click`, mohou být spojeny s kliknutím na konkrétní prvek. V tomto projektu budeme používat události klávesnice.
Pro zpracování události musíte použít metodu `addEventListener()` okna a poskytnout jí dva vstupní parametry. Prvním parametrem je název události, například `keyup`. Druhým parametrem je funkce, která by měla být vyvolána v důsledku proběhnutí události.
Pro zpracování události musíte použít metodu `addEventListener()` okna a poskytnout jí dva vstupní parametry. Prvním parametrem je název události, například `keyup`. Druhým parametrem je funkce, která by měla být vyvolána v důsledku události.
Pro události klávesnice existují dvě vlastnosti na události, které můžete použít k zjištění, která klávesa byla stisknuta:
Pro události kláves existují dvě vlastnosti události, které můžete použít k určení, která klávesa byla stisknuta:
- `key`, což je textová reprezentace stisknuté klávesy, například `ArrowUp`.
- `key`, což je textová reprezentace stisknuté klávesy, například `ArrowUp`
- `keyCode`, což je číselná reprezentace, například `37`, odpovídá `ArrowLeft`.
✅ Manipulace s událostmi klávesnice je užitečná i mimo vývoj her. Jaké další využití této techniky vás napadá?
✅ Manipulace s událostmi kláves je užitečná i mimo vývoj her. Jaké další využití této techniky vás napadají?
### Speciální klávesy: upozornění
Existují některé *speciální* klávesy, které ovlivňují okno. To znamená, že pokud posloucháte událost `keyup` a použijete tyto speciální klávesy k pohybu svého hrdiny, provede se také horizontální posouvání. Z tohoto důvodu možná budete chtít *vypnout* toto vestavěné chování prohlížeče při vytváření své hry. Potřebujete kód jako tento:
Existují některé *speciální* klávesy, které ovlivňují okno. To znamená, že pokud posloucháte událost `keyup` a použijete tyto speciální klávesy k pohybu svého hrdiny, dojde také k horizontálnímu posouvání. Z tohoto důvodu možná budete chtít *vypnout* toto vestavěné chování prohlížeče při vytváření své hry. Potřebujete kód jako tento:
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
Výše uvedený kód zajistí, že šipkové klávesy a mezerník budou mít své *výchozí* chování vypnuté. Mechanismus *vypnutí*se provede, když zavoláme `e.preventDefault()`.
Výše uvedený kód zajistí, že šipky a mezerník budou mít své *výchozí* chování vypnuté. Mechanismus *vypnutí*nastane, když zavoláme `e.preventDefault()`.
## Pohyb vyvolaný hrou
## Pohyb řízený hrou
Můžeme nechat objekty pohybovat se samy pomocí časovačů, jako jsou funkce `setTimeout()` nebo `setInterval()`, které aktualizují polohu objektu při každém tiknutí nebo časovém intervalu. Takto to může vypadat:
Objekty se mohou pohybovat samy pomocí časovačů, jako jsou funkce `setTimeout()` nebo `setInterval()`, které aktualizují polohu objektu při každém tiknutí nebo časovém intervalu. Takto to může vypadat:
```javascript
let id = setInterval(() => {
@ -103,9 +103,9 @@ let id = setInterval(() => {
## Herní smyčka
Herní smyčka je koncept, který je v podstatě funkcí vyvolávanou v pravidelných intervalech. Nazývá se herní smyčka, protože vše, co by mělo být viditelné pro uživatele, je vykresleno v této smyčce. Herní smyčka využívá všechny herní objekty, které jsou součástí hry, a vykresluje je, pokud z nějakého důvodu již nejsou součástí hry. Například pokud je objekt nepřítel, který byl zasažen laserem a explodoval, již není součástí aktuální herní smyčky (o tom se dozvíte více v dalších lekcích).
Herní smyčka je koncept, který v podstatě představuje funkci vyvolávanou v pravidelných intervalech. Říká se jí herní smyčka, protože vše, co by mělo být viditelné pro uživatele, je vykresleno v této smyčce. Herní smyčka využívá všechny herní objekty, které jsou součástí hry, a vykresluje je, pokud z nějakého důvodu již nejsou součástí hry. Například pokud je objekt nepřítel, který byl zasažen laserem a exploduje, již není součástí aktuální herní smyčky (o tom se dozvíte více v dalších lekcích).
Takto může typická herní smyčka vypadat, vyjádřená v kódu:
Takto může typická herní smyčka vypadat v kódu:
```javascript
let gameLoopId = setInterval(() =>
@ -119,18 +119,18 @@ let gameLoopId = setInterval(() =>
}, 200);
```
Výše uvedená smyčka je vyvolávána každých `200` milisekund, aby znovu vykreslila plátno. Máte možnost zvolit nejlepší interval, který dává smysl pro vaši hru.
Výše uvedená smyčka je vyvolávána každých `200` milisekund, aby překreslila plátno. Máte možnost zvolit nejlepší interval, který dává smysl pro vaši hru.
## Pokračování vesmírné hry
## Pokračování ve vesmírné hře
Vezmete existující kód a rozšíříte ho. Buď začněte s kódem, který jste dokončili během části I, nebo použijte kód z [části II - startovací](../../../../6-space-game/3-moving-elements-around/your-work).
Vezmete existující kód a rozšíříte ho. Buď začněte s kódem, který jste dokončili během části I, nebo použijte kód z [části II - startér](../../../../6-space-game/3-moving-elements-around/your-work).
- **Pohyb hrdiny**: přidáte kód, který zajistí, že můžete hrdinu pohybovat pomocí šipek.
- **Pohyb nepřátel**: také budete muset přidat kód, který zajistí, že se nepřátelé pohybují shora dolů v daném tempu.
- **Pohyb hrdiny**: přidáte kód, který zajistí, že můžete pohybovat hrdinou pomocí šipek.
- **Pohyb nepřátel**: budete také muset přidat kód, který zajistí, že se nepřátelé pohybují shora dolů v daném tempu.
## Doporučené kroky
Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měla by obsahovat následující:
Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měly by obsahovat následující:
```bash
-| assets
@ -141,23 +141,21 @@ Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měla
-| package.json
```
Svůj projekt spustíte ve složce `your_work` zadáním:
Spusťte svůj projekt ve složce `your_work` zadáním:
```bash
cd your-work
npm start
```
Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu, právě teď by měl zobrazit hrdinu a všechny nepřátele; zatím se nic nepohybuje!
Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu, aktuálně by měl zobrazit hrdinu a všechny nepřátele; zatím se nic nehýbe!
### Přidání kódu
1. **Přidejte dedikované objekty** pro `hero`, `enemy` a `game object`, měly by mít vlastnosti `x` a `y`. (Pamatujte na část o [dědičnosti nebo kompozici](../README.md)).
*TIP*`game object` by měl být ten, který má `x` a `y` a schopnost vykreslit se na plátno.
*TIP*: Začněte přidáním nové třídy GameObject s jejím konstruktorem, jak je uvedeno níže, a poté ji vykreslete na plátno:
>tip: začněte přidáním nové třídy GameObject s jejím konstruktorem, jak je uvedeno níže, a poté ji vykreslete na plátno:
```javascript
class GameObject {
@ -177,8 +175,8 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
}
```
Nyní rozšiřte tento GameObject, abyste vytvořili Hero a Enemy.
Nyní rozšiřte tento GameObject a vytvořte Hero a Enemy.
```javascript
class Hero extends GameObject {
constructor(x, y) {
@ -205,9 +203,9 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
}
```
2. **Přidejte zpracování událostí kláves** pro navigaci (pohyb hrdiny nahoru/dolů vlevo/vpravo)
2. **Přidejte obslužné funkce událostí kláves** pro navigaci (pohyb hrdiny nahoru/dolů, vlevo/vpravo).
*PAMATUJTE* je to kartézský systém, levý horní roh je `0,0`. Také nezapomeňte přidat kód pro zastavení *výchozího chování*.
*PAMATUJTE*: Jde o kartézský systém, levý horní roh je `0,0`. Také nezapomeňte přidat kód pro zastavení *výchozího chování*.
>tip: vytvořte svou funkci onKeyDown a připojte ji k oknu:
@ -221,9 +219,9 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
window.addEventListener("keydown", onKeyDown);
```
Zkontrolujte konzoli svého prohlížeče v tomto bodě a sledujte zaznamenané stisky kláves.
Zkontrolujte konzoli prohlížeče a sledujte, jak se zaznamenávají stisky kláves.
3. **Implementujte** [Pub sub pattern](../README.md), což udrží váš kód čistý, jak budete pokračovat v dalších částech.
3. **Implementujte** [Pub-sub vzor](../README.md), který udrží váš kód čistý, jak budete pokračovat v dalších částech.
Pro tuto poslední část můžete:
@ -311,9 +309,9 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
}
```
1. **Nastavit herní smyčku**
1. **Nastavte herní smyčku**
Refaktorujte funkci window.onload, aby inicializovala hru a nastavila herní smyčku na vhodný interval. Také přidáte laserový paprsek:
Refaktorujte funkci window.onload tak, aby inicializovala hru a nastavila herní smyčku na vhodný interval. Přidáte také laserový paprsek:
```javascript
window.onload = async () => {
@ -334,7 +332,7 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
};
```
5. **Přidejte kód** pro pohyb nepřátel v určitém intervalu
5. **Přidejte kód** pro pohyb nepřátel v určitém intervalu.
Refaktorujte funkci `createEnemies()`, aby vytvořila nepřátele a přidala je do nové třídy gameObjects:
@ -376,27 +374,27 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
}
```
Vaši nepřátelé by měli začít postupovat na vaši vesmírnou loď!
Vaši nepřátelé by měli začít postupovat směrem k vaší vesmírné lodi!
---
## 🚀 Výzva
Jak vidíte, váš kód se může proměnit v "špagetový kód", když začnete přidávat funkce, proměnné a třídy. Jak můžete lépe organizovat svůj kód, aby byl čitelnější? Navrhněte systém pro organizaci svého kódu, i když stále zůstává v jednom souboru.
Jak vidíte, váš kód se může stát „špagetovým kódem“, když začnete přidávat funkce, proměnné a třídy. Jak můžete lépe organizovat svůj kód, aby byl čitelnější? Navrhněte systém pro organizaci svého kódu, i když stále zůstává v jednom souboru.
## Kvíz po přednášce
## Kvíz po lekci
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/34)
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/34)
## Přehled a samostudium
## Recenze a samostudium
I když píšeme naši hru bez použití frameworků, existuje mnoho JavaScriptových frameworků pro vývoj her na plátně. Udělejte si čas na [čtení o těchto](https://github.com/collections/javascript-game-engines).
I když píšeme naši hru bez použití frameworků, existuje mnoho JavaScriptových frameworků pro vývoj her na plátně. Věnujte nějaký čas [čtení o těchto](https://github.com/collections/javascript-game-engines).
## Úkol
## Zadání
[Okomentujte svůj kód](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/35)
V této lekci se naučíte střílet lasery pomocí JavaScriptu! Do naší hry přidáme dvě věci:
V této lekci se naučíte, jak střílet lasery pomocí JavaScriptu! Do naší hry přidáme dvě věci:
- **Laser**: tento laser bude vystřelen z lodi vašeho hrdiny a bude se pohybovat vertikálně nahoru
- **Detekce kolizí**, jako součást implementace schopnosti *střílet* přidáme také několik herních pravidel:
- **Laser zasáhne nepřítele**: Nepřítel zemře, pokud ho zasáhne laser
- **Laser zasáhne horní část obrazovky**: Laser bude zničen, pokud zasáhne horní část obrazovky
- **Kolize nepřítele a hrdiny**: Nepřítel i hrdina budou zničeni, pokud do sebe narazí
- **Nepřítel zasáhne spodní část obrazovky**: Nepřítel i hrdina budou zničeni, pokud nepřítel zasáhne spodní část obrazovky
- **Laser zasáhne nepřítele**: Nepřítel zemře, pokud je zasažen laserem
- **Laser zasáhne horní část obrazovky**: Laser je zničen, pokud zasáhne horní část obrazovky
- **Kolize nepřítele a hrdiny**: Nepřítel i hrdina jsou zničeni, pokud do sebe narazí
- **Nepřítel zasáhne spodní část obrazovky**: Nepřítel i hrdina jsou zničeni, pokud nepřítel zasáhne spodní část obrazovky
Stručně řečeno, vy -- *hrdina* -- musíte zasáhnout všechny nepřátele laserem, než se dostanou na spodní část obrazovky.
Stručně řečeno, vy -- *hrdina* -- musíte zasáhnout všechny nepřátele laserem dříve, než se dostanou na spodní část obrazovky.
✅ Udělejte si malý průzkum o úplně první počítačové hře, která byla kdy napsána. Jaká byla její funkčnost?
@ -34,7 +34,7 @@ Jak provádíme detekci kolizí? Musíme si představit herní objekty jako obd
Pokud se dva obdélníky, například hrdina a nepřítel, *protnou*, dojde ke kolizi. Co by se mělo stát, záleží na pravidlech hry. K implementaci detekce kolizí tedy potřebujete následující:
1. Způsob, jak získat obdélníkové vyjádření herního objektu, například takto:
1. Způsob, jak získat obdélníkové zastoupení herního objektu, něco jako toto:
```javascript
rectFromGameObject() {
@ -60,14 +60,14 @@ Pokud se dva obdélníky, například hrdina a nepřítel, *protnou*, dojde ke k
## Jak ničíme objekty
Abychom mohli ve hře něco zničit, musíme hře sdělit, že tento objekt již nemá být vykreslen v herní smyčce, která se spouští v určitém intervalu. Jedním ze způsobů je označit herní objekt jako *mrtvý*, když se něco stane, například takto:
Abychom mohli ničit objekty ve hře, musíme dát hře vědět, že tento objekt by se již neměl vykreslovat v herní smyčce, která se spouští v určitém intervalu. Jedním ze způsobů je označit herní objekt jako *mrtvý*, když se něco stane, například takto:
```javascript
// collision happened
enemy.dead = true
```
Poté můžete *mrtvé* objekty odstranit před opětovným vykreslením obrazovky, například takto:
Poté můžete pokračovat s odstraněním *mrtvých* objektů před překreslením obrazovky, například takto:
Vystřelení laseru znamená reagovat na klávesovou událost a vytvořit objekt, který se pohybuje určitým směrem. Musíme tedy provést následující kroky:
Vystřelení laseru znamená reagovat na událost klávesnice a vytvořit objekt, který se pohybuje určitým směrem. Proto musíme provést následující kroky:
1. **Vytvořit laserový objekt**: z horní části lodi našeho hrdiny, který se po vytvoření začne pohybovat směrem nahoru k horní části obrazovky.
2. **Přiřadit kód ke klávesové události**: musíme vybrat klávesu na klávesnici, která bude představovat střelbu laseru hráčem.
2. **Připojit kód k události klávesnice**: musíme vybrat klávesu na klávesnici, která bude reprezentovat střelbu laseru hráčem.
3. **Vytvořit herní objekt, který vypadá jako laser**, když je klávesa stisknuta.
## Časový limit pro laser
Laser musí být vystřelen pokaždé, když stisknete klávesu, například *mezerník*. Aby hra nevytvářela příliš mnoho laserů v krátkém čase, musíme to opravit. Řešením je implementace tzv. *časového limitu*, časovače, který zajistí, že laser může být vystřelen jen v určitých intervalech. To můžete implementovat následujícím způsobem:
Laser by měl být vystřelen pokaždé, když stisknete klávesu, například *mezerník*. Abychom zabránili hře vytvářet příliš mnoho laserů v krátkém čase, musíme to opravit. Řešením je implementace tzv. *časového limitu*, časovače, který zajistí, že laser může být vystřelen jen v určitých intervalech. Můžete to implementovat následujícím způsobem:
```javascript
class Cooldown {
@ -109,23 +109,23 @@ class Weapon {
}
```
✅ Podívejte se na lekci 1 v sérii vesmírných her, abyste si připomněli, jak fungují *časové limity*.
✅ Podívejte se na lekci 1 v sérii o vesmírné hře, abyste si připomněli, jak fungují *časové limity*.
## Co vytvořit
Vezmete stávající kód (který byste měli vyčistit a refaktorovat) z předchozí lekce a rozšíříte ho. Buď začněte s kódem z části II, nebo použijte kód z [části III - startovací](../../../../6-space-game/4-collision-detection/your-work).
Vezmete existující kód (který byste měli mít vyčištěný a refaktorovaný) z předchozí lekce a rozšíříte ho. Buď začněte s kódem z části II, nebo použijte kód z [části III - startovací](../../../../6-space-game/4-collision-detection/your-work).
> tip: laser, se kterým budete pracovat, je již ve vaší složce s prostředky a je odkazován vaším kódem
- **Přidejte detekci kolizí**, když laser narazí na něco, měla by platit následující pravidla:
1. **Laser zasáhne nepřítele**: nepřítel zemře, pokud ho zasáhne laser
2. **Laser zasáhne horní část obrazovky**: laser bude zničen, pokud zasáhne horní část obrazovky
3. **Kolize nepřítele a hrdiny**: nepřítel i hrdina budou zničeni, pokud do sebe narazí
4. **Nepřítel zasáhne spodní část obrazovky**: nepřítel i hrdina budou zničeni, pokud nepřítel zasáhne spodní část obrazovky
1. **Laser zasáhne nepřítele**: nepřítel zemře, pokud je zasažen laserem
2. **Laser zasáhne horní část obrazovky**: laser je zničen, pokud zasáhne horní část obrazovky
3. **Kolize nepřítele a hrdiny**: nepřítel i hrdina jsou zničeni, pokud do sebe narazí
4. **Nepřítel zasáhne spodní část obrazovky**: nepřítel i hrdina jsou zničeni, pokud nepřítel zasáhne spodní část obrazovky
## Doporučené kroky
Najděte soubory, které byly pro vás vytvořeny ve složce `your-work`. Měla by obsahovat následující:
Najděte soubory, které byly pro vás vytvořeny ve složce `your-work`. Měly by obsahovat následující:
```bash
-| assets
@ -144,11 +144,11 @@ cd your-work
npm start
```
Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu, aktuálně by se měl zobrazit hrdina a všichni nepřátelé, nic se však zatím nehýbe :).
Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu, aktuálně by měl zobrazit hrdinu a všechny nepřátele, nic se zatím nehýbe :).
### Přidání kódu
1. **Nastavte obdélníkové vyjádření svého herního objektu pro zpracování kolizí**. Následující kód umožňuje získat obdélníkové vyjádření `GameObject`. Upravte svou třídu GameObject, aby ji rozšířila:
1. **Nastavte obdélníkové zastoupení herního objektu pro zpracování kolizí**. Následující kód umožňuje získat obdélníkové zastoupení `GameObject`. Upravte svou třídu GameObject, aby ji rozšířila:
```javascript
rectFromGameObject() {
@ -175,7 +175,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
```
3. **Přidejte schopnost střílet laser**
1. **Přidejte zprávu pro klávesovou událost**. Klávesa *mezerník* by měla vytvořit laser těsně nad lodí hrdiny. Přidejte tři konstanty do objektu Messages:
1. **Přidejte zprávu pro událost klávesnice**. Klávesa *mezerník* by měla vytvořit laser těsně nad lodí hrdiny. Přidejte tři konstanty do objektu Messages:
```javascript
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
@ -183,7 +183,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
1. **Zpracujte klávesu mezerník**. Upravte funkci `window.addEventListener` pro událost keyup, aby zpracovávala mezerník:
1. **Zpracujte klávesu mezerník**. Upravte funkci `window.addEventListener` pro událost `keyup`, aby zpracovávala mezerník:
```javascript
} else if(evt.keyCode === 32) {
@ -200,7 +200,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
}
```
a přidejte novou funkci `eventEmitter.on()`, aby se zajistilo chování, když nepřítel narazí na laser:
a přidejte novou funkci `eventEmitter.on()`, která zajistí chování, když nepřítel narazí na laser:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -209,7 +209,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
})
```
1. **Pohyb objektu**, zajistěte, aby se laser postupně pohyboval k horní části obrazovky. Vytvoříte novou třídu Laser, která rozšiřuje `GameObject`, stejně jako dříve:
1. **Pohybujte objektem**, zajistěte, aby se laser postupně pohyboval k horní části obrazovky. Vytvoříte novou třídu Laser, která rozšiřuje `GameObject`, jak jste to udělali dříve:
```javascript
class Laser extends GameObject {
@ -230,7 +230,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
}
```
1. **Zpracování kolizí**, implementujte pravidla kolizí pro laser. Přidejte funkci `updateGameObjects()`, která testuje kolidující objekty:
1. **Zpracujte kolize**, implementujte pravidla kolizí pro laser. Přidejte funkci `updateGameObjects()`, která testuje kolidující objekty:
```javascript
function updateGameObjects() {
@ -252,7 +252,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
}
```
Ujistěte se, že jste přidali`updateGameObjects()` do herní smyčky v `window.onload`.
Ujistěte se, že přidáte`updateGameObjects()` do herní smyčky v `window.onload`.
4. **Implementujte časový limit** pro laser, aby mohl být vystřelen jen v určitých intervalech.
@ -285,7 +285,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
}
```
V tomto bodě má vaše hra určitou funkčnost! Můžete se pohybovat pomocí šipek, střílet laser mezerníkem a nepřátelé zmizí, když je zasáhnete. Skvělá práce!
V tomto bodě má vaše hra nějakou funkčnost! Můžete se pohybovat pomocí šipek, střílet laser mezerníkem a nepřátelé mizí, když je zasáhnete. Skvělá práce!
---
@ -297,7 +297,7 @@ Přidejte explozi! Podívejte se na herní prostředky v [repozitáři Space Art
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/36)
## Přehled a samostudium
## Recenze a samostudium
Experimentujte s intervaly ve své hře. Co se stane, když je změníte? Přečtěte si více o [časových událostech v JavaScriptu](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/).
@ -307,5 +307,5 @@ Experimentujte s intervaly ve své hře. Co se stane, když je změníte? Přeč
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
@ -17,7 +17,7 @@ V této lekci se naučíte, jak přidat skóre do hry a počítat životy.
## Zobrazení textu na obrazovce
Abyste mohli zobrazit skóre hry na obrazovce, musíte vědět, jak umístit text na plátno. Odpovědí je použití metody `fillText()` na objektu canvas. Můžete také ovládat další aspekty, jako je použití konkrétního fontu, barvy textu nebo jeho zarovnání (vlevo, vpravo, na střed). Níže je ukázka kódu, který vykresluje text na obrazovce.
Abyste mohli zobrazit skóre hry na obrazovce, musíte vědět, jak umístit text na plátno. Odpovědí je použití metody `fillText()` na objektu canvas. Můžete také ovládat další aspekty, jako je výběr fontu, barva textu a jeho zarovnání (vlevo, vpravo, na střed). Níže je ukázka kódu, který vykresluje text na obrazovce.
```javascript
ctx.font = "30px Arial";
@ -26,22 +26,22 @@ ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
```
✅ Přečtěte si více o [přidávání textu na plátno](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) a klidně si svůj text upravte, aby vypadal lépe!
✅ Přečtěte si více o [přidávání textu na plátno](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) a klidně si svůj text udělejte ještě hezčí!
## Život jako herní koncept
Koncept života ve hře je pouze číslo. V kontextu vesmírné hry je běžné přiřadit určitý počet životů, které se odečítají jeden po druhém, když vaše loď utrpí poškození. Je hezké, pokud můžete zobrazit grafickou reprezentaci, například malé lodě nebo srdce, místo pouhého čísla.
Koncept života ve hře je pouze číslo. V kontextu vesmírné hry je běžné přiřadit určitý počet životů, které se odečítají jeden po druhém, když vaše loď utrpí poškození. Je skvělé, pokud můžete zobrazit grafickou reprezentaci, například malé lodě nebo srdíčka, místo pouhého čísla.
## Co vytvořit
Přidejte do své hry následující:
- **Herní skóre**: Za každou zničenou nepřátelskou loď by měl hrdina získat body, doporučujeme 100 bodů za loď. Herní skóre by mělo být zobrazeno vlevo dole.
- **Životy**: Vaše loď má tři životy. Ztratíte jeden život pokaždé, když do vás narazí nepřátelská loď. Počet životů by měl být zobrazen vpravo dole a měl by být tvořen následující grafikou .
- **Životy**: Vaše loď má tři životy. O život přijdete pokaždé, když do vás narazí nepřátelská loď. Počet životů by měl být zobrazen vpravo dole a měl by být tvořen následující grafikou .
## Doporučené kroky
Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měly by obsahovat následující:
Najděte soubory, které byly vytvořeny pro vás ve složce `your-work`. Měla by obsahovat následující:
```bash
-| assets
@ -60,17 +60,17 @@ cd your-work
npm start
```
Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu. V tuto chvíli by se měl zobrazit hrdina a všichni nepřátelé, a když stisknete šipky vlevo a vpravo, hrdina se pohybuje a může sestřelovat nepřátele.
Výše uvedený příkaz spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlížeč a zadejte tuto adresu. V tuto chvíli by se měl zobrazit hrdina a všichni nepřátelé. Jakmile stisknete šipky vlevo a vpravo, hrdina se pohybuje a může sestřelovat nepřátele.
### Přidání kódu
1. **Zkopírujte potřebné soubory** ze složky `solution/assets/` do složky `your-work`; přidáte soubor`life.png`. Přidejte `lifeImg` do funkce `window.onload`:
1. **Zkopírujte potřebné prostředky** ze složky `solution/assets/` do složky `your-work`; přidáte grafiku`life.png`. Přidejte `lifeImg` do funkce `window.onload`:
```javascript
lifeImg = await loadTexture("assets/life.png");
```
1. Přidejte `lifeImg` do seznamu aktiv:
1. Přidejte `lifeImg` do seznamu prostředků:
```javascript
let heroImg,
@ -82,7 +82,7 @@ Tím se spustí HTTP server na adrese `http://localhost:5000`. Otevřete prohlí
2. **Přidejte proměnné**. Přidejte kód, který reprezentuje vaše celkové skóre (0) a zbývající životy (3), a zobrazte tyto hodnoty na obrazovce.
3. **Rozšiřte funkci `updateGameObjects()`**. Rozšiřte funkci `updateGameObjects()`, aby zpracovávala kolize s nepřáteli:
3. **Rozšiřte funkci `updateGameObjects()`**. Rozšiřte funkci `updateGameObjects()` tak, aby zpracovávala kolize s nepřáteli:
```javascript
enemies.forEach(enemy => {
@ -183,21 +183,21 @@ Na konci této práce byste měli vidět malé lodě symbolizující životy vpr
## 🚀 Výzva
Váš kód je téměř hotový. Dokážete si představit své další kroky?
Váš kód je téměř hotový. Dokážete si představit další kroky?
## Kvíz po lekci
[Kvíz po lekci](https://ff-quizzes.netlify.app/web/quiz/38)
## Přehled a samostudium
## Recenze a samostudium
Prozkoumejte způsoby, jak můžete zvyšovat a snižovat herní skóre a životy. Existují zajímavé herní enginy, jako je [PlayFab](https://playfab.com). Jak by použití jednoho z nich mohlo vylepšit vaši hru?
Prozkoumejte způsoby, jak můžete zvyšovat a snižovat herní skóre a životy. Existují zajímavé herní enginy, jako například [PlayFab](https://playfab.com). Jak by použití jednoho z nich mohlo vylepšit vaši hru?
## Zadání
[Postavte hru se skóre](assignment.md)
[Vytvořte hru se skórováním](assignment.md)
---
**Prohlášení**:
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Existuje několik způsobů, jak vyjádřit *konečný stav* ve hře. Je na vás jako na tvůrci hry, abyste určili, proč hra skončila. Zde jsou některé důvody, pokud předpokládáme, že mluvíme o vesmírné hře, kterou jste dosud vytvářeli:
- **Zničeno `N` nepřátelských lodí**: Je běžné, že pokud rozdělíte hru na různé úrovně, musíte zničit `N` nepřátelských lodí, abyste úroveň dokončili.
- **Bylo zničeno `N` nepřátelských lodí**: Je běžné, že pokud rozdělíte hru na různé úrovně, musíte zničit `N` nepřátelských lodí, abyste úroveň dokončili.
- **Vaše loď byla zničena**: Existují hry, kde prohrajete, pokud je vaše loď zničena. Dalším běžným přístupem je koncept životů. Pokaždé, když je vaše loď zničena, odečte se jeden život. Jakmile ztratíte všechny životy, hra končí.
- **Nasbíráno `N` bodů**: Dalším běžným konečným stavem je nasbírání bodů. Jak získáte body, je na vás, ale je běžné přiřadit body různým aktivitám, jako je zničení nepřátelské lodi nebo sbírání předmětů, které se objeví, když jsou zničeny.
- **Nasbírali jste `N` bodů**: Další běžný konečný stav je, že nasbíráte body. Jak body získáváte, je na vás, ale je běžné přiřadit body různým aktivitám, jako je zničení nepřátelské lodi nebo sbírání předmětů, které se objeví, když jsou zničeny.
- **Dokončení úrovně**: To může zahrnovat několik podmínek, jako je zničení `X` nepřátelských lodí, nasbírání `Y` bodů nebo třeba získání konkrétního předmětu.
## Restartování
@ -31,7 +31,7 @@ Pokud se lidem vaše hra líbí, pravděpodobně ji budou chtít hrát znovu. Ja
Do své hry přidáte tyto pravidla:
1. **Výhra ve hře**. Jakmile budou zničeny všechny nepřátelské lodě, vyhráváte hru. Navíc zobrazte nějakou zprávu o vítězství.
1. **Restart**. Jakmile ztratíte všechny životy nebo vyhrajete hru, měli byste nabídnout možnost restartu hry. Pamatujte! Budete muset znovu inicializovat hru a vymazat předchozí stav hry.
1. **Restart**. Jakmile ztratíte všechny životy nebo vyhrajete hru, měli byste nabídnout možnost restartu hry. Pamatujte! Budete muset hru znovu inicializovat a předchozí stav hry by měl být vymazán.
## Doporučené kroky
@ -125,7 +125,7 @@ Výše uvedené spustí HTTP server na adrese `http://localhost:5000`. Otevřete
}
```
1. **Přidání restartovací zprávy**. Přidejte tuto zprávu do constants Messages:
1. **Přidejte restartovací zprávu**. Přidejte tuto zprávu do constants Messages:
Vaším úkolem je vytvořit novou ukázkovou hru, takže prozkoumejte některé zajímavé hry, abyste zjistili, jaký typ hry byste mohli vytvořit.
Vaším úkolem je vytvořit nový vzorový příklad hry, takže prozkoumejte některé zajímavé hry, abyste zjistili, jaký typ hry byste mohli vytvořit.
## Úkol
[Vytvořte ukázkovou hru](assignment.md)
[Vytvořte vzorovou hru](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatizovaný překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Od příchodu JavaScriptu do prohlížečů se webové stránky stávají interaktivnějšími a složitějšími než kdy dříve. Webové technologie se nyní běžně používají k vytváření plně funkčních aplikací, které běží přímo v prohlížeči, a nazýváme je [webové aplikace](https://en.wikipedia.org/wiki/Web_application). Protože jsou webové aplikace vysoce interaktivní, uživatelé nechtějí čekat na úplné načtení stránky pokaždé, když provedou nějakou akci. Proto se používá JavaScript k přímé aktualizaci HTML pomocí DOM, aby se zajistil plynulejší uživatelský zážitek.
Od vzniku JavaScriptu v prohlížečích se webové stránky stávají interaktivnějšími a složitějšími než kdy dříve. Webové technologie se nyní běžně používají k vytváření plně funkčních aplikací, které běží přímo v prohlížeči, a nazýváme je [webové aplikace](https://en.wikipedia.org/wiki/Web_application). Protože jsou webové aplikace vysoce interaktivní, uživatelé nechtějí čekat na úplné načtení stránky pokaždé, když provedou nějakou akci. Proto se používá JavaScript k přímé aktualizaci HTML pomocí DOM, aby se zajistil plynulejší uživatelský zážitek.
V této lekci položíme základy pro vytvoření bankovní webové aplikace, přičemž použijeme HTML šablony k vytvoření více obrazovek, které lze zobrazit a aktualizovat bez nutnosti znovu načítat celou HTML stránku.
### Předpoklady
Pro testování webové aplikace, kterou v této lekci vytvoříme, potřebujete lokální webový server. Pokud ho nemáte, můžete nainstalovat [Node.js](https://nodejs.org) a použít příkaz `npx lite-server`z vaší složky projektu. Tím vytvoříte lokální webový server a otevřete svou aplikaci v prohlížeči.
Pro testování webové aplikace, kterou v této lekci vytvoříme, potřebujete lokální webový server. Pokud ho nemáte, můžete si nainstalovat [Node.js](https://nodejs.org) a použít příkaz `npx lite-server`ve složce svého projektu. Tím vytvoříte lokální webový server a otevřete svou aplikaci v prohlížeči.
### Příprava
Na svém počítači vytvořte složku s názvem `bank` a uvnitř ní soubor s názvem `index.html`. Začneme s tímto HTML [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code):
Na svém počítači vytvořte složku nazvanou `bank` a uvnitř ní soubor `index.html`. Začneme s tímto HTML [základem](https://en.wikipedia.org/wiki/Boilerplate_code):
```html
<!DOCTYPE html>
@ -50,21 +50,21 @@ Pokud chcete vytvořit více obrazovek pro webovou stránku, jedním řešením
- Při přepínání obrazovek musíte znovu načíst celé HTML, což může být pomalé.
- Je obtížné sdílet data mezi různými obrazovkami.
Dalším přístupem je mít pouze jeden HTML soubor a definovat více [HTML šablon](https://developer.mozilla.org/docs/Web/HTML/Element/template) pomocí elementu `<template>`. Šablona je znovupoužitelný HTML blok, který není prohlížečem zobrazen, a musí být instancován za běhu pomocí JavaScriptu.
Dalším přístupem je mít pouze jeden HTML soubor a definovat více [HTML šablon](https://developer.mozilla.org/docs/Web/HTML/Element/template) pomocí elementu `<template>`. Šablona je znovupoužitelný HTML blok, který není prohlížečem zobrazen a musí být instancován za běhu pomocí JavaScriptu.
### Úkol
Vytvoříme bankovní aplikaci se dvěma obrazovkami: přihlašovací stránkou a dashboardem. Nejprve přidáme do těla HTML zástupný prvek, který použijeme k instancování různých obrazovek naší aplikace:
Vytvoříme bankovní aplikaci se dvěma obrazovkami: přihlašovací stránkou a dashboardem. Nejprve přidáme do těla HTML prvek zástupce, který použijeme k instancování různých obrazovek naší aplikace:
```html
<divid="app">Loading...</div>
```
Dáváme mu `id`, aby bylo později snazší ho najít pomocí JavaScriptu.
Dáváme mu atribut `id`, aby bylo později snazší ho najít pomocí JavaScriptu.
> Tip: protože obsah tohoto prvku bude nahrazen, můžeme do něj vložit zprávu nebo indikátor načítání, který se zobrazí během načítání aplikace.
> Tip: protože obsah tohoto prvku bude nahrazen, můžeme do něj vložit zprávu o načítání nebo indikátor, který se zobrazí, zatímco se aplikace načítá.
Dále přidáme pod HTML šablonu pro přihlašovací stránku. Prozatím do ní vložíme pouze nadpis a sekci obsahující odkaz, který použijeme k navigaci.
Dále přidáme pod tento prvek HTML šablonu pro přihlašovací stránku. Prozatím do ní vložíme pouze nadpis a sekci obsahující odkaz, který použijeme k navigaci.
```html
<templateid="login">
@ -106,13 +106,13 @@ Poté přidáme další HTML šablonu pro stránku dashboardu. Tato stránka bud
</template>
```
> Tip: při vytváření HTML šablon, pokud chcete vidět, jak budou vypadat, můžete zakomentovat řádky `<template>` a `</template>` obklopením pomocí`<!-- -->`.
> Tip: při vytváření HTML šablon, pokud chcete vidět, jak budou vypadat, můžete zakomentovat řádky `<template>` a `</template>`tím, že je obklopíte `<!-- -->`.
✅ Proč si myslíte, že používáme atributy `id` na šablonách? Mohli bychom použít něco jiného, například třídy?
✅ Proč myslíte, že používáme atributy `id` na šablonách? Mohli bychom použít něco jiného, například třídy?
## Zobrazení šablon pomocí JavaScriptu
Pokud zkusíte svůj aktuální HTML soubor v prohlížeči, uvidíte, že se zasekne na zobrazení `Loading...`. To je proto, že musíme přidat nějaký JavaScriptový kód, který instancuje a zobrazí HTML šablony.
Pokud zkusíte aktuální HTML soubor v prohlížeči, uvidíte, že se zasekne na zobrazení `Loading...`. To je proto, že musíme přidat nějaký JavaScriptový kód, který instancuje a zobrazí HTML šablony.
Instancování šablony se obvykle provádí ve 3 krocích:
@ -120,11 +120,11 @@ Instancování šablony se obvykle provádí ve 3 krocích:
2. Klonování elementu šablony pomocí [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
3. Připojení k DOM pod viditelný prvek, například pomocí [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
✅ Proč musíme šablonu klonovat před jejím připojením k DOM? Co si myslíte, že by se stalo, kdybychom tento krok přeskočili?
✅ Proč musíme šablonu klonovat, než ji připojíme k DOM? Co si myslíte, že by se stalo, kdybychom tento krok přeskočili?
### Úkol
Vytvořte nový soubor s názvem `app.js` ve složce projektu a importujte tento soubor do sekce `<head>` vašeho HTML:
Vytvořte nový soubor nazvaný `app.js` ve složce svého projektu a importujte tento soubor do sekce `<head>` svého HTML:
```html
<scriptsrc="app.js"defer></script>
@ -142,7 +142,7 @@ function updateRoute(templateId) {
}
```
To, co zde děláme, je přesně 3 kroky popsané výše. Instancujeme šablonu s `id``templateId` a její klonovaný obsah vložíme do našeho zástupného prvku aplikace. Všimněte si, že musíme použít `cloneNode(true)`, abychom zkopírovali celý podstrom šablony.
To, co zde děláme, jsou přesně 3 kroky popsané výše. Instancujeme šablonu s `id``templateId` a vložíme její klonovaný obsah do našeho zástupce aplikace. Všimněte si, že musíme použít `cloneNode(true)`, abychom zkopírovali celý podstrom šablony.
Nyní zavolejte tuto funkci s jednou ze šablon a podívejte se na výsledek.
@ -154,7 +154,7 @@ updateRoute('login');
## Vytváření tras
Když mluvíme o webové aplikaci, nazýváme *Routing* záměr mapovat **URL** na konkrétní obrazovky, které by měly být zobrazeny. Na webové stránce s více HTML soubory se to děje automaticky, protože cesty k souborům se odrážejí v URL. Například s těmito soubory ve vaší složce projektu:
Když mluvíme o webové aplikaci, nazýváme *trasování* záměr mapovat **URL** na konkrétní obrazovky, které by měly být zobrazeny. Na webové stránce s více HTML soubory se to děje automaticky, protože cesty k souborům se odrážejí v URL. Například s těmito soubory ve složce vašeho projektu:
Nicméně, pro naši webovou aplikaci používáme jeden HTML soubor obsahující všechny obrazovky, takže toto výchozí chování nám nepomůže. Musíme tuto mapu vytvořit ručně a aktualizovat zobrazenou šablonu pomocí JavaScriptu.
Nicméně pro naši webovou aplikaci používáme jeden HTML soubor obsahující všechny obrazovky, takže nám toto výchozí chování nepomůže. Musíme tuto mapu vytvořit ručně a aktualizovat zobrazenou šablonu pomocí JavaScriptu.
### Úkol
Použijeme jednoduchý objekt k implementaci [mapy](https://en.wikipedia.org/wiki/Associative_array) mezi cestami URL a našimi šablonami. Přidejte tento objekt na začátek vašeho souboru `app.js`.
Použijeme jednoduchý objekt k implementaci [mapy](https://en.wikipedia.org/wiki/Associative_array) mezi cestami URL a našimi šablonami. Přidejte tento objekt na začátek svého souboru `app.js`.
```js
const routes = {
@ -198,9 +198,9 @@ function updateRoute() {
}
```
Zde jsme namapovali trasy, které jsme deklarovali, na odpovídající šablonu. Můžete vyzkoušet, že to funguje správně, změnou URL ručně ve vašem prohlížeči.
Zde jsme mapovali trasy, které jsme deklarovali, na odpovídající šablonu. Můžete vyzkoušet, že to funguje správně, změnou URL ručně ve svém prohlížeči.
✅ Co se stane, pokud zadáte neznámou cestu do URL? Jak bychom to mohli vyřešit?
✅ Co se stane, když zadáte neznámou cestu do URL? Jak bychom to mohli vyřešit?
## Přidání navigace
@ -211,9 +211,9 @@ Dalším krokem pro naši aplikaci je přidání možnosti navigace mezi stránk
Druhou část jsme již vyřešili pomocí funkce `updateRoute`, takže musíme zjistit, jak aktualizovat aktuální URL.
Budeme muset použít JavaScript a konkrétně [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), který umožňuje aktualizovat URL a vytvořit nový záznam v historii prohlížení, aniž by se HTML znovu načítalo.
Budeme muset použít JavaScript a konkrétně [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), který umožňuje aktualizovat URL a vytvořit nový záznam v historii prohlížení, aniž by se znovu načítalo HTML.
> Poznámka: Zatímco HTML prvek kotvy [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) může být použit samostatně k vytvoření hypertextových odkazů na různé URL, ve výchozím nastavení způsobí, že prohlížeč znovu načte HTML. Je nutné zabránit tomuto chování při zpracování tras pomocí vlastního JavaScriptu, použitím funkce preventDefault() na události kliknutí.
> Poznámka: Zatímco HTML prvek kotvy [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) může být použit samostatně k vytvoření hypertextových odkazů na různé URL, ve výchozím nastavení způsobí, že prohlížeč znovu načte HTML. Je nutné tomuto chování zabránit při manipulaci s trasováním pomocí vlastního JavaScriptu, použitím funkce preventDefault() na události kliknutí.
### Úkol
@ -226,7 +226,7 @@ function navigate(path) {
}
```
Tato metoda nejprve aktualizuje aktuální URL na základě zadané cesty, poté aktualizuje šablonu. Vlastnost `window.location.origin` vrací kořen URL, což nám umožňuje rekonstruovat kompletní URL ze zadané cesty.
Tato metoda nejprve aktualizuje aktuální URL na základě zadané cesty a poté aktualizuje šablonu. Vlastnost `window.location.origin` vrací kořen URL, což nám umožňuje rekonstruovat kompletní URL ze zadané cesty.
Nyní, když máme tuto funkci, můžeme se postarat o problém, který máme, pokud cesta neodpovídá žádné definované trase. Upravením funkce `updateRoute` přidáme záložní trasu na jednu z existujících tras, pokud nemůžeme najít shodu.
@ -244,7 +244,7 @@ function updateRoute() {
Pokud nelze najít trasu, nyní přesměrujeme na stránku `login`.
Nyní vytvořme funkci pro získání URL při kliknutí na odkaz a zabránění výchozímu chování odkazu prohlížeče:
Nyní vytvořme funkci pro získání URL při kliknutí na odkaz a zabránění výchozímu chování prohlížeče při kliknutí na odkaz:
```js
function onLinkClick(event) {
@ -265,19 +265,19 @@ Objekt `event` výše zachytí událost `click` a předá ji naší funkci `onLi
Pomocí atributu [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) připojte událost `click` k JavaScriptovému kódu, zde volání funkce `navigate()`.
Zkuste kliknout na tyto odkazy, nyní byste měli být schopni navigovat mezi různými obrazovkami vaší aplikace.
Zkuste kliknout na tyto odkazy, nyní byste měli být schopni navigovat mezi různými obrazovkami své aplikace.
✅ Metoda `history.pushState` je součástí standardu HTML5 a je implementována ve [všech moderních prohlížečích](https://caniuse.com/?search=pushState). Pokud vytváříte webovou aplikaci pro starší prohlížeče, existuje trik, který můžete použít místo této API: použití [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) před cestou vám umožní implementovat trasování, které funguje s běžnou navigací kotvy a nenačítá stránku znovu, protože jeho účelem bylo vytvořit interní odkazy na stránce.
✅ Metoda `history.pushState` je součástí standardu HTML5 a je implementována [ve všech moderních prohlížečích](https://caniuse.com/?search=pushState). Pokud vytváříte webovou aplikaci pro starší prohlížeče, existuje trik, který můžete použít místo této API: použití [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) před cestou vám umožní implementovat trasování, které funguje s běžnou navigací kotvy a nenačítá stránku znovu, protože jeho účelem bylo vytvořit interní odkazy na stránce.
## Zpracování tlačítek zpět a vpřed v prohlížeči
## Řešení tlačítek zpět a vpřed v prohlížeči
Použití `history.pushState` vytváří nové záznamy v historii navigace prohlížeče. Můžete to zkontrolovat podržením *tlačítka zpět*vašeho prohlížeče, mělo by zobrazit něco jako toto:
Použití `history.pushState` vytváří nové záznamy v historii navigace prohlížeče. Můžete to zkontrolovat podržením *tlačítka zpět*svého prohlížeče, mělo by zobrazit něco jako toto:

Pokud zkusíte několikrát kliknout na tlačítko zpět, uvidíte, že se aktuální URL mění a historie se aktualizuje, ale stále se zobrazuje stejná šablona.
To je proto, že aplikace neví, že je potřeba zavolat `updateRoute()` pokaždé, když se historie změní. Pokud se podíváte na [dokumentaci `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), můžete vidět, že pokud se stav změní - což znamená, že jsme se přesunuli na jiné URL - je vyvolána událost [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event). Použijeme to k vyřešení tohoto problému.
To je proto, že aplikace neví, že je potřeba zavolat `updateRoute()` pokaždé, když se historie změní. Pokud se podíváte na [dokumentaci `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), můžete vidět, že pokud se stav změní - což znamená, že jsme se přesunuli na jiné URL - je spuštěna událost [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event). Použijeme to k vyřešení tohoto problému.
### Úkol
@ -296,7 +296,7 @@ Zde je video o arrow funkcích:
> 🎥 Klikněte na obrázek výše pro video o arrow funkcích.
Nyní zkuste použít tlačítka zpět a vpřed ve vašem prohlížeči a zkontrolujte, že zobrazená trasa je tentokrát správně aktualizována.
Nyní zkuste použít tlačítka zpět a vpřed svého prohlížeče a zkontrolujte, že zobrazená trasa je tentokrát správně aktualizována.
---
@ -314,9 +314,9 @@ Trasování je jednou z překvapivě složitých částí vývoje webu, zejména
## Zadání
[Vylepšete trasování](assignment.md)
[Zlepšete trasování](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
V téměř všech moderních webových aplikacích si můžete vytvořit účet, abyste měli svůj vlastní soukromý prostor. Protože k webové aplikaci může přistupovat více uživatelů současně, je potřeba mechanismus, který umožní ukládat osobní údaje každého uživatele odděleně a vybrat, které informace zobrazit. Nebudeme se zabývat tím, jak [bezpečně spravovat identitu uživatele](https://en.wikipedia.org/wiki/Authentication), protože je to samostatné rozsáhlé téma, ale zajistíme, aby si každý uživatel mohl vytvořit jeden (nebo více) bankovních účtů v naší aplikaci.
V téměř všech moderních webových aplikacích si můžete vytvořit účet, abyste měli svůj vlastní soukromý prostor. Protože k webové aplikaci může přistupovat více uživatelů současně, je potřeba mechanismus pro oddělené ukládání osobních dat každého uživatele a výběr informací, které se mají zobrazit. Nebudeme se zabývat tím, jak [bezpečně spravovat identitu uživatele](https://en.wikipedia.org/wiki/Authentication), protože je to samostatné rozsáhlé téma, ale zajistíme, aby si každý uživatel mohl vytvořit jeden (nebo více) bankovních účtů v naší aplikaci.
V této části použijeme HTML formuláře k přidání přihlášení a registrace do naší webové aplikace. Ukážeme si, jak programově odesílat data na serverovou API, a nakonec jak definovat základní pravidla validace pro vstupy uživatele.
V této části použijeme HTML formuláře k přidání přihlašování a registrace do naší webové aplikace. Ukážeme si, jak programově odesílat data na serverovou API a nakonec, jak definovat základní validační pravidla pro vstupy uživatele.
### Předpoklady
Musíte mít dokončenou část [HTML šablony a směrování](../1-template-route/README.md) webové aplikace pro tuto lekci. Také je potřeba nainstalovat [Node.js](https://nodejs.org) a [spustit serverovou API](../api/README.md) lokálně, abyste mohli odesílat data pro vytvoření účtů.
Musíte mít dokončenou část [HTML šablony a směrování](../1-template-route/README.md) webové aplikace z této lekce. Také je potřeba nainstalovat [Node.js](https://nodejs.org) a [spustit serverovou API](../api/README.md) lokálně, abyste mohli odesílat data pro vytvoření účtů.
**Poznámka**
Budete mít spuštěné dva terminály současně, jak je uvedeno níže:
@ -41,7 +41,7 @@ curl http://localhost:5000/api
## Formulář a ovládací prvky
Element `<form>`obklopuje část HTML dokumentu, kde uživatel může zadávat a odesílat data pomocí interaktivních ovládacích prvků. Existuje mnoho různých uživatelských rozhraní (UI) ovládacích prvků, které lze použít v rámci formuláře, nejběžnějšími jsou elementy `<input>` a `<button>`.
Element `<form>`zapouzdřuje část HTML dokumentu, kde uživatel může zadávat a odesílat data pomocí interaktivních ovládacích prvků. Existuje celá řada uživatelských rozhraní (UI) ovládacích prvků, které lze použít ve formuláři, přičemž nejběžnější jsou elementy `<input>` a `<button>`.
Existuje mnoho různých [typů](https://developer.mozilla.org/docs/Web/HTML/Element/input) `<input>`, například pro vytvoření pole, kde uživatel může zadat své uživatelské jméno, můžete použít:
@ -49,16 +49,16 @@ Existuje mnoho různých [typů](https://developer.mozilla.org/docs/Web/HTML/Ele
<inputid="username"name="username"type="text">
```
Atribut `name` bude použit jako název vlastnosti při odesílání dat formuláře. Atribut `id` se používá k propojení `<label>` s ovládacím prvkem formuláře.
Atribut `name` bude použit jako název vlastnosti při odesílání dat formuláře. Atribut `id` slouží k propojení `<label>` s ovládacím prvkem formuláře.
> Podívejte se na celý seznam [typů `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) a [dalších ovládacích prvků formuláře](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls), abyste získali představu o všech nativních UI prvcích, které můžete použít při vytváření svého rozhraní.
✅ Všimněte si, že `<input>` je [prázdný element](https://developer.mozilla.org/docs/Glossary/Empty_element), ke kterému byste *neměli* přidávat odpovídající uzavírací tag. Můžete však použít samouzavírací notaci `<input/>`, ale není to nutné.
✅ Všimněte si, že `<input>` je [prázdný element](https://developer.mozilla.org/docs/Glossary/Empty_element), ke kterému byste *neměli* přidávat odpovídající uzavírací značku. Můžete však použít samo-uzavírací notaci `<input/>`, ale není to nutné.
Element `<button>` v rámci formuláře je trochu speciální. Pokud nespecifikujete jeho atribut `type`, automaticky odešle data formuláře na server při stisknutí. Zde jsou možné hodnoty atributu `type`:
Element `<button>` ve formuláři je trochu speciální. Pokud nespecifikujete jeho atribut `type`, automaticky odešle data formuláře na server při stisknutí. Zde jsou možné hodnoty atributu `type`:
- `submit`: Výchozí hodnota v rámci`<form>`, tlačítko spustí akci odeslání formuláře.
- `reset`: Tlačítko resetuje všechny ovládací prvky formuláře na jejich počáteční hodnoty.
- `submit`: Výchozí hodnota ve`<form>`, tlačítko spustí akci odeslání formuláře.
- `reset`: Tlačítko resetuje všechny ovládací prvky formuláře na jejich výchozí hodnoty.
- `button`: Nepřiřazuje žádné výchozí chování při stisknutí tlačítka. Můžete mu pak přiřadit vlastní akce pomocí JavaScriptu.
### Úkol
@ -79,12 +79,12 @@ Začněme přidáním formuláře do šablony `login`. Budeme potřebovat pole p
</template>
```
Pokud se podíváte blíže, můžete si všimnout, že jsme zde také přidali element `<label>`. Elementy `<label>` se používají k přidání názvu k UI ovládacím prvkům, jako je naše pole pro uživatelské jméno. Popisky jsou důležité pro čitelnost vašich formulářů, ale přinášejí také další výhody:
Pokud se podíváte blíže, můžete si všimnout, že jsme zde také přidali element `<label>`. Elementy `<label>` se používají k přidání názvu k ovládacím prvkům UI, jako je naše pole pro uživatelské jméno. Popisky jsou důležité pro čitelnost vašich formulářů, ale přinášejí i další výhody:
- Propojením popisku s ovládacím prvkem formuláře pomáhá uživatelům, kteří používají asistivní technologie (například čtečku obrazovky), pochopit, jaká data se od nich očekávají.
- Kliknutím na popisek můžete přímo zaměřit přidružený vstup, což usnadňuje jeho dosažení na zařízeních s dotykovou obrazovkou.
- Propojením popisku s ovládacím prvkem formuláře pomáháte uživatelům využívajícím asistivní technologie (například čtečky obrazovky) pochopit, jaká data mají zadat.
- Kliknutím na popisek můžete přímo zaostřit na propojený vstup, což usnadňuje jeho dosažení na zařízeních s dotykovou obrazovkou.
> [Přístupnost](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) na webu je velmi důležité téma, které je často přehlíženo. Díky [semantickým HTML elementům](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) není obtížné vytvářet přístupný obsah, pokud je používáte správně. Můžete si [přečíst více o přístupnosti](https://developer.mozilla.org/docs/Web/Accessibility), abyste se vyhnuli běžným chybám a stali se odpovědným vývojářem.
> [Přístupnost](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) na webu je velmi důležité téma, které je často přehlíženo. Díky [sémantickým HTML elementům](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) není obtížné vytvářet přístupný obsah, pokud je používáte správně. Můžete si [přečíst více o přístupnosti](https://developer.mozilla.org/docs/Web/Accessibility), abyste se vyhnuli běžným chybám a stali se odpovědným vývojářem.
Nyní přidáme druhý formulář pro registraci, hned pod ten předchozí:
@ -107,25 +107,25 @@ Nyní přidáme druhý formulář pro registraci, hned pod ten předchozí:
Pomocí atributu `value` můžeme definovat výchozí hodnotu pro daný vstup.
Všimněte si také, že vstup pro `balance` má typ `number`. Vypadá jinak než ostatní vstupy? Zkuste s ním interagovat.
✅ Dokážete navigovat a interagovat s formuláři pouze pomocí klávesnice? Jak byste to udělali?
✅ Dokážete navigovat a pracovat s formuláři pouze pomocí klávesnice? Jak byste to udělali?
## Odesílání dat na server
Nyní, když máme funkční UI, dalším krokem je odeslání dat na server. Udělejme rychlý test pomocí našeho aktuálního kódu: co se stane, když kliknete na tlačítko *Přihlásit* nebo *Registrovat*?
Nyní, když máme funkční uživatelské rozhraní, dalším krokem je odeslání dat na server. Udělejme rychlý test s naším aktuálním kódem: co se stane, když kliknete na tlačítko *Přihlásit* nebo *Registrovat*?
Všimli jste si změny v sekci URL vašeho prohlížeče?


Výchozí akce pro `<form>` je odeslání formuláře na aktuální URL serveru pomocí [metody GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), připojením dat formuláře přímo k URL. Tato metoda má však některé nedostatky:
Výchozí akcí pro `<form>` je odeslání formuláře na aktuální URL serveru pomocí [metody GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), přičemž data formuláře se připojí přímo k URL. Tato metoda má však několik nevýhod:
- Odesílaná data jsou velmi omezená velikostí (asi 2000 znaků)
- Data jsou přímo viditelná v URL (není ideální pro hesla)
- Nepracuje s nahráváním souborů
- Data jsou přímo viditelná v URL (což není ideální pro hesla)
- Neumožňuje nahrávání souborů
Proto ji můžete změnit na použití [metody POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), která odesílá data formuláře na server v těle HTTP požadavku, bez předchozích omezení.
Proto ji můžete změnit na použití [metody POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), která odesílá data formuláře na server v těle HTTP požadavku, bez výše uvedených omezení.
> Zatímco POST je nejčastěji používaná metoda pro odesílání dat, [v některých specifických scénářích](https://www.w3.org/2001/tag/doc/whenToUseGet.html) je vhodnější použít metodu GET, například při implementaci vyhledávacího pole.
> I když je POST nejčastěji používanou metodou pro odesílání dat, [v některých specifických scénářích](https://www.w3.org/2001/tag/doc/whenToUseGet.html) je vhodnější použít metodu GET, například při implementaci vyhledávacího pole.
### Úkol
@ -139,18 +139,18 @@ Nyní zkuste zaregistrovat nový účet se svým jménem. Po kliknutí na tlač

Pokud vše proběhne správně, server by měl odpovědět na váš požadavek [JSON](https://www.json.org/json-en.html) odpovědí obsahující data účtu, který byl vytvořen.
Pokud vše proběhne správně, server by měl odpovědět na váš požadavek [JSON](https://www.json.org/json-en.html) odpovědí obsahující data vytvořeného účtu.
✅ Zkuste se zaregistrovat znovu se stejným jménem. Co se stane?
## Odesílání dat bez obnovení stránky
Jak jste si pravděpodobně všimli, existuje drobný problém s přístupem, který jsme právě použili: při odeslání formuláře se dostaneme z naší aplikace a prohlížeč přesměruje na URL serveru. Snažíme se vyhnout všem obnovením stránky v naší webové aplikaci, protože vytváříme [jednostránkovou aplikaci (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
Jak jste si pravděpodobně všimli, existuje malý problém s přístupem, který jsme právě použili: při odeslání formuláře opustíme naši aplikaci a prohlížeč přesměruje na URL serveru. Snažíme se vyhnout všem obnovením stránky v naší webové aplikaci, protože vytváříme [jednostránkovou aplikaci (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
Abychom odeslali data formuláře na server bez vynucení obnovení stránky, musíme použít JavaScriptový kód. Místo zadání URL do vlastnosti `action` elementu `<form>` můžete použít jakýkoli JavaScriptový kód předcházený řetězcem `javascript:`, abyste provedli vlastní akci. Použití tohoto přístupu také znamená, že budete muset implementovat některé úkoly, které byly dříve prováděny automaticky prohlížečem:
Abychom mohli odeslat data formuláře na server bez vynucení obnovení stránky, musíme použít JavaScript. Místo zadání URL do vlastnosti `action` elementu `<form>` můžete použít jakýkoli JavaScriptový kód předcházený řetězcem `javascript:`, abyste provedli vlastní akci. Použití tohoto přístupu také znamená, že budete muset implementovat některé úkoly, které dříve automaticky prováděl prohlížeč:
- Získání dat formuláře
- Konverze a kódování dat formuláře do vhodného formátu
- Převod a kódování dat formuláře do vhodného formátu
- Vytvoření HTTP požadavku a jeho odeslání na server
Otevřete `app.js` a přidejte novou funkci s názvem `register`:
Otevřete soubor `app.js` a přidejte novou funkci s názvem `register`:
```js
function register() {
@ -172,7 +172,7 @@ function register() {
}
```
Zde získáváme element formuláře pomocí `getElementById()` a používáme pomocníka [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) k extrakci hodnot z ovládacích prvků formuláře jako sadu dvojic klíč/hodnota. Poté data převedeme na běžný objekt pomocí [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) a nakonec data serializujeme do [JSON](https://www.json.org/json-en.html), formátu běžně používaného pro výměnu dat na webu.
Zde získáváme element formuláře pomocí `getElementById()` a používáme pomocníka [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) k extrakci hodnot z ovládacích prvků formuláře jako sadu klíč/hodnota. Poté převádíme data na běžný objekt pomocí [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) a nakonec serializujeme data do [JSON](https://www.json.org/json-en.html), formátu běžně používaného pro výměnu dat na webu.
Data jsou nyní připravena k odeslání na server. Vytvořte novou funkci s názvem `createAccount`:
@ -191,7 +191,7 @@ async function createAccount(account) {
}
```
Co tato funkce dělá? Nejprve si všimněte klíčového slova `async`. To znamená, že funkce obsahuje kód, který bude prováděn [**asynchronně**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Při použití spolu s klíčovým slovem `await` umožňuje čekat na provedení asynchronního kódu – například čekání na odpověď serveru – před pokračováním.
Co tato funkce dělá? Nejprve si všimněte klíčového slova `async`. To znamená, že funkce obsahuje kód, který se bude provádět [**asynchronně**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Když je použito spolu s klíčovým slovem `await`, umožňuje čekat na provedení asynchronního kódu – například čekání na odpověď serveru – před pokračováním.
Zde je rychlé video o použití `async/await`:
@ -204,21 +204,21 @@ Používáme API `fetch()` k odeslání JSON dat na server. Tato metoda přijím
- URL serveru, takže zde zadáme `//localhost:5000/api/accounts`.
- Nastavení požadavku. Zde nastavíme metodu na `POST` a poskytneme `body` požadavku. Protože odesíláme JSON data na server, musíme také nastavit hlavičku `Content-Type` na `application/json`, aby server věděl, jak interpretovat obsah.
Protože server odpoví na požadavek JSONem, můžeme použít `await response.json()` k analýze JSON obsahu a vrácení výsledného objektu. Všimněte si, že tato metoda je asynchronní, takže zde používáme klíčové slovo `await`, abychom zajistili, že budou zachyceny i chyby během analýzy.
Protože server odpoví na požadavek JSON, můžeme použít `await response.json()` k analýze JSON obsahu a vrácení výsledného objektu. Všimněte si, že tato metoda je asynchronní, takže zde používáme klíčové slovo `await`, abychom se ujistili, že případné chyby během analýzy jsou také zachyceny.
Nyní přidejte nějaký kód do funkce `register`, aby volala`createAccount()`:
Nyní přidejte do funkce `register` kód pro volání`createAccount()`:
```js
const result = await createAccount(jsonData);
```
Protože zde používáme klíčové slovo `await`, musíme přidat klíčové slovo `async` před funkci register:
Protože zde používáme klíčové slovo `await`, musíme před funkci `register` přidat klíčové slovo `async`:
```js
async function register() {
```
Nakonec přidejme nějaké logy pro kontrolu výsledku. Finální funkce by měla vypadat takto:
Nakonec přidejme nějaké logy pro kontrolu výsledku. Konečná funkce by měla vypadat takto:
```js
async function register() {
@ -235,9 +235,9 @@ async function register() {
}
```
Bylo to trochu dlouhé, ale dostali jsme se tam! Pokud otevřete [nástroje pro vývojáře prohlížeče](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) a zkusíte zaregistrovat nový účet, neměli byste vidět žádnou změnu na webové stránce, ale v konzoli se objeví zpráva potvrzující, že vše funguje.
To bylo trochu dlouhé, ale dostali jsme se tam! Pokud otevřete [nástroje pro vývojáře prohlížeče](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) a zkusíte zaregistrovat nový účet, neměli byste vidět žádnou změnu na webové stránce, ale v konzoli se objeví zpráva potvrzující, že vše funguje.


✅ Myslíte si, že data jsou odesílána na server bezpečně? Co kdyby někdo dokázal zachytit požadavek? Můžete si přečíst o [HTTPS](https://en.wikipedia.org/wiki/HTTPS), abyste se dozvěděli více o bezpečné komunikaci dat.
@ -245,17 +245,17 @@ Bylo to trochu dlouhé, ale dostali jsme se tam! Pokud otevřete [nástroje pro
Pokud se pokusíte zaregistrovat nový účet bez zadání uživatelského jména, můžete vidět, že server vrátí chybu se stavovým kódem [400 (Špatný požadavek)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
Před odesláním dat na server je dobré [validovat data formuláře](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) předem, kdykoli je to možné, abyste zajistili, že odesíláte platný požadavek. HTML5 ovládací prvky formuláře poskytují vestavěnou validaci pomocí různých atributů:
Před odesláním dat na server je dobrým zvykem [validovat data formuláře](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) předem, kdykoli je to možné, abyste se ujistili, že odesíláte platný požadavek. HTML5 ovládací prvky formulářů poskytují vestavěnou validaci pomocí různých atributů:
- `required`: pole musí být vyplněno, jinak nelze formulář odeslat.
- `minlength` a `maxlength`: definují minimální a maximální počet znaků v textových polích.
- `min` a `max`: definují minimální a maximální hodnotu číselného pole.
- `type`: definuje typ očekávaných dat, jako`number`, `email`, `file` nebo [jiné vestavěné typy](https://developer.mozilla.org/docs/Web/HTML/Element/input). Tento atribut může také změnit vizuální zobrazení ovládacího prvku formuláře.
- `pattern`: umožňuje definovat [regulární výraz](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) pro testování, zda jsou zadaná data platná nebo ne.
> Tip: vzhled ovládacích prvků formuláře můžete přizpůsobit podle toho, zda jsou platné nebo neplatné, pomocí pseudo-tříd CSS `:valid` a `:invalid`.
- `type`: definuje typ očekávaných dat, například`number`, `email`, `file` nebo [jiné vestavěné typy](https://developer.mozilla.org/docs/Web/HTML/Element/input). Tento atribut může také změnit vizuální zobrazení ovládacího prvku formuláře.
- `pattern`: umožňuje definovat [regulární výraz](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) pro ověření, zda zadaná data jsou platná nebo ne.
> Tip: můžete přizpůsobit vzhled ovládacích prvků formuláře podle toho, zda jsou platné nebo neplatné, pomocí pseudo-tříd CSS `:valid` a `:invalid`.
### Úkol
Existují 2 povinná pole pro vytvoření platného nového účtu: uživatelské jméno a měna, ostatní pole jsou volitelná. Aktualizujte HTML formuláře tak, aby používalo atribut `required` a text v popisku pole:
Pro vytvoření platného nového účtu jsou vyžadována dvě pole: uživatelské jméno a měna, ostatní pole jsou volitelná. Aktualizujte HTML formuláře tak, aby používalo atribut `required` a text v popisku pole:
```html
<labelfor="user">Username (required)</label>
@ -277,37 +277,37 @@ Přidejte atribut `maxlength` do textových polí:
Pokud nyní stisknete tlačítko *Registrovat* a některé pole nesplňuje pravidlo validace, které jsme definovali, měli byste vidět něco takového:
Pokud nyní stisknete tlačítko *Registrovat* a některé pole nesplňuje námi definované validační pravidlo, měli byste vidět něco takového:

Validace, která se provádí *před* odesláním jakýchkoli dat na server, se nazývá **validace na straně klienta**. Ale mějte na paměti, že není vždy možné provést všechny kontroly bez odeslání dat. Například zde nemůžeme ověřit, zda již existuje účet se stejným uživatelským jménem, aniž bychom odeslali požadavek na server. Další validace prováděná na serveru se nazývá **validace na straně serveru**.
Validace, která se provádí *před* odesláním jakýchkoli dat na server, se nazývá **validace na straně klienta**. Mějte však na paměti, že není vždy možné provést všechny kontroly bez odeslání dat. Například zde nemůžeme ověřit, zda již existuje účet se stejným uživatelským jménem, aniž bychom odeslali požadavek na server. Další validace prováděná na serveru se nazývá **validace na straně serveru**.
Obvykle je potřeba implementovat obě. Zatímco validace na straně klienta zlepšuje uživatelský zážitek tím, že poskytuje okamžitou zpětnou vazbu uživateli, validace na straně serveru je klíčová pro zajištění, že data uživatele, se kterými pracujete, jsou správná a bezpečná.
Obvykle je potřeba implementovat obě. Zatímco validace na straně klienta zlepšuje uživatelský zážitek tím, že poskytuje okamžitou zpětnou vazbu, validace na straně serveru je klíčová pro zajištění, že data uživatele, se kterými pracujete, jsou správná a bezpečná.
---
## 🚀 Výzva
Zobrazte chybovou zprávu v HTML, pokud uživatel již existuje.
Zobrazte v HTML chybovou zprávu, pokud uživatel již existuje.
Zde je příklad, jak může vypadat finální přihlašovací stránka po troše stylování:
Zde je příklad, jak může vypadat konečná přihlašovací stránka po menší úpravě stylů:


## Kvíz po přednášce
[Kvíz po přednášce](https://ff-quizzes.netlify.app/web/quiz/44)
## Přehled & Samostudium
## Recenze a samostudium
Vývojáři byli velmi kreativní při vytváření formulářů, zejména pokud jde o strategie validace. Zjistěte více o různých způsobech práce s formuláři prohlížením [CodePen](https://codepen.com); najdete nějaké zajímavé a inspirativní formuláře?
Vývojáři byli velmi kreativní při vytváření formulářů, zejména pokud jde o validační strategie. Prozkoumejte různé přístupy k formulářům na [CodePen](https://codepen.com); najdete nějaké zajímavé a inspirativní formuláře?
## Zadání
[Stylujte svou bankovní aplikaci](assignment.md)
[Styling vaší bankovní aplikace](assignment.md)
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby AI pro překlady [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Nenese odpovědnost za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Za autoritativní zdroj by měl být považován původní dokument v jeho původním jazyce. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Základem každé webové aplikace jsou *data*. Data mohou mít různé podoby, ale jejich hlavním účelem je vždy zobrazit informace uživateli. S tím, jak se webové aplikace stávají stále interaktivnějšími a složitějšími, je způsob, jakým uživatel přistupuje k informacím a jak s nimi pracuje, klíčovou součástí vývoje webu.
Jádrem každé webové aplikace jsou *data*. Data mohou mít různé podoby, ale jejich hlavním účelem je vždy zobrazit uživateli informace. S tím, jak se webové aplikace stávají stále interaktivnějšími a složitějšími, je způsob, jakým uživatel přistupuje k informacím a jak s nimi pracuje, klíčovou součástí vývoje webu.
V této lekci se naučíme, jak asynchronně získávat data ze serveru a používat je k zobrazení informací na webové stránce bez nutnosti znovu načítat HTML.
### Předpoklady
Pro tuto lekci musíte mít vytvořenou část webové aplikace [Přihlašovací a registrační formulář](../2-forms/README.md). Také je potřeba nainstalovat [Node.js](https://nodejs.org) a [spustit serverovou API](../api/README.md) lokálně, abyste získali data o účtu.
Pro tuto lekci musíte mít vytvořenou část webové aplikace [Přihlašovací a registrační formulář](../2-forms/README.md). Také je potřeba nainstalovat [Node.js](https://nodejs.org) a [spustit serverovou API](../api/README.md) lokálně, abyste získali data o účtech.
Můžete ověřit, zda server běží správně, spuštěním tohoto příkazu v terminálu:
@ -34,17 +34,17 @@ curl http://localhost:5000/api
## AJAX a získávání dat
Tradiční webové stránky aktualizují zobrazovaný obsah, když uživatel vybere odkaz nebo odešle data pomocí formuláře, a to znovunačtením celé HTML stránky. Pokaždé, když je potřeba načíst nová data, webový server vrátí zcela novou HTML stránku, kterou musí prohlížeč zpracovat, což přeruší aktuální akci uživatele a omezí interakce během načítání. Tento postup se také nazývá *vícestránková aplikace* (Multi-Page Application, MPA).
Tradiční webové stránky aktualizují zobrazovaný obsah, když uživatel vybere odkaz nebo odešle data pomocí formuláře, tím, že znovu načtou celou HTML stránku. Pokaždé, když je potřeba načíst nová data, webový server vrátí zcela novou HTML stránku, kterou musí prohlížeč zpracovat, což přeruší aktuální akci uživatele a omezuje interakce během načítání. Tento postup se také nazývá *vícestránková aplikace* nebo *MPA*.

S rostoucí složitostí a interaktivitou webových aplikací se objevila nová technika nazvaná [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Tato technika umožňuje webovým aplikacím asynchronně odesílat a získávat data ze serveru pomocí JavaScriptu, aniž by bylo nutné znovu načítat HTML stránku. Výsledkem jsou rychlejší aktualizace a plynulejší interakce uživatele. Když jsou ze serveru přijata nová data, aktuální HTML stránka může být také aktualizována pomocí JavaScriptu a API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Postupem času se tento přístup vyvinul do toho, co dnes nazýváme [*jednostránková aplikace* (Single-Page Application, SPA)](https://en.wikipedia.org/wiki/Single-page_application).
S rostoucí složitostí a interaktivitou webových aplikací se objevila nová technika nazvaná [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Tato technika umožňuje webovým aplikacím asynchronně odesílat a získávat data ze serveru pomocí JavaScriptu, aniž by bylo nutné znovu načítat HTML stránku, což vede k rychlejším aktualizacím a plynulejším interakcím uživatele. Když server vrátí nová data, aktuální HTML stránka může být aktualizována pomocí JavaScriptu a API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Tento přístup se postupem času vyvinul v to, co dnes nazýváme [*jednostránková aplikace* nebo *SPA*](https://en.wikipedia.org/wiki/Single-page_application).

Když byl AJAX poprvé představen, jediným dostupným API pro asynchronní získávání dat bylo [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Moderní prohlížeče však nyní implementují pohodlnější a výkonnější [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), které využívá promises a je lépe přizpůsobené pro manipulaci s JSON daty.
> I když všechny moderní prohlížeče podporují `Fetch API`, pokud chcete, aby vaše webová aplikace fungovala na starších prohlížečích, je vždy dobré zkontrolovat [tabulku kompatibility na caniuse.com](https://caniuse.com/fetch).
> Ačkoli všechny moderní prohlížeče podporují `Fetch API`, pokud chcete, aby vaše webová aplikace fungovala i na starších prohlížečích, je vždy dobré zkontrolovat [tabulku kompatibility na caniuse.com](https://caniuse.com/fetch).
### Úkol
@ -57,9 +57,9 @@ async function login() {
}
```
Začneme tím, že získáme prvek formuláře pomocí `getElementById()` a poté získáme uživatelské jméno z inputu pomocí `loginForm.user.value`. Každý ovládací prvek formuláře lze přistupovat podle jeho názvu (nastaveného v HTML pomocí atributu `name`) jako vlastnosti formuláře.
Začínáme získáním prvku formuláře pomocí `getElementById()` a poté získáme uživatelské jméno z inputu pomocí `loginForm.user.value`. Každý ovládací prvek formuláře lze přistupovat podle jeho názvu (nastaveného v HTML pomocí atributu `name`) jako vlastnosti formuláře.
Podobně jako jsme to udělali pro registraci, vytvoříme další funkci pro provedení požadavku na server, tentokrát pro získání dat o účtu:
Podobně jako u registrace vytvoříme další funkci pro provedení požadavku na server, tentokrát pro získání dat o účtu:
```js
async function getAccount(user) {
@ -72,9 +72,9 @@ async function getAccount(user) {
}
```
Používáme `fetch` API k asynchronnímu požadavku na data ze serveru, ale tentokrát nepotřebujeme žádné další parametry kromě URL, protože pouze dotazujeme data. Ve výchozím nastavení `fetch` vytváří HTTP požadavek typu [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), což je přesně to, co zde potřebujeme.
Používáme `fetch` API pro asynchronní požadavek na server, ale tentokrát nepotřebujeme žádné další parametry kromě URL, protože pouze dotazujeme data. Ve výchozím nastavení `fetch` vytváří HTTP požadavek typu [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), což je přesně to, co zde potřebujeme.
✅ `encodeURIComponent()` je funkce, která escapuje speciální znaky pro URL. Jaké problémy bychom mohli mít, pokud bychom tuto funkci nevolali a použili přímo hodnotu `user` v URL?
✅ `encodeURIComponent()` je funkce, která escapuje speciální znaky pro URL. Jaké problémy by mohly nastat, pokud bychom tuto funkci nevolali a použili přímo hodnotu `user` v URL?
Nyní aktualizujeme naši funkci `login`, aby používala `getAccount`:
@ -93,7 +93,7 @@ async function login() {
}
```
Protože je `getAccount` asynchronní funkce, musíme ji spárovat s klíčovým slovem `await`, abychom počkali na výsledek serveru. Stejně jako u každého požadavku na server musíme také řešit chybové případy. Prozatím přidáme pouze zprávu do logu, která zobrazí chybu, a vrátíme se k tomu později.
Protože je `getAccount` asynchronní funkce, musíme ji spárovat s klíčovým slovem `await`, abychom počkali na výsledek serveru. Jako u každého požadavku na server musíme také řešit chybové případy. Prozatím přidáme pouze zprávu do logu, která zobrazí chybu, a vrátíme se k tomu později.
Poté musíme data uložit někam, abychom je mohli později použít k zobrazení informací na dashboardu. Protože proměnná `account` zatím neexistuje, vytvoříme globální proměnnou na začátku našeho souboru:
@ -103,7 +103,7 @@ let account = null;
Po uložení uživatelských dat do proměnné můžeme přejít ze stránky *login* na *dashboard* pomocí funkce `navigate()`, kterou již máme.
Nakonec musíme zavolat naši funkci `login`, když je odeslán přihlašovací formulář, a to úpravou HTML:
Nakonec musíme zavolat naši funkci `login`, když je odeslán přihlašovací formulář, úpravou HTML:
```html
<formid="loginForm"action="javascript:login()">
@ -118,13 +118,13 @@ account = result;
navigate('/dashboard');
```
✅ Věděli jste, že ve výchozím nastavení můžete volat serverové API pouze z *téže domény a portu*, na kterém si prohlížíte webovou stránku? Toto je bezpečnostní mechanismus vynucovaný prohlížeči. Ale počkat, naše webová aplikace běží na `localhost:3000`, zatímco serverová API běží na `localhost:5000`, proč to funguje? Pomocí techniky nazvané [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) je možné provádět cross-origin HTTP požadavky, pokud server přidá do odpovědi speciální hlavičky, které umožňují výjimky pro specifické domény.
✅ Věděli jste, že ve výchozím nastavení můžete volat serverové API pouze z *téže domény a portu*, na kterém si prohlížíte webovou stránku? Toto je bezpečnostní mechanismus vynucený prohlížeči. Ale počkat, naše webová aplikace běží na `localhost:3000`, zatímco serverová API běží na `localhost:5000`, proč to funguje? Pomocí techniky nazvané [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) je možné provádět cross-origin HTTP požadavky, pokud server přidá do odpovědi speciální hlavičky, které povolují výjimky pro specifické domény.
> Více o API se dozvíte v této [lekci](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)
## Aktualizace HTML pro zobrazení dat
Nyní, když máme uživatelská data, musíme aktualizovat existující HTML, aby je zobrazovalo. Již víme, jak získat prvek z DOM pomocí například `document.getElementById()`. Po získání základního prvku zde jsou některá API, která můžete použít k jeho úpravě nebo přidání podřízených prvků:
Nyní, když máme uživatelská data, musíme aktualizovat existující HTML, aby je zobrazovalo. Již víme, jak získat prvek z DOM pomocí například `document.getElementById()`. Po získání základního prvku můžete použít následující API pro jeho úpravu nebo přidání podřízených prvků:
- Pomocí vlastnosti [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) můžete změnit text prvku. Všimněte si, že změna této hodnoty odstraní všechny podřízené prvky (pokud nějaké existují) a nahradí je poskytnutým textem. Proto je to také efektivní metoda pro odstranění všech podřízených prvků daného prvku přiřazením prázdného řetězce `''`.
@ -136,7 +136,7 @@ Nyní, když máme uživatelská data, musíme aktualizovat existující HTML, a
Než přejdeme na obrazovku dashboardu, je tu ještě jedna věc, kterou bychom měli udělat na stránce *login*. Aktuálně, pokud se pokusíte přihlásit s uživatelským jménem, které neexistuje, zobrazí se zpráva v konzoli, ale pro běžného uživatele se nic nezmění a neví, co se děje.
Přidáme zástupný prvek do přihlašovacího formuláře, kde můžeme v případě potřeby zobrazit chybovou zprávu. Dobré místo by bylo těsně před přihlašovacím `<button>`:
Přidáme prvek placeholderu do přihlašovacího formuláře, kde můžeme v případě potřeby zobrazit chybovou zprávu. Dobré místo by bylo těsně před přihlašovacím `<button>`:
```html
...
@ -145,7 +145,7 @@ Přidáme zástupný prvek do přihlašovacího formuláře, kde můžeme v př
...
```
Tento `<div>` prvek je prázdný, což znamená, že na obrazovce se nic nezobrazí, dokud do něj nepřidáme nějaký obsah. Také mu dáme `id`, abychom ho mohli snadno získat pomocí JavaScriptu.
Tento `<div>` prvek je prázdný, což znamená, že na obrazovce se nic nezobrazí, dokud do něj nepřidáme nějaký obsah. Také mu dáme `id`, abychom jej mohli snadno získat pomocí JavaScriptu.
Vraťte se do souboru `app.js` a vytvořte novou pomocnou funkci `updateElement`:
@ -168,17 +168,17 @@ Nyní, pokud se pokusíte přihlásit s neplatným účtem, měli byste vidět n

Nyní máme chybový text, který se zobrazuje vizuálně, ale pokud to zkusíte s čtečkou obrazovky, všimnete si, že se nic neoznamuje. Aby byl text, který je dynamicky přidán na stránku, oznámen čtečkami obrazovky, bude potřeba použít něco, co se nazývá [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Zde použijeme specifický typ live regionu nazývaný alert:
Nyní máme chybový text, který se zobrazuje vizuálně, ale pokud to zkusíte s čtečkou obrazovky, všimnete si, že nic není oznámeno. Aby byl text, který je dynamicky přidán na stránku, oznámen čtečkami obrazovky, bude potřeba použít něco, co se nazývá [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Zde použijeme specifický typ live regionu nazývaný alert:
```html
<divid="loginError"role="alert"></div>
```
Implementujte stejnou funkci pro chyby ve funkci `register` (nezapomeňte aktualizovat HTML).
Implementujte stejnou funkčnost pro chyby ve funkci `register` (nezapomeňte aktualizovat HTML).
## Zobrazení informací na dashboardu
Pomocí stejných technik, které jsme právě viděli, se postaráme také o zobrazení informací o účtu na stránce dashboardu.
Pomocí stejných technik, které jsme právě viděli, se také postaráme o zobrazení informací o účtu na stránce dashboardu.
Takto vypadá objekt účtu přijatý ze serveru:
@ -196,11 +196,11 @@ Takto vypadá objekt účtu přijatý ze serveru:
}
```
> Poznámka: Pro usnadnění můžete použít předem existující účet `test`, který je již naplněn daty.
> Poznámka: pro usnadnění můžete použít předem existující účet `test`, který je již naplněn daty.
### Úkol
Začněme tím, že nahradíme sekci "Balance" v HTML přidáním zástupných prvků:
Začněme nahrazením sekce "Balance" v HTML přidáním placeholder prvků:
```html
<section>
@ -214,9 +214,9 @@ Také přidáme novou sekci těsně pod ní pro zobrazení popisu účtu:
<h2id="description"></h2>
```
✅ Protože popis účtu funguje jako nadpis pro obsah pod ním, je označen sémanticky jako nadpis. Zjistěte více o tom, jak je [struktura nadpisů](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) důležitá pro přístupnost, a kriticky se podívejte na stránku, abyste zjistili, co dalšího by mohlo být nadpisem.
✅ Protože popis účtu funguje jako nadpis pro obsah pod ním, je označen sémanticky jako nadpis. Zjistěte více o tom, jak je [struktura nadpisů](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) důležitá pro přístupnost, a kriticky se podívejte na stránku, abyste určili, co dalšího by mohlo být nadpisem.
Dále vytvoříme novou funkci v `app.js`, která vyplní zástupné prvky:
Dále vytvoříme novou funkci v `app.js` pro vyplnění placeholderu:
```js
function updateDashboard() {
@ -257,7 +257,7 @@ S touto změnou se při každém zobrazení stránky dashboardu zavolá funkce `
## Dynamické vytváření řádků tabulky pomocí HTML šablon
V [první lekci](../1-template-route/README.md) jsme použili HTML šablony spolu s metodou [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) k implementaci navigace v naší aplikaci. Šablony mohou být také menší a použity k dynamickému vyplnění opakujících se částí stránky.
V [první lekci](../1-template-route/README.md) jsme použili HTML šablony spolu s metodou [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) k implementaci navigace v naší aplikaci. Šablony mohou být také menší a použity k dynamickému naplnění opakujících se částí stránky.
Použijeme podobný přístup k zobrazení seznamu transakcí v HTML tabulce.
@ -275,9 +275,9 @@ Přidejte novou šablonu do `<body>` HTML:
</template>
```
Tato šablona představuje jeden řádek tabulky se třemi sloupci, které chceme vyplnit: *datum*, *objekt* a *částka* transakce.
Tato šablona představuje jeden řádek tabulky se třemi sloupci, které chceme naplnit: *datum*, *objekt* a *částka* transakce.
Poté přidejte tuto vlastnost `id` k `<tbody>` elementu tabulky v šabloně dashboardu, aby bylo snazší ji najít pomocí JavaScriptu:
Poté přidejte tuto vlastnost `id` k `<tbody>` elementu tabulky v šabloně dashboardu, aby bylo snazší jej najít pomocí JavaScriptu:
```html
<tbodyid="transactions"></tbody>
@ -297,7 +297,7 @@ function createTransactionRow(transaction) {
}
```
Tato funkce dělá přesně to, co její název napovídá: pomocí šablony, kterou jsme vytvořili dříve, vytvoří nový řádek tabulky a vyplní jeho obsah pomocí dat transakce. Použijeme ji ve funkci `updateDashboard()` k naplnění tabulky:
Tato funkce dělá přesně to, co její název napovídá: pomocí šablony, kterou jsme vytvořili dříve, vytvoří nový řádek tabulky a naplní jeho obsah pomocí dat transakce. Použijeme ji v naší funkci `updateDashboard()` k naplnění tabulky:
@ -321,17 +321,17 @@ function updateElement(id, textOrNode) {
```
Používáme metodu [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), protože umožňuje připojit buď text, nebo [DOM uzly](https://developer.mozilla.org/docs/Web/API/Node) k nadřazenému prvku, což je ideální pro všechny naše případy použití.
Pokud se pokusíte přihlásit pomocí účtu `test`, měli byste nyní na hlavním panelu vidět seznam transakcí 🎉.
Pokud se pokusíte přihlásit pomocí účtu `test`, měli byste nyní na hlavní stránce vidět seznam transakcí 🎉.
---
## 🚀 Výzva
Spolupracujte na tom, aby stránka hlavního panelu vypadala jako skutečná bankovní aplikace. Pokud jste již svou aplikaci upravili, zkuste použít [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) k vytvoření [responzivního designu](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), který bude dobře fungovat jak na stolních počítačích, tak na mobilních zařízeních.
Spolupracujte na tom, aby stránka dashboardu vypadala jako skutečná bankovní aplikace. Pokud jste již svou aplikaci upravili, zkuste použít [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) k vytvoření [responzivního designu](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks), který bude dobře fungovat jak na stolních počítačích, tak na mobilních zařízeních.
Zde je příklad upravené stránky hlavního panelu:
Zde je příklad upravené stránky dashboardu:


## Kvíz po přednášce
@ -344,4 +344,4 @@ Zde je příklad upravené stránky hlavního panelu:
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
# Vytvoření bankovní aplikace, část 4: Koncepty správy stavu
## Kvíz před lekcí
## Kvíz před přednáškou
[Kvíz před lekcí](https://ff-quizzes.netlify.app/web/quiz/47)
[Kvíz před přednáškou](https://ff-quizzes.netlify.app/web/quiz/47)
### Úvod
Jak webová aplikace roste, stává se stále obtížnější sledovat všechny datové toky. Který kód získává data, která stránka je využívá, kde a kdy je třeba je aktualizovat... snadno se dostanete k nepořádnému kódu, který je těžké udržovat. To platí zejména tehdy, když potřebujete sdílet data mezi různými stránkami aplikace, například uživatelská data. Koncept *správy stavu* existoval vždy ve všech typech programů, ale jak webové aplikace rostou na složitosti, stává se klíčovým bodem, o kterém je třeba během vývoje přemýšlet.
Jak webová aplikace roste, stává se stále obtížnější sledovat všechny datové toky. Který kód získává data, která stránka je spotřebovává, kde a kdy je třeba je aktualizovat... snadno se dostanete k chaotickému kódu, který je obtížné udržovat. To platí zejména tehdy, když potřebujete sdílet data mezi různými stránkami vaší aplikace, například uživatelská data. Koncept *správy stavu*vždy existoval ve všech typech programů, ale jak webové aplikace stále rostou na složitosti, stává se klíčovým bodem, o kterém je třeba během vývoje přemýšlet.
V této závěrečné části se podíváme na aplikaci, kterou jsme vytvořili, a přehodnotíme, jak je spravován stav, abychom umožnili podporu obnovení prohlížeče kdykoli a zachování dat mezi uživatelskými relacemi.
V této poslední části se podíváme na aplikaci, kterou jsme vytvořili, abychom přehodnotili, jak je spravován stav, což umožní podporu obnovení prohlížeče kdykoli a zachování dat mezi uživatelskými relacemi.
### Předpoklady
Musíte mít dokončenou část [získávání dat](../3-data/README.md) webové aplikace pro tuto lekci. Také je třeba nainstalovat [Node.js](https://nodejs.org) a [spustit serverové API](../api/README.md) lokálně, abyste mohli spravovat data účtu.
Pro tuto lekci musíte mít dokončenou část [získávání dat](../3-data/README.md) webové aplikace. Také musíte nainstalovat [Node.js](https://nodejs.org) a [spustit server API](../api/README.md) lokálně, abyste mohli spravovat data účtu.
Můžete otestovat, zda server běží správně, spuštěním tohoto příkazu v terminálu:
@ -34,34 +34,34 @@ curl http://localhost:5000/api
## Přehodnocení správy stavu
V [předchozí lekci](../3-data/README.md) jsme představili základní koncept stavu v naší aplikaci pomocí globální proměnné `account`, která obsahuje bankovní data aktuálně přihlášeného uživatele. Naše současná implementace má však několik nedostatků. Zkuste obnovit stránku, když jste na přehledu. Co se stane?
V [předchozí lekci](../3-data/README.md) jsme představili základní koncept stavu v naší aplikaci s globální proměnnou `account`, která obsahuje bankovní data aktuálně přihlášeného uživatele. Nicméně naše současná implementace má určité nedostatky. Zkuste obnovit stránku, když jste na dashboardu. Co se stane?
V aktuálním kódu jsou tři problémy:
Existují 3 problémy se současným kódem:
- Stav není zachován, protože obnovení prohlížeče vás vrátí na přihlašovací stránku.
- Existuje více funkcí, které stav upravují. Jak aplikace roste, může být obtížné sledovat změny a snadno zapomenete na aktualizaci jedné z nich.
- Existuje několik funkcí, které upravují stav. Jak aplikace roste, může být obtížné sledovat změny a snadno zapomenete aktualizovat jednu z nich.
- Stav není vyčištěn, takže když kliknete na *Odhlásit se*, data účtu tam stále jsou, i když jste na přihlašovací stránce.
Mohli bychom aktualizovat náš kód, abychom tyto problémy řešili jeden po druhém, ale to by vedlo k většímu duplicitnímu kódu a aplikace by byla složitější a obtížněji udržovatelná. Nebo bychom si mohli na pár minut udělat pauzu a přehodnotit naši strategii.
Mohli bychom aktualizovat náš kód, abychom tyto problémy řešili jeden po druhém, ale vytvořilo by to více duplicitního kódu a učinilo aplikaci složitější a obtížněji udržovatelnou. Nebo bychom se mohli na pár minut zastavit a přehodnotit naši strategii.
> Jaké problémy se zde vlastně snažíme vyřešit?
[Správa stavu](https://en.wikipedia.org/wiki/State_management) je o nalezení dobrého přístupu k řešení těchto dvou konkrétních problémů:
- Jak udržet datové toky v aplikaci srozumitelné?
- Jak udržet data stavu vždy synchronizovaná s uživatelským rozhraním (a naopak)?
- Jak udržet stavová data vždy synchronizovaná s uživatelským rozhraním (a naopak)?
Jakmile se o tyto problémy postaráte, jakékoli další problémy, které byste mohli mít, mohou být buď již vyřešeny, nebo se staly snazšími k řešení. Existuje mnoho možných přístupů k řešení těchto problémů, ale my se zaměříme na běžné řešení, které spočívá v **centralizaci dat a způsobů jejich změny**. Datové toky by vypadaly takto:
Jakmile se o tyto problémy postaráte, jakékoli další problémy, které byste mohli mít, mohou být buď již vyřešeny, nebo se staly snadněji řešitelnými. Existuje mnoho možných přístupů k řešení těchto problémů, ale zvolíme běžné řešení, které spočívá v **centralizaci dat a způsobů jejich změny**. Datové toky by vypadaly takto:

> Zde se nebudeme zabývat částí, kde data automaticky spouštějí aktualizaci zobrazení, protože je to spojeno s pokročilejšími koncepty [reaktivního programování](https://en.wikipedia.org/wiki/Reactive_programming). Je to dobré téma k dalšímu studiu, pokud se chcete ponořit hlouběji.
> Zde nebudeme pokrývat část, kde data automaticky spouštějí aktualizaci zobrazení, protože je spojena s pokročilejšími koncepty [reaktivního programování](https://en.wikipedia.org/wiki/Reactive_programming). Je to dobré téma pro hlubší studium, pokud máte zájem.
✅ Existuje mnoho knihoven s různými přístupy ke správě stavu, přičemž [Redux](https://redux.js.org) je populární volbou. Podívejte se na koncepty a vzory, které používají, protože často poskytují dobrý přehled o potenciálních problémech, kterým můžete čelit ve velkých webových aplikacích, a o tom, jak je lze řešit.
✅ Existuje mnoho knihoven s různými přístupy ke správě stavu, [Redux](https://redux.js.org) je populární volbou. Podívejte se na koncepty a vzory, které používá, protože často poskytují dobrý přehled o potenciálních problémech, kterým můžete čelit ve velkých webových aplikacích, a o tom, jak je lze vyřešit.
### Úkol
Začneme malou refaktorizací. Nahraďte deklaraci `account`:
Myšlenkou je *centralizovat* všechna data naší aplikace do jediného objektu stavu. Zatím máme ve stavu pouze `account`, takže se toho moc nezmění, ale vytváříme tím cestu pro budoucí rozšíření.
Myšlenkou je *centralizovat* všechna data naší aplikace do jediného objektu stavu. Zatím máme ve stavu pouze `account`, takže se toho moc nezmění, ale vytváříme cestu pro budoucí rozšíření.
Musíme také aktualizovat funkce, které jej používají. Ve funkcích `register()` a `login()` nahraďte `account = ...` za `state.account = ...`;
@ -85,15 +85,15 @@ Na začátek funkce `updateDashboard()` přidejte tento řádek:
const account = state.account;
```
Tato refaktorizace sama o sobě nepřinesla mnoho vylepšení, ale myšlenkou bylo položit základy pro další změny.
Tento refaktoring sám o sobě nepřinesl mnoho zlepšení, ale myšlenkou bylo položit základy pro další změny.
## Sledování změn dat
Nyní, když jsme zavedli objekt `state` pro ukládání našich dat, dalším krokem je centralizace aktualizací. Cílem je usnadnit sledování jakýchkoli změn a kdy k nim dochází.
Nyní, když jsme vytvořili objekt `state` pro ukládání našich dat, dalším krokem je centralizace aktualizací. Cílem je usnadnit sledování jakýchkoli změn a kdy k nim dochází.
Abychom zabránili provádění změn v objektu `state`, je také dobré považovat jej za [*neměnný*](https://en.wikipedia.org/wiki/Immutable_object), což znamená, že jej nelze vůbec upravovat. To také znamená, že musíte vytvořit nový objekt stavu, pokud chcete v něm něco změnit. Tímto způsobem si vytvoříte ochranu proti potenciálně nežádoucím [vedlejším efektům](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) a otevřete možnosti pro nové funkce ve vaší aplikaci, jako je implementace funkce zpět/znovu, a zároveň usnadníte ladění. Například byste mohli zaznamenávat každou změnu provedenou ve stavu a uchovávat historii změn, abyste pochopili zdroj chyby.
Aby se zabránilo změnám objektu `state`, je také dobré považovat jej za [*neměnný*](https://en.wikipedia.org/wiki/Immutable_object), což znamená, že jej nelze vůbec upravovat. To také znamená, že musíte vytvořit nový objekt stavu, pokud chcete něco změnit. Tímto způsobem vytváříte ochranu proti potenciálně nežádoucím [vedlejším účinkům](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) a otevíráte možnosti pro nové funkce ve vaší aplikaci, jako je implementace undo/redo, a zároveň usnadňujete ladění. Například byste mohli zaznamenávat každou změnu provedenou ve stavu a uchovávat historii změn, abyste pochopili zdroj chyby.
V JavaScriptu můžete použít [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) k vytvoření neměnné verze objektu. Pokud se pokusíte provést změny v neměnném objektu, bude vyvolána výjimka.
V JavaScriptu můžete použít [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) k vytvoření neměnné verze objektu. Pokud se pokusíte provést změny neměnného objektu, bude vyvolána výjimka.
✅ Znáte rozdíl mezi *mělkým* a *hlubokým* neměnným objektem? Můžete si o tom přečíst [zde](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze).
@ -110,7 +110,7 @@ function updateState(property, newData) {
}
```
V této funkci vytváříme nový objekt stavu a kopírujeme data z předchozího stavu pomocí [*operátoru rozbalení (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Poté přepíšeme konkrétní vlastnost objektu stavu novými daty pomocí [notace hranatých závorek](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` pro přiřazení. Nakonec objekt uzamkneme, aby nebylo možné provádět úpravy, pomocí `Object.freeze()`. Zatím máme ve stavu pouze vlastnost `account`, ale s tímto přístupem můžete do stavu přidat tolik vlastností, kolik potřebujete.
V této funkci vytváříme nový objekt stavu a kopírujeme data z předchozího stavu pomocí [*operátoru rozbalení (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Poté přepisujeme konkrétní vlastnost objektu stavu novými daty pomocí [notace hranatých závorek](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` pro přiřazení. Nakonec objekt uzamkneme, aby se zabránilo úpravám pomocí `Object.freeze()`. Zatím máme ve stavu pouze vlastnost `account`, ale s tímto přístupem můžete do stavu přidat tolik vlastností, kolik potřebujete.
Také aktualizujeme inicializaci `state`, abychom zajistili, že počáteční stav bude také zmrazen:
@ -126,13 +126,13 @@ Poté aktualizujte funkci `register` nahrazením přiřazení `state.account = r
updateState('account', result);
```
Uděláme totéž s funkcí `login`, kde nahradíme`state.account = data;` za:
Uděláme totéž s funkcí `login`, nahrazením`state.account = data;` za:
```js
updateState('account', data);
```
Nyní využijeme příležitosti k opravě problému, kdy data účtu nejsou vymazána, když uživatel klikne na *Odhlásit se*.
Nyní využijeme příležitosti k vyřešení problému, kdy data účtu nejsou vymazána, když uživatel klikne na *Odhlásit se*.
Vytvořte novou funkci `logout()`:
@ -143,7 +143,7 @@ function logout() {
}
```
V `updateDashboard()` nahraďte přesměrování `return navigate('/login');` za `return logout();`;
V `updateDashboard()` nahraďte přesměrování `return navigate('/login');` za `return logout()`;
Zkuste zaregistrovat nový účet, odhlásit se a znovu se přihlásit, abyste ověřili, že vše stále funguje správně.
@ -151,27 +151,27 @@ Zkuste zaregistrovat nový účet, odhlásit se a znovu se přihlásit, abyste o
## Zachování stavu
Většina webových aplikací potřebuje uchovávat data, aby mohla správně fungovat. Všechna kritická data jsou obvykle uložena v databázi a přistupuje se k nim prostřednictvím serverového API, jako jsou například uživatelská data účtu v našem případě. Někdy je však také zajímavé uchovávat některá data na klientské aplikaci běžící ve vašem prohlížeči, pro lepší uživatelský zážitek nebo pro zlepšení výkonu načítání.
Většina webových aplikací potřebuje uchovávat data, aby mohla správně fungovat. Všechna kritická data jsou obvykle uložena v databázi a přistupuje se k nim prostřednictvím serverového API, například k datům uživatelského účtu v našem případě. Ale někdy je také zajímavé uchovávat některá data na klientské aplikaci, která běží ve vašem prohlížeči, pro lepší uživatelský zážitek nebo pro zlepšení výkonu načítání.
Když chcete uchovávat data ve vašem prohlížeči, měli byste si položit několik důležitých otázek:
Když chcete uchovávat data ve svém prohlížeči, existuje několik důležitých otázek, které byste si měli položit:
- *Jsou data citlivá?* Měli byste se vyhnout ukládání jakýchkoli citlivých dat na klienta, jako jsou uživatelská hesla.
- *Jak dlouho potřebujete tato data uchovávat?* Plánujete přistupovat k těmto datům pouze během aktuální relace, nebo je chcete uchovávat navždy?
- *Jsou data citlivá?* Měli byste se vyhnout ukládání jakýchkoli citlivých dat na klienta, jako jsou hesla uživatelů.
- *Jak dlouho potřebujete tato data uchovávat?* Plánujete přístup k těmto datům pouze pro aktuální relaci, nebo je chcete uchovávat navždy?
Existuje několik způsobů, jak ukládat informace uvnitř webové aplikace, v závislosti na tom, čeho chcete dosáhnout. Například můžete použít URL k uložení vyhledávacího dotazu a umožnit jeho sdílení mezi uživateli. Můžete také použít [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies), pokud je potřeba data sdílet se serverem, například informace o [autentizaci](https://en.wikipedia.org/wiki/Authentication).
Existuje několik způsobů, jak ukládat informace uvnitř webové aplikace, v závislosti na tom, čeho chcete dosáhnout. Například můžete použít URL k uložení vyhledávacího dotazu a učinit jej sdílitelným mezi uživateli. Můžete také použít [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies), pokud je třeba data sdílet se serverem, například informace o [autentizaci](https://en.wikipedia.org/wiki/Authentication).
Další možností je použití jedné z mnoha API pro ukládání dat v prohlížeči. Dvě z nich jsou obzvláště zajímavé:
Další možností je použití jedné z mnoha API prohlížeče pro ukládání dat. Dvě z nich jsou obzvláště zajímavé:
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database), který umožňuje uchovávat data specifická pro aktuální webovou stránku mezi různými relacemi. Data uložená v něm nikdy nevyprší.
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): funguje stejně jako `localStorage`, kromě toho, že data uložená v něm jsou vymazána, když relace skončí (když je prohlížeč zavřen).
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): funguje stejně jako `localStorage`, kromě toho, že data uložená v něm jsou vymazána, když relace skončí (když se prohlížeč zavře).
Všimněte si, že obě tato API umožňují ukládat pouze [řetězce](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Pokud chcete ukládat složité objekty, budete je muset serializovat do formátu [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) pomocí [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
Všimněte si, že obě tyto API umožňují ukládat pouze [řetězce](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Pokud chcete ukládat složité objekty, budete je muset serializovat do formátu [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) pomocí [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
✅ Pokud chcete vytvořit webovou aplikaci, která nepracuje se serverem, je také možné vytvořit databázi na klientovi pomocí [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Toto je vyhrazeno pro pokročilé případy použití nebo pokud potřebujete ukládat významné množství dat, protože je složitější na použití.
### Úkol
Chceme, aby naši uživatelé zůstali přihlášeni, dokud explicitně nekliknou na tlačítko *Odhlásit se*, takže použijeme `localStorage` k ukládání dat účtu. Nejprve definujme klíč, který použijeme k ukládání našich dat.
Chceme, aby naši uživatelé zůstali přihlášeni, dokud explicitně nekliknou na tlačítko *Odhlásit se*, takže použijeme `localStorage` k ukládání dat účtu. Nejprve definujeme klíč, který použijeme k ukládání našich dat.
```js
const storageKey = 'savedAccount';
@ -183,9 +183,9 @@ Poté přidejte tento řádek na konec funkce `updateState()`:
Tímto způsobem budou data uživatelského účtu zachována a vždy aktuální, protože jsme dříve centralizovali všechny aktualizace stavu. Zde začínáme těžit ze všech našich předchozích refaktorů 🙂.
Tímto způsobem budou data uživatelského účtu uchována a vždy aktuální, protože jsme dříve centralizovali všechny naše aktualizace stavu. Zde začínáme těžit ze všech našich předchozích refaktorů 🙂.
Protože jsou data uložena, musíme se také postarat o jejich obnovení při načtení aplikace. Vzhledem k tomu, že začneme mít více inicializačního kódu, může být dobrý nápad vytvořit novou funkci `init`, která také zahrnuje náš předchozí kód na konci `app.js`:
Protože jsou data uložena, musíme se také postarat o jejich obnovení, když je aplikace načtena. Vzhledem k tomu, že začneme mít více inicializačního kódu, může být dobrý nápad vytvořit novou funkci `init`, která také zahrnuje náš předchozí kód na konci `app.js`:
```js
function init() {
@ -202,17 +202,17 @@ function init() {
init();
```
Zde načítáme uložená data a pokud nějaká existují, aktualizujeme stav odpovídajícím způsobem. Je důležité to udělat *před* aktualizací trasy, protože během aktualizace stránky může být kód závislý na stavu.
Zde získáváme uložená data a pokud nějaká existují, aktualizujeme stav odpovídajícím způsobem. Je důležité to udělat *před* aktualizací trasy, protože během aktualizace stránky může být kód závislý na stavu.
Můžeme také nastavit stránku *Dashboard* jako výchozí stránku naší aplikace, protože nyní zachováváme data účtu. Pokud žádná data nenajdeme, přehled se stejně postará o přesměrování na stránku *Login*. V `updateRoute()` nahraďte výchozí `return navigate('/login');` za `return navigate('/dashboard');`.
Můžeme také udělat stránku *Dashboard* výchozí stránkou naší aplikace, protože nyní uchováváme data účtu. Pokud žádná data nejsou nalezena, dashboard se postará o přesměrování na stránku *Login*. V `updateRoute()` nahraďte výchozí `return navigate('/login');` za `return navigate('/dashboard');`.
Nyní se přihlaste do aplikace a zkuste obnovit stránku. Měli byste zůstat na přehledu. Touto aktualizací jsme se postarali o všechny naše počáteční problémy...
Nyní se přihlaste do aplikace a zkuste obnovit stránku. Měli byste zůstat na dashboardu. S touto aktualizací jsme se postarali o všechny naše počáteční problémy...
## Aktualizace dat
...Ale možná jsme také vytvořili nový problém. Ups!
Přejděte na přehled pomocí účtu `test`, poté spusťte tento příkaz v terminálu pro vytvoření nové transakce:
Přejděte na dashboard pomocí účtu `test`, poté spusťte tento příkaz v terminálu, abyste vytvořili novou transakci:
Zkuste nyní obnovit stránku přehledu v prohlížeči. Co se stane? Vidíte novou transakci?
Zkuste nyní obnovit stránku dashboardu v prohlížeči. Co se stane? Vidíte novou transakci?
Stav je zachován na neurčito díky `localStorage`, ale to také znamená, že se nikdy neaktualizuje, dokud se z aplikace neodhlásíte a znovu nepřihlásíte!
Stav je uchováván neomezeně díky `localStorage`, ale to také znamená, že se nikdy neaktualizuje, dokud se z aplikace neodhlásíte a znovu nepřihlásíte!
Jednou z možných strategií, jak to opravit, je znovu načíst data účtu pokaždé, když je přehled načten, aby se předešlo zastaralým datům.
Jednou z možných strategií, jak to opravit, je znovu načíst data účtu pokaždé, když je dashboard načten, aby se zabránilo zastaralým datům.
### Úkol
@ -247,9 +247,9 @@ async function updateAccountData() {
}
```
Tato metoda ověřuje, že jsme aktuálně přihlášeni, a poté znovu načte data účtu ze serveru.
Tato metoda kontroluje, zda jsme aktuálně přihlášeni, a poté znovu načte data účtu ze serveru.
Vytvořte další funkci s názvem`refresh`:
Vytvořte další funkci nazvanou`refresh`:
```js
async function refresh() {
@ -258,7 +258,7 @@ async function refresh() {
}
```
Tato funkce aktualizuje data účtu a poté se postará o aktualizaci HTML stránky přehledu. To je to, co potřebujeme zavolat, když je načtena trasa přehledu. Aktualizujte definici trasy na:
Tato funkce aktualizuje data účtu a poté se postará o aktualizaci HTML stránky dashboardu. To je to, co potřebujeme zavolat, když je načtena trasa dashboardu. Aktualizujte definici trasy:
```js
const routes = {
@ -267,28 +267,28 @@ const routes = {
};
```
Zkuste nyní obnovit přehled, měl by zobrazit aktualizovaná data účtu.
Zkuste nyní obnovit dashboard, měl by zobrazit aktualizovaná data účtu.
---
## 🚀 Výzva
Nyní, když znovu načítáme data účtu pokaždé, když je přehled načten, myslíte si, že stále potřebujeme zachovávat *všechna data účtu*?
Nyní, když znovu načítáme data účtu pokaždé, když je dashboard načten, myslíte si, že stále potřebujeme uchovávat *všechna data účtu*?
Zkuste společně změnit, co je uloženo a načítáno z `localStorage`, aby zahrnovalo pouze to, co je pro fungování aplikace absolutně nezbytné.
Zkuste společně upravit, co je ukládáno a načítáno z `localStorage`, aby zahrnovalo pouze to, co je absolutně nezbytné pro fungování aplikace.
Tento dokument byl přeložen pomocí služby AI pro překlady [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Tato lekce pokrývá základy používání [VSCode.dev](https://vscode.dev), webového editoru kódu, abyste mohli upravovat svůj kód a přispívat do projektu, aniž byste museli cokoli instalovat na svůj počítač.
Tato lekce se zabývá základy používání [VSCode.dev](https://vscode.dev), webového editoru kódu, který vám umožní upravovat kód a přispívat do projektu bez nutnosti instalace čehokoli na váš počítač.
<!----
TODO: přidat volitelný obrázek
@ -40,7 +40,7 @@ Editor kódu je nezbytný nástroj pro psaní programů a spolupráci na existuj
## Začínáme s VSCode.dev
[VSCode.dev](https://vscode.dev) je editor kódu na webu. Nemusíte nic instalovat, stačí ho otevřít jako jakoukoli jinou webovou stránku. Chcete-li začít s editorem, otevřete následující odkaz: [https://vscode.dev](https://vscode.dev). Pokud nejste přihlášeni na [GitHub](https://github.com/), postupujte podle pokynů k přihlášení nebo vytvoření nového účtu a poté se přihlaste.
[VSCode.dev](https://vscode.dev) je editor kódu na webu. Nemusíte nic instalovat, stačí ho otevřít jako jakoukoli jinou webovou stránku. Chcete-li začít, otevřete následující odkaz: [https://vscode.dev](https://vscode.dev). Pokud nejste přihlášeni na [GitHub](https://github.com/), postupujte podle pokynů k přihlášení nebo vytvoření nového účtu a poté se přihlaste.
Po načtení by měl editor vypadat podobně jako na tomto obrázku:
@ -54,11 +54,11 @@ Existují tři hlavní sekce, od levé strany směrem doprava:
Klikněte na každou z ikon, abyste zobrazili různé nabídky. Po dokončení klikněte na _Průzkumník_, abyste se vrátili na výchozí obrazovku.
Když začnete vytvářet kód nebo upravovat existující kód, bude se to odehrávat v největší oblasti napravo. Tuto oblast budete také používat k vizualizaci existujícího kódu, což si vyzkoušíte v další části.
Když začnete vytvářet nebo upravovat kód, bude se to odehrávat v největší oblasti napravo. Tuto oblast budete také používat k vizualizaci existujícího kódu, což si vyzkoušíte v další části.
## Otevření GitHub repozitáře
První věc, kterou budete potřebovat, je otevřít GitHub repozitář. Existuje několik způsobů, jak repozitář otevřít. V této sekci si ukážeme dva různé způsoby, jak můžete repozitář otevřít a začít pracovat na změnách.
Prvním krokem je otevření GitHub repozitáře. Existuje několik způsobů, jak repozitář otevřít. V této sekci se podíváme na dva různé způsoby, jak začít pracovat na změnách.
### 1. Pomocí editoru
@ -66,17 +66,17 @@ Použijte samotný editor k otevření vzdáleného repozitáře. Pokud přejdet
Můžete také použít příkazovou paletu. Příkazová paleta je vstupní pole, do kterého můžete zadat libovolné slovo, které je součástí příkazu nebo akce, abyste našli správný příkaz k provedení. Použijte nabídku vlevo nahoře, poté vyberte _View_ a následně _Command Palette_, nebo použijte následující klávesovou zkratku: Ctrl-Shift-P (na MacOS Command-Shift-P).
Můžete také použít příkazovou paletu. Příkazová paleta je vstupní pole, do kterého můžete zadat libovolné slovo, které je součástí příkazu nebo akce, abyste našli správný příkaz k provedení. Použijte nabídku vlevo nahoře, poté vyberte _View_ a následně _Command Palette_, nebo použijte klávesovou zkratku: Ctrl-Shift-P (na MacOS Command-Shift-P).
Jakmile se nabídka otevře, napište _open remote repository_ a poté vyberte první možnost. Zobrazí se vám seznam repozitářů, kterých jste součástí nebo které jste nedávno otevřeli. Můžete také použít úplnou URL adresu GitHubu k výběru jednoho z nich. Použijte následující URL a vložte ji do pole:
Jakmile se nabídka otevře, napište _open remote repository_ a vyberte první možnost. Zobrazí se seznam repozitářů, kterých jste součástí nebo které jste nedávno otevřeli. Můžete také použít úplnou URL adresu GitHubu k výběru jednoho z nich. Použijte následující URL a vložte ji do pole:
✅ Pokud bylo úspěšné, uvidíte všechny soubory tohoto repozitáře načtené v textovém editoru.
✅ Pokud se vše podaří, uvidíte všechny soubory tohoto repozitáře načtené v textovém editoru.
### 2. Použití URL
@ -84,25 +84,25 @@ Repozitář můžete také načíst přímo pomocí URL. Například úplná URL
## Úprava souborů
Jakmile máte repozitář otevřený v prohlížeči/vscode.dev, dalším krokem bude provádění aktualizací nebo změn projektu.
Jakmile máte repozitář otevřený v prohlížeči/vscode.dev, dalším krokem je provádění aktualizací nebo změn projektu.
### 1. Vytvoření nového souboru
Můžete vytvořit soubor buď uvnitř existující složky, nebo v kořenovém adresáři/složce. Chcete-li vytvořit nový soubor, otevřete umístění/složku, do které chcete soubor uložit, a vyberte ikonu _'New file ...'_ na panelu aktivit _(vlevo)_, pojmenujte ho a stiskněte Enter.
Soubor můžete vytvořit buď uvnitř existující složky, nebo v kořenovém adresáři/složce. Chcete-li vytvořit nový soubor, otevřete umístění/složku, kam chcete soubor uložit, a vyberte ikonu _'New file ...'_ na panelu aktivit _(vlevo)_, pojmenujte ho a stiskněte Enter.

### 2. Úprava a uložení souboru v repozitáři
Používání vscode.dev je užitečné, kdykoli chcete rychle aktualizovat svůj projekt, aniž byste museli načítat jakýkoli software lokálně.
Chcete-li aktualizovat svůj kód, klikněte na ikonu 'Explorer', která se také nachází na panelu aktivit, abyste zobrazili soubory a složky v repozitáři.
Vyberte soubor, který chcete otevřít v oblasti kódu, proveďte změny a uložte.
Používání vscode.dev je užitečné, kdykoli chcete rychle aktualizovat svůj projekt bez nutnosti načítání jakéhokoli softwaru lokálně.
Chcete-li aktualizovat svůj kód, klikněte na ikonu 'Explorer', která se také nachází na panelu aktivit, abyste zobrazili soubory a složky v repozitáři. Vyberte soubor, který chcete otevřít v oblasti kódu, proveďte změny a uložte.
Jakmile dokončíte aktualizaci projektu, vyberte ikonu _`source control`_, která obsahuje všechny nové změny, které jste provedli v repozitáři.
Chcete-li zobrazit změny, které jste provedli ve svém projektu, vyberte soubor(y) ve složce `Changes` na rozšířeném panelu aktivit. Tím se otevře 'Working Tree', kde vizuálně uvidíte změny, které jste provedli v souboru. Červená barva označuje vynechání projektu, zatímco zelená značí přidání.
Chcete-li zobrazit změny, které jste provedli, vyberte soubor(y) ve složce `Changes` na rozšířeném panelu aktivit. Tím se otevře 'Working Tree', kde vizuálně uvidíte změny, které jste provedli v souboru. Červená barva označuje odstranění z projektu, zatímco zelená značí přidání.
@ -110,7 +110,7 @@ Pokud jste spokojeni se změnami, které jste provedli, najeďte na složku `Cha
Pokud však nejste spokojeni s některými změnami a chcete je zrušit, najeďte na složku `Changes` a vyberte ikonu `undo`.
Poté zadejte `commit message`_(popis změny, kterou jste provedli v projektu)_, klikněte na ikonu `check`, abyste změny commitovali a odeslali.
Poté napište `commit message`_(popis změny, kterou jste provedli v projektu)_, klikněte na ikonu `check`, abyste změny commitovali a odeslali.
Jakmile dokončíte práci na projektu, vyberte ikonu `hamburger menu` vlevo nahoře, abyste se vrátili do repozitáře na github.com.
@ -118,10 +118,10 @@ Jakmile dokončíte práci na projektu, vyberte ikonu `hamburger menu` vlevo nah
## Používání rozšíření
Instalace rozšíření na VSCode vám umožňuje přidávat nové funkce a možnosti přizpůsobení vývojového prostředí ve vašem editoru, což zlepšuje váš vývojový proces. Tato rozšíření také pomáhají přidávat podporu pro různé programovací jazyky a často jsou buď obecná, nebo zaměřená na konkrétní jazyk.
Instalace rozšíření ve VSCode vám umožní přidat nové funkce a možnosti přizpůsobení vývojového prostředí v editoru, což zlepší váš pracovní postup. Tato rozšíření také pomáhají přidat podporu pro různé programovací jazyky a často jsou buď obecná, nebo zaměřená na konkrétní jazyk.
Chcete-li procházet seznam všech dostupných rozšíření, klikněte na ikonu _`Extensions`_ na panelu aktivit a začněte psát název rozšíření do textového pole označeného _'Search Extensions in Marketplace'_.
Uvidíte seznam rozšíření, z nichž každé obsahuje **název rozšíření, jméno vydavatele, jednovětný popis, počet stažení** a **hodnocení hvězdičkami**.
Chcete-li procházet seznam všech dostupných rozšíření, klikněte na ikonu _`Extensions`_ na panelu aktivit a začněte psát název rozšíření do textového pole označeného _'Search Extensions in Marketplace'_.
Zobrazí se seznam rozšíření, z nichž každé obsahuje **název rozšíření, jméno vydavatele, jednovětný popis, počet stažení** a **hodnocení hvězdičkami**.
@ -151,12 +151,12 @@ Po instalaci a používání rozšíření nabízí vscode.dev možnosti správy
Vyberte nainstalované rozšíření na rozšířeném panelu aktivit > klikněte na ikonu ozubeného kolečka > vyberte 'Disable' nebo 'Disable (Workspace)' **NEBO** otevřete rozšíření v oblasti kódu a klikněte na modré tlačítko Disable.
- **Odinstalovat:** Vyberte nainstalované rozšíření na rozšířeném panelu aktivit > klikněte na ikonu ozubeného kolečka > vyberte 'Uninstall' **NEBO** otevřete rozšíření v oblasti kódu a klikněte na modré tlačítko Uninstall.
---
## Zadání
[Vytvořte webovou stránku životopisu pomocí vscode.dev](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
<!----
@ -170,5 +170,5 @@ Přečtěte si více o [VSCode.dev](https://code.visualstudio.com/docs/editor/vs
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
**Upozornění**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
# Vytvořte webovou stránku s životopisem pomocí vscode.dev
# Vytvořte webovou stránku životopisu pomocí vscode.dev
_Jak skvělé by bylo, kdyby vás personalista požádal o životopis a vy byste mu poslali URL?_ 😎
_Jak skvělé by bylo, kdyby vás personalista požádal o životopis a vy mu poslali odkaz?_ 😎
## Cíle
@ -23,9 +23,9 @@ Po tomto úkolu se naučíte:
## Kroky
**Krok 1:** Vytvořte nový GitHub repozitář a pojmenujte ho `my-resume`
**Krok 1:** Vytvořte nový GitHub repozitář a pojmenujte ho `my-resume`.
**Krok 2:** Vytvořte soubor `index.html` ve svém repozitáři. Přidáme alespoň jeden soubor přímo na github.com, protože prázdný repozitář nelze otevřít ve vscode.dev.
**Krok 2:** Vytvořte soubor `index.html` ve svém repozitáři. Přidáme alespoň jeden soubor přímo na github.com, protože prázdný repozitář nelze otevřít na vscode.dev.
Klikněte na odkaz `creating a new file`, zadejte název `index.html` a vyberte tlačítko `Commit new file`.
@ -33,7 +33,7 @@ Klikněte na odkaz `creating a new file`, zadejte název `index.html` a vyberte
**Krok 3:** Otevřete [VSCode.dev](https://vscode.dev) a vyberte tlačítko `Open Remote Repository`.
Zkopírujte URL repozitáře, který jste právě vytvořili pro svůj web s životopisem, a vložte jej do vstupního pole:
Zkopírujte URL repozitáře, který jste právě vytvořili pro svůj web životopisu, a vložte ho do vstupního pole:
_Nahraďte `your-username` svým uživatelským jménem na GitHubu._
Nahraďte _zástupný text_ ve výše uvedeném HTML kódu detaily svého životopisu.
Nahraďte _text zástupce_ ve svém HTML kódu detaily svého životopisu.
**Krok 5:** Najděte složku My-Resume, klikněte na ikonu `New File ...` a vytvořte ve svém projektu 2 nové soubory: `style.css` a `codeswing.json`.
**Krok 5:** Najděte složku My-Resume, klikněte na ikonu `New File ...` a vytvořte 2 nové soubory ve svém projektu: `style.css` a `codeswing.json`.
**Krok 6:** Otevřete soubor `style.css`, vložte do něj níže uvedený kód a uložte.
@ -217,25 +217,25 @@ Nahraďte _zástupný text_ ve výše uvedeném HTML kódu detaily svého život
"styles": []
}
**Krok 7:** Nainstalujte rozšíření `Codeswing`, abyste mohli vizualizovat webovou stránku s životopisem v kódovací oblasti.
**Krok 7:** Nainstalujte rozšíření `Codeswing`, abyste mohli vizualizovat webovou stránku životopisu v kódové oblasti.
Klikněte na ikonu _`Extensions`_ na panelu aktivit a zadejte Codeswing. Klikněte na _modré tlačítko instalace_ na rozšířeném panelu aktivit nebo použijte tlačítko instalace, které se objeví v kódovací oblasti po výběru rozšíření. Ihned po instalaci rozšíření sledujte změny ve svém projektu 😃.
Klikněte na ikonu _`Extensions`_ na panelu aktivit a zadejte Codeswing. Klikněte na _modré tlačítko instalace_ na rozšířeném panelu aktivit nebo použijte tlačítko instalace, které se objeví v kódové oblasti, jakmile vyberete rozšíření pro načtení dalších informací. Ihned po instalaci rozšíření si všimněte změn ve vašem projektu 😃.


Pokud jste spokojeni se změnami, které jste provedli, najděte složku `Changes` a klikněte na tlačítko `+`, abyste změny připravili ke commitu.
Pokud jste spokojeni se změnami, které jste provedli, najděte složku `Changes` a klikněte na tlačítko `+`, abyste změny připravili.
Zadejte zprávu ke commitu _(popis změn, které jste provedli v projektu)_ a potvrďte změny kliknutím na `check`. Po dokončení práce na projektu vyberte ikonu hamburgerového menu v levém horním rohu a vraťte se do repozitáře na GitHubu.
Zadejte zprávu ke commitu _(popis změny, kterou jste provedli v projektu)_ a potvrďte změny kliknutím na `check`. Jakmile dokončíte práci na projektu, vyberte ikonu hamburgerového menu v levém horním rohu a vraťte se do repozitáře na GitHubu.
Gratulujeme 🎉 Právě jste vytvořili webovou stránku s životopisem pomocí vscode.dev v několika krocích.
Gratulujeme 🎉 Právě jste vytvořili webovou stránku svého životopisu pomocí vscode.dev během několika kroků.
## 🚀 Výzva
Otevřete vzdálený repozitář, ke kterému máte oprávnění provádět změny, a aktualizujte některé soubory. Poté zkuste vytvořit novou větev se svými změnami a vytvořit Pull Request.
Otevřete vzdálený repozitář, ke kterému máte oprávnění provádět změny, a aktualizujte některé soubory. Poté zkuste vytvořit novou větev se svými změnami a vytvořte Pull Request.
## Recenze a samostudium
@ -244,4 +244,4 @@ Přečtěte si více o [VSCode.dev](https://code.visualstudio.com/docs/editor/vs
---
**Prohlášení**:
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.
Tento dokument byl přeložen pomocí služby pro automatický překlad [Co-op Translator](https://github.com/Azure/co-op-translator). I když se snažíme o co největší přesnost, mějte prosím na paměti, že automatické překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za závazný zdroj. Pro důležité informace doporučujeme profesionální lidský překlad. Neodpovídáme za žádná nedorozumění nebo nesprávné výklady vyplývající z použití tohoto překladu.
Some files were not shown because too many files have changed in this diff
Show More