diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml new file mode 100644 index 00000000..6984af78 --- /dev/null +++ b/.github/workflows/lock.yml @@ -0,0 +1,13 @@ +name: Lock closed issue + +on: + issues: + types: [closed] + +jobs: + lock: + runs-on: ubuntu-latest + steps: + - uses: OSDKDev/lock-issues@v1.1 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/README.md b/1-getting-started-lessons/1-intro-to-programming-languages/README.md index 110623ca..5bce8be1 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/README.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/README.md @@ -2,7 +2,7 @@ This lesson covers the basics of programming languages. The topics covered here apply to most modern programming languages today. In the 'Tools of the Trade' section, you'll learn about useful software that helps you as a developer. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md b/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md index 649d2ab6..c1206550 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md @@ -2,7 +2,7 @@ ## Instructions -There are many tools that a web developer may need that are on the [MDN documentation for client-side tooling](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Select 3 tools not covered in the lesson, explain why a web developer would use it, and search for a tool that falls under this category and share its documentation. Do not use the same tool example on MDN docs. +There are many tools that a web developer may need that are on the [MDN documentation for client-side tooling](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Select 3 tools not covered in the lesson, explain why a web developer would use it, and search for a tool that falls under this category and share its documentation. Do not use the same tool example on MDN docs. ## Rubric diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.es.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.es.md index d1da3963..e882d21c 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.es.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.es.md @@ -1,6 +1,9 @@ # Introducción a lenguajes de programación y herramientas del oficio -Esta lección cubre los conceptos básicos de los lenguajes de programación. Los temas que se tratan aquí se aplican a la mayoría de los lenguajes de programación modernos en la actualidad. En la sección 'Herramientas del oficio', aprenderá sobre software útil que lo ayuda como desarrollador. +Esta lección cubre los conceptos básicos de los lenguajes de programación. Los temas que aprenderemos aquí se aplican a la mayoría de los lenguajes de programación modernos en la actualidad. En la sección 'Herramientas del oficio', aprenderás sobre software y herramientas que te ayudarán como desarrollador. + + +> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/1) ### Introducción @@ -10,21 +13,21 @@ En esta lección, cubriremos: - ¿Qué es la programación? - Tipos de lenguajes de programación - Elementos básicos de un programa -- Software y herramientas útiles para el desarrollador profesional. +- Software y herramientas para desarrolladores profesionales ## ¿Qué es la programación? -La programación (también conocida como codificación) es el proceso de escribir instrucciones en un dispositivo, como una computadora o un dispositivo móvil. Escribimos estas instrucciones con un lenguaje de programación, que luego es interpretado por el dispositivo. Estos conjuntos de instrucciones pueden tener varios nombres, pero *programa*, *programa de computadora*, *aplicación (app)* y *ejecutable* son algunos nombres populares. +La programación (también conocida como codificación) es el proceso de escribir instrucciones en un dispositivo, como una computadora o un celular. Escribimos estas instrucciones con un lenguaje de programación, que luego es interpretado por el dispositivo. Estos conjuntos de instrucciones pueden tener varios nombres, pero *programa*, *programa de computadora*, *aplicación (app)* y *ejecutable* son algunos nombres populares. -Un *programa* puede ser cualquier cosa que esté escrita con código; los sitios web, los juegos y las aplicaciones de teléfono son programas. Si bien es posible crear un programa sin escribir código, la lógica subyacente se interpreta al dispositivo y esa lógica probablemente se escribió con código. Un programa que está *ejecutándose* o *ejecutando código* está ejecutando instrucciones. El dispositivo con el que estás leyendo esta lección está ejecutando un programa para imprimirlo en tu pantalla. +Un *programa* puede ser cualquier cosa que esté escrita con código; los sitios web, los video juegos y las aplicaciones de teléfono son programas. Si bien es posible crear un programa sin escribir código, la lógica subyacente se interpreta al dispositivo y esa lógica probablemente se escribió con código. Un programa que está *ejecutándose* o *ejecutando código* está ejecutando instrucciones. El dispositivo con el que estás leyendo esta lección está ejecutando un programa para imprimirlo en tu pantalla. -✅ Investigua un poco: ¿quién se considera el primer programador de computadoras del mundo? +✅ Investigua un poco: ¿quién se considera el primer programador(a) de computadoras del mundo? ## Lenguajes de programación -Los lenguajes de programación tienen un propósito principal: que los desarrolladores creen instrucciones para enviarlas a un dispositivo. Los dispositivos solo pueden entender binarios (1 y 0), y para *la mayoría* de los desarrolladores esa no es una forma muy eficiente de comunicarse. Los lenguajes de programación son un vehículo para la comunicación entre humanos y computadoras. +Los lenguajes de programación tienen un propósito principal: que los desarrolladores crear instrucciones para enviarlas a un dispositivo. Los dispositivos solo pueden entender binarios (1 y 0), y para *la mayoría* de los desarrolladores, esa no es una forma muy eficiente de comunicarse. Los lenguajes de programación son un vehículo para la comunicación entre humanos y computadoras. -Los lenguajes de programación vienen en diferentes formatos y pueden tener diferentes propósitos. Por ejemplo, JavaScript se usa principalmente para aplicaciones web, mientras que Bash se usa principalmente para sistemas operativos. +Los lenguajes de programación vienen en diferentes formatos y tienen diferentes propósitos. Por ejemplo, JavaScript se usa principalmente para aplicaciones web, mientras que Bash se usa principalmente para sistemas operativos. *Los idiomas de bajo nivel* normalmente requieren menos pasos que los *idiomas de alto nivel* para que un dispositivo interprete las instrucciones. Sin embargo, lo que hace que los lenguajes de alto nivel sean populares es su legibilidad y soporte. JavaScript se considera un lenguaje de alto nivel. @@ -85,20 +88,20 @@ Existe la posibilidad de que un dispositivo no ejecute algunas declaraciones. Es [](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade") -En esta sección, aprenderá sobre algún software que puede resultarle muy útil al comenzar su viaje de desarrollo profesional. +En esta sección, aprenderás sobre software que puede ayudarte comenzar tu viaje de desarrollo profesional. Un **entorno de desarrollo** es un conjunto único de herramientas y características que un desarrollador utilizará a menudo al escribir software. Algunas de estas herramientas se han personalizado para las necesidades específicas de un desarrollador y pueden cambiar con el tiempo si un desarrollador cambia las prioridades en el trabajo o proyectos personales, o cuando usa un lenguaje de programación diferente. Los entornos de desarrollo son tan únicos como los desarrolladores que los utilizan. ### Editores -Una de las herramientas más importantes para el desarrollo de software es el editor. Los editores son el lugar donde escribe su código y, a veces, donde ejecutará su código. +Una de las herramientas más importantes para el desarrollo de software es el editor. Los editores son el lugar donde escribes su código y, a veces, donde ejecutarás tu código. Los desarrolladores confían en los editores por algunas razones adicionales: -- *Depuración* Descubrimiento de errores y errores al recorrer el código, línea por línea. Algunos editores tienen capacidades de depuración o se pueden personalizar y agregar para lenguajes de programación específicos. -- *Resaltado de sintaxis* Agrega colores y formato de texto al código, lo hace más fácil de leer. La mayoría de los editores permiten el resaltado de sintaxis personalizado. -- *Extensiones e integraciones del navegador* Adiciones especializadas para desarrolladores, por desarrolladores, para acceder a herramientas adicionales que no están integradas en el editor base. Por ejemplo, muchos desarrolladores también necesitan una forma de documentar su código y explicar cómo funciona, e instalarán una extensión de revisión ortográfica para verificar si hay errores tipográficos. La mayoría de estas adiciones están diseñadas para su uso dentro de un editor específico, y la mayoría de los editores vienen con una forma de buscar extensiones disponibles. -- *Personalización* La mayoría de los editores son extremadamente personalizables, y cada desarrollador tendrá su propio entorno de desarrollo único que se adapta a sus necesidades. Muchos también permiten a los desarrolladores crear su propia extensión. +- *Depuración* - Descubrimiento de errores y errores al recorrer el código, línea por línea. Algunos editores tienen capacidades de depuración o se pueden personalizar y agregar para lenguajes de programación específicos. +- *Resaltado de sintaxis* - Agrega colores y formato de texto al código, lo hace más fácil de leer. La mayoría de los editores permiten el resaltado de sintaxis personalizado. +- *Extensiones e integraciones del navegador* - Adiciones especializadas para desarrolladores, por desarrolladores, para acceder a herramientas adicionales que no están integradas en el editor base. Por ejemplo, muchos desarrolladores también necesitan una forma de documentar su código y explicar cómo funciona, e instalarán una extensión de revisión ortográfica para verificar si hay errores. La mayoría de estas adiciones están diseñadas para usarse dentro de un editor específico, y la mayoría de los editores vienen con una forma de buscar extensiones disponibles. +- *Personalización* - La mayoría de los editores son extremadamente personalizables, y cada desarrollador tendrá su propio entorno de desarrollo único que se adapta a sus necesidades. Muchos también permiten a los desarrolladores crear su propia extensión. #### Editores populares y extensiones de desarrollo web @@ -114,9 +117,9 @@ Los desarrolladores confían en los editores por algunas razones adicionales: ### Navegadores -Otra herramienta fundamental es el navegador. Los desarrolladores web confían en el navegador para observar cómo se ejecuta su código en la web, también se usa para ver elementos visuales de una página web que están escritos en el editor, como HTML. +Otra herramienta fundamental es el navegador. Los desarrolladores de web confían en el navegador para observar cómo se ejecuta su código en la web. También se usa para ver elementos visuales de una página web que están escritos en el editor, como HTML. -Muchos navegadores vienen con *herramientas para desarrolladores* (DevTools) que contienen un conjunto de características e información útiles para ayudar a los desarrolladores a recopilar y capturar información importante sobre su aplicación. Por ejemplo: si una página web tiene errores, a veces es útil saber cuándo ocurrieron. DevTools en un navegador se puede configurar para capturar esta información. +Muchos navegadores vienen con *herramientas para desarrolladores* (DevTools) que contienen un conjunto de características e información útiles para ayudar a los desarrolladores a recopilar y capturar información importante sobre su aplicación. Por ejemplo: si una página web tiene errores, a veces es útil saber cuándo ocurrieron. Se puede configurar DevTools en un navegador para capturar esta información. #### Navegadores y herramientas de desarrollo populares @@ -124,15 +127,15 @@ Muchos navegadores vienen con *herramientas para desarrolladores* (DevTools) que - [Chrome](https://developers.google.com/web/tools/chrome-devtools/) - [Firefox](https://developer.mozilla.org/docs/Tools) -### Herramientas de línea de comandos +### Herramientas de línea de comandos (CLI) -Algunos desarrolladores prefieren una vista menos gráfica para sus tareas diarias y confían en la línea de comandos para lograrlo. El desarrollo de código requiere una gran cantidad de escritura, y algunos desarrolladores prefieren no interrumpir su flujo en el teclado y usarán atajos de teclado para cambiar entre ventanas de escritorio, trabajar en diferentes archivos y usar herramientas. La mayoría de las tareas se pueden completar con un mouse, pero una de las ventajas de utilizar la línea de comandos es que se pueden hacer muchas cosas con las herramientas de la línea de comandos sin necesidad de cambiar entre el mouse y el teclado. Otro beneficio de la línea de comandos es que son configurables y puede guardar su configuración personalizada, cambiarla más tarde y también importarla a nuevas máquinas de desarrollo. Debido a que los entornos de desarrollo son tan exclusivos para cada desarrollador, algunos evitarán usar la línea de comandos, algunos dependerán de ella por completo y algunos prefieren una combinación de ambos. +Algunos desarrolladores prefieren una vista menos gráfica para sus tareas diarias y confían en la línea de comandos **(CLI)** para lograrlo. El desarrollo de código requiere una gran cantidad de escritura, y algunos desarrolladores prefieren no interrumpir su flujo en el teclado y usarán atajos (shortcut) de teclado para cambiar entre ventanas de escritorio, trabajar en diferentes archivos y usar herramientas. La mayoría de las tareas se pueden completar con un mouse, pero una de las ventajas de utilizar la línea de comandos es que se pueden hacer muchas cosas con las herramientas de la línea de comandos, sin necesidad de cambiar entre el mouse y el teclado. Otro beneficio de la línea de comandos es que son configurables y puedes guardar tu configuración personalizada, cambiarla más tarde y también importarla a nuevas máquinas de desarrollo. Debido a que los entornos de desarrollo son tan exclusivos para cada desarrollador, algunos evitarán usar la línea de comandos, algunos dependerán de ella por completo y algunos prefieren una combinación de ambos. -### Opciones de línea de comandos populares +### Opciones de línea de comandos (CLI) populares -Las opciones para la línea de comando variarán según el sistema operativo que utilice. +Las opciones para la línea de comando varian según el sistema operativo que utilices. -*💻 = viene preinstalado en el sistema operativo.* +💻 = *viene preinstalado en el sistema operativo.* #### Windows @@ -153,7 +156,7 @@ Las opciones para la línea de comando variarán según el sistema operativo que - [KDE Konsole](https://docs.kde.org/trunk5/en/applications/konsole/index.html) - [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7?WT.mc_id=academic-13441-cxa) -#### Popular Command Line Tools +#### Línea de comandos (CLI) Populares - [Git](https://git-scm.com/) (💻 en la mayoría de los sistemas operativos) - [NPM](https://www.npmjs.com/) @@ -161,9 +164,9 @@ Las opciones para la línea de comando variarán según el sistema operativo que ### Documentación -Cuando un desarrollador quiere aprender algo nuevo, lo más probable es que recurra a la documentación para aprender a usarla. Los desarrolladores a menudo confían en la documentación para guiarlos a través de cómo usar las herramientas y los lenguajes correctamente, y también para obtener un conocimiento más profundo de cómo funciona. +Cuando un desarrollador quiere aprender algo nuevo, lo más probable es que recurras a la documentación para aprender a usarla. Los desarrolladores a menudo confían en la documentación para guiarlos a través de cómo usar las herramientas y los lenguajes correctamente, y también para obtener un conocimiento más profundo de cómo funciona. -#### Documentación popular sobre desarrollo web +#### Documentación popular sobre desarrollo de web - [Mozilla Developer Network](https://developer.mozilla.org/docs/Web) - [Frontend Masters](https://frontendmasters.com/learn/) @@ -178,6 +181,6 @@ Compara algunos lenguajes de programación. ¿Cuáles son algunos de los rasgos ## Revisión y autoestudio -Estudia un poco sobre los diferentes lenguajes disponibles para el programador. Intente escribir una línea en un idioma y luego vuelva a hacerlo en otros dos. ¿Qué aprendes? +Estudia un poco sobre los diferentes lenguajes disponibles para el programador. Intenta escribir una línea en un idioma y luego vuelve a hacerlo en otros dos. ¿Qué aprendiste? -**Asignación**: [Asignación](../assignment.md) \ No newline at end of file +**Tarea**: [Tarea](../assignment.md) \ No newline at end of file diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.fr.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.fr.md new file mode 100644 index 00000000..f04fed52 --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.fr.md @@ -0,0 +1,191 @@ +# Introduction aux langages de programmation et aux outils du métier + +Cette leçon couvre les bases des langages de programmation. Les sujets abordés ici s'appliquent à la plupart des langages de programmation modernes d'aujourd'hui. Dans la section «Outils du métier», vous découvrirez des logiciels utiles qui vous aideront en tant que développeur. + + +> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) + +## Pre-Lecture Quiz +[Pre-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/1) + +## introduction + +Dans cette leçon, nous aborderons: + +- Qu'est-ce que la programmation? +- Types de langages de programmation +- Éléments de base d'un programme +- Logiciel et outillage utiles pour le développeur professionnel + +## Qu'est-ce que la programmation? + +Pla programmation (également appelée codage) est le processus d'écriture d'instructions sur un appareil, tel qu'un ordinateur ou un appareil mobile. Nous écrivons ces instructions avec un langage de programmation, qui est ensuite interprété par l'appareil. Ces ensembles d'instructions peuvent être désignés sous différents noms, mais *programme*, *programme informatique*, *application (application)* et *exécutable* sont quelques noms courants. + +Un *programme* peut être tout ce qui est écrit avec du code; les sites Web, les jeux et les applications téléphoniques sont des programmes. Bien qu'il soit possible de créer un programme sans écrire de code, la logique sous-jacente est interprétée sur le périphérique et cette logique a probablement été écrite avec du code. Un programme qui *exécute* ou *exécute du code* exécute des instructions. L'appareil avec lequel vous lisez actuellement cette leçon exécute un programme pour l'imprimer sur votre écran. + +✅ Faites une petite recherche: qui est considéré comme le premier programmeur informatique au monde? + +## Langages de programmation + +Les langages de programmation ont un objectif principal: permettre aux développeurs de créer des instructions à envoyer à un appareil. Les appareils ne peuvent comprendre que le binaire (1 et 0), et pour *la plupart* les développeurs, ce n'est pas un moyen très efficace de communiquer. Les langages de programmation sont un vecteur de communication entre les humains et les ordinateurs. + +Les langages de programmation se présentent sous différents formats et peuvent servir à des fins différentes. Par exemple, JavaScript est principalement utilisé pour les applications Web, tandis que Bash est principalement utilisé pour les systèmes d'exploitation. + +*Les langues de bas niveau* nécessitent généralement moins d'étapes que les *langues de haut niveau* pour qu'un appareil interprète les instructions. Cependant, ce qui rend les langages de haut niveau populaires, c'est leur lisibilité et leur support. JavaScript est considéré comme un langage de haut niveau. + +Le code suivant illustre la différence entre un langage de haut niveau avec JavaScript et un langage de bas niveau avec le code d'assembly ARM. + +```javascript +let number = 10 +let n1 = 0, n2 = 1, nextTerm; + +for (let i = 1; i <= number; i++) { + console.log(n1); + nextTerm = n1 + n2; + n1 = n2; + n2 = nextTerm; +} +``` + +```c + area ascen,code,readonly + entry + code32 + adr r0,thumb+1 + bx r0 + code16 +thumb + mov r0,#00 + sub r0,r0,#01 + mov r1,#01 + mov r4,#10 + ldr r2,=0x40000000 +back add r0,r1 + str r0,[r2] + add r2,#04 + mov r3,r0 + mov r0,r1 + mov r1,r3 + sub r4,#01 + cmp r4,#00 + bne back + end +``` + +Croyez-le ou non, *they're both doing the same thing*: impression d'une séquence de Fibonacci jusqu'à 10. + +✅ Une séquence de Fibonacci est [defined](https://en.wikipedia.org/wiki/Fibonacci_number) comme un ensemble de nombres tels que chaque nombre est la somme des deux précédents, à partir de 0 et 1. + +## Éléments d'un programme + +Une seule instruction dans un programme est appelée une *instruction* et aura généralement un caractère ou un interligne qui marque où l'instruction se termine, ou *se termine*. La façon dont un programme se termine varie avec chaque langue. + +La plupart des programmes reposent sur l'utilisation des données d'un utilisateur ou d'ailleurs, où les déclarations peuvent s'appuyer sur des données pour exécuter des instructions. Les données peuvent modifier le comportement d'un programme, de sorte que les langages de programmation proposent un moyen de stocker temporairement des données pouvant être utilisées ultérieurement. Ces données sont appelées *variables*. Les variables sont des instructions qui demandent à un appareil d'enregistrer des données dans sa mémoire. Les variables des programmes sont similaires à celles de l'algèbre, où elles ont un nom unique et leur valeur peut changer avec le temps. + +Il est possible que certaines instructions ne soient pas exécutées par un périphérique. C'est généralement par conception lors de l'écriture par le développeur ou par accident lorsqu'une erreur inattendue se produit. Ce type de contrôle d'une application la rend plus robuste et maintenable. Généralement, ces changements de contrôle se produisent lorsque certaines décisions sont respectées. Une instruction courante dans les langages de programmation modernes pour contrôler la manière dont un programme est exécuté est l'instruction `if..else`. + +✅ Vous en apprendrez plus sur ce type d'énoncé dans les leçons suivantes + +## Outils du métier + +[](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade") + +Dans cette section, vous découvrirez certains logiciels que vous pourriez trouver très utiles au début de votre parcours de développement professionnel. + +Un **environnement de développement** est un ensemble unique d'outils et de fonctionnalités qu'un développeur utilisera souvent lors de l'écriture d'un logiciel. Certains de ces outils ont été personnalisés pour les besoins spécifiques d'un développeur et peuvent changer au fil du temps si un développeur change de priorités dans ses projets professionnels ou personnels, ou lorsqu'il utilise un langage de programmation différent. Les environnements de développement sont aussi uniques que les développeurs qui les utilisent. + +### éditeurs + +L'éditeur est l'un des outils les plus cruciaux pour le développement logiciel. Les éditeurs sont l'endroit où vous écrivez votre code et parfois où vous exécuterez votre code. + +Les développeurs comptent sur les éditeurs pour quelques raisons supplémentaires: + +- *Débogage* Découverte des bogues et des erreurs en parcourant le code, ligne par ligne. Certains éditeurs ont des capacités de débogage ou peuvent être personnalisés et ajoutés pour des langages de programmation spécifiques. +- *Mise en évidence de la syntaxe* Ajoute des couleurs et la mise en forme du texte au code, le rend plus facile à lire. La plupart des éditeurs permettent une coloration syntaxique personnalisée. +- *Extensions et intégrations* Ajouts spécialisés pour les développeurs, par les développeurs, pour accéder à des outils supplémentaires qui ne sont pas intégrés à l'éditeur de base. Par exemple, de nombreux développeurs ont également besoin d'un moyen de documenter leur code et d'expliquer comment il fonctionne et installeront une extension de vérification orthographique pour vérifier les fautes de frappe. La plupart de ces ajouts sont destinés à être utilisés dans un éditeur spécifique, et la plupart des éditeurs proposent un moyen de rechercher les extensions disponibles. +- *Personnalisation* La plupart des éditeurs sont extrêmement personnalisables, et chaque développeur aura son propre environnement de développement unique qui répond à ses besoins. Beaucoup permettent également aux développeurs de créer leur propre extension. + +#### Éditeurs et extensions de développement Web populaires + +- [Visual Studio Code](https://code.visualstudio.com/) + - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) + - [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) + - [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [Atom](https://atom.io/) + - [spell-check](https://atom.io/packages/spell-check) + - [teletype](https://atom.io/packages/teletype) + - [atom-beautify](https://atom.io/packages/atom-beautify) + +### Navigateurs + +Un autre outil crucial est le navigateur. Les développeurs Web comptent sur le navigateur pour observer comment leur code s'exécute sur le Web, il est également utilisé pour afficher les éléments visuels d'une page Web qui sont écrits dans l'éditeur, comme le HTML. + +De nombreux navigateurs sont livrés avec des *outils de développement* (DevTools) qui contiennent un ensemble de fonctionnalités et d'informations utiles pour aider les développeurs à collecter et capturer des informations importantes sur leur application. Par exemple: si une page Web contient des erreurs, il est parfois utile de savoir quand elles se sont produites. DevTools dans un navigateur peut être configuré pour capturer ces informations. +#### Navigateurs et outils de développement populaires + +- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium?WT.mc_id=academic-13441-cxa) +- [Chrome](https://developers.google.com/web/tools/chrome-devtools/) +- [Firefox](https://developer.mozilla.org/docs/Tools) + +### ligne de commande + +Certains développeurs préfèrent une vue moins graphique pour leurs tâches quotidiennes et comptent sur la ligne de commande pour y parvenir. Le développement de code nécessite une quantité importante de saisie, et certains développeurs préfèrent ne pas perturber leur flux sur le clavier et utiliseront des raccourcis clavier pour basculer entre les fenêtres du bureau, travailler sur différents fichiers et utiliser des outils. La plupart des tâches peuvent être effectuées avec une souris, mais un avantage de l'utilisation de la ligne de commande est que beaucoup peut être fait avec des outils de ligne de commande sans avoir besoin de permuter entre la souris et le clavier. Un autre avantage de la ligne de commande est qu'elle est configurable et que vous pouvez enregistrer votre configuration personnalisée, la modifier ultérieurement et également l'importer sur de nouvelles machines de développement. Parce que les environnements de développement sont si uniques à chaque développeur, certains éviteront d'utiliser la ligne de commande, certains s'y fieront entièrement, et certains préfèrent un mélange des deux. + +### Options de ligne de commande populaires + +Les options de la ligne de commande varient en fonction du système d'exploitation que vous utilisez. + +*💻 = est préinstallé sur le système d'exploitation.* + +#### Windows + +- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7?WT.mc_id=academic-13441-cxa) 💻 +- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands?WT.mc_id=academic-13441-cxa) (also known as CMD) 💻 +- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-13441-cxa) +- [mintty](https://mintty.github.io/) + +#### MacOS + +- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻 +- [iTerm](https://iterm2.com/) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### Linux + +- [Bash](https://www.gnu.org/software/bash/manual/html_node/index.html) 💻 +- [KDE Konsole](https://docs.kde.org/trunk5/en/applications/konsole/index.html) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### Popular Command Line Tools + +- [Git](https://git-scm.com/) (💻 on most operating sytems) +- [NPM](https://www.npmjs.com/) +- [Yarn](https://classic.yarnpkg.com/en/docs/cli/) + +### Documentation + +Lorsqu'un développeur souhaite apprendre quelque chose de nouveau, il se tournera très probablement vers la documentation pour apprendre à l'utiliser. Les développeurs s'appuient souvent sur la documentation pour les guider dans la manière d'utiliser correctement les outils et les langages, et également pour acquérir une connaissance plus approfondie de son fonctionnement. + +#### Documentation populaire sur le développement Web + +- [Mozilla Developer Network](https://developer.mozilla.org/docs/Web) +- [Frontend Masters](https://frontendmasters.com/learn/) + +✅ Faites des recherches: maintenant que vous connaissez les bases de l'environnement d'un développeur Web, comparez-le et comparez-le à l'environnement d'un concepteur Web. + +--- + +## 🚀 Défi + +Comparez quelques langages de programmation. Quelles sont certaines des caractéristiques uniques de JavaScript par rapport à Java? Et COBOL vs Go? + +## Quiz post-conférence +[Quiz post-conférence](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/2) + +## Révision et auto-étude + +Étudiez un peu les différentes langues disponibles pour le programmeur. Essayez d'écrire une ligne dans une langue, puis refaites-la dans deux autres. Qu'apprenez-vous? + +## Affectation + +[Lire la documentation](assignment.fr.md) diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.gr.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.gr.md index 82421a8f..4c924dca 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.gr.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.gr.md @@ -2,7 +2,7 @@ Αυτό το μάθημα καλύπτει τα βασικά των γλωσσών προγραμματισμού. Τα θέματα που καλύπτονται εδώ ισχύουν για τις περισσότερες σύγχρονες γλώσσες προγραμματισμού σήμερα. Στην ενότητα 'Εργαλεία του Εμπορίου', θα μάθετε για χρήσιμο λογισμικό που σας βοηθά ως προγραμματιστές. - + > Σκίτσο από [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.id.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.id.md index 13a99727..c84fcc25 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.id.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.id.md @@ -2,7 +2,7 @@ Pelajaran ini mencakup dasar-dasar bahasa pemrograman. Topik yang dibahas di sini berlaku untuk sebagian besar bahasa pemrograman modern saat ini. Di bagian 'Alat Keterampilan', Anda akan belajar tentang perangkat lunak yang berguna yang membantu Anda sebagai pengembang. - + > Catatan sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuis Pra-Kuliah diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.it.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.it.md index baac5411..ebceea1b 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.it.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.it.md @@ -2,7 +2,7 @@ Questa lezione tratta delle basi dei linguaggi di programmazione. Gli argomenti trattati qui si applicano alla maggior parte dei moderni linguaggi di programmazione di oggi. Nella sezione 'Strumenti Necessari' conoscerete utili software che vi aiuteranno come programmatore. - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ja.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ja.md index b0361fba..401c664e 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ja.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ja.md @@ -4,7 +4,7 @@ ここで取り上げた特徴は、最新のプログラミング言語のほとんどに当てはまります。 次にツールセクションでは、開発者にとって有用なソフトウェアを紹介します。 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 事前クイズ diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ko.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ko.md index bea6837a..0abd4d60 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ko.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ko.md @@ -2,7 +2,7 @@ 이 강의에서는 프로그래밍 언어의 기초를 다룹니다. 여기에서 다루는 주제는 오늘 날 많은 최신 프로그래밍 언어에 적용됩니다. 'Tools of the Trade' 세션에서는 개발자에게 도움이 되는 유용한 소프트웨어에 대해 알아보겠습니다. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ms.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ms.md index 44914eb6..1b649a80 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ms.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.ms.md @@ -2,7 +2,7 @@ Pelajaran ini merangkumi asas bahasa pengaturcaraan. Topik yang anda akan belajar di sini dapat mengaplikasikan untuk kebanyakan bahasa pengaturcaraan moden hari ini. Pada bahagian 'Alat Perdagangan', anda akan belajar bagaimana mengenai perisian berguna yang membantu anda sebagai pembangun. - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra-Kuliah diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.nl.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.nl.md index f34f2d4e..504a5143 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.nl.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.nl.md @@ -1,8 +1,8 @@ # Introductie van Programmeertalen en Bijbehorend Vakgereedschap -Deze les beschrijft de basis over programmeertalen. De onderwerpen zijn van toepassing op de meeste hedendaagse programeertalen. In het 'Vakgereedschap' onderdeel leer je over nuttige toepassingen die je helpen als web ontwikkelaar. +Deze les beschrijft de basis over programmeertalen. De onderwerpen zijn van toepassing op de meeste hedendaagse programeertalen. In het 'Vakgereedschap' onderdeel leert u over nuttige toepassingen die u helpen als web ontwikkelaar. - + > Sketchnote door [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -22,7 +22,7 @@ In deze les hebben we het over: Programmeren (ook wel coderen genoemd) is het process van het schrijven van instructies voor een apparaat, zoals een computer of een mobieltje. We schrijven deze instructies met een programmeertaal, welke wordt geinterpreteerd door het apparaat. Deze sets van instructies staan bekend onder verschillende namen zoals; *programma*, *computer programma*, *applicatie (app)*, *script* en *executable*. -Een *programma* kan van alles zijn wat met code is geschreven; websites, spellen, en mobiele apps zijn programmas. Hoewel het mogelijk is om een programma te maken zonder code te schrijven, is de onderliggende logica, dat wordt geinterpreteerd door het apparaat, hoogstwaarschijnlijk wel geschreven met code. Een programma dat *draait* of *code uitvoert* voert instructies uit. Het apparaat wat je nu gebruikt om deze les te volgen draait een programma om deze tekst op het scherm te tonen. +Een *programma* kan van alles zijn wat met code is geschreven; websites, spellen, en mobiele apps zijn programmas. Hoewel het mogelijk is om een programma te maken zonder code te schrijven, is de onderliggende logica, dat wordt geinterpreteerd door het apparaat, hoogstwaarschijnlijk wel geschreven met code. Een programma dat *draait* of *code uitvoert* voert instructies uit. Het apparaat wat u nu gebruikt om deze les te volgen draait een programma om deze tekst op het scherm te tonen. ✅ Doe wat onderzoek: wie wordt gezien als werelds eerste computer programmeur? @@ -85,24 +85,24 @@ De meeste programma's zijn afhankelijk van gegevens, die ofwel door een gebruike Niet alle statements in een programma worden altijd uitgevoerd. Dit is meestal zo bedacht door de ontwikkelaar of het treed onbedoeld op bij onverwachte fouten. Het is een vorm van controle in een applicatie, dat het robuuster en onderhoudbaarder maakt. De keuze in welke statements worden uitgevoerd hangt vaak af van de data en of dit voldoet aan bepaalde condities. Een veelvoorkomend statement in een moderne programmeertaal om de controle van een programma te beïnvloeden is het `if..else` statement. -✅ Je leert meer over het `if..else` statement in de volgende lessen. +✅ U leert meer over het `if..else` statement in de volgende lessen. ## Vakgereedschap [](https://youtube.com/watch?v=69WJeXGBdxg "Vakgereedschap") -In dit onderdeel leer je welke applicaties je wellicht handig vindt om mee te werken als je je professionele web ontwikkelaar carrière start. +In dit onderdeel leert u welke applicaties u wellicht handig vindt om mee te werken als u uw professionele web ontwikkelaar carrière start. Een **ontwikkelomgeving** is een unieke set van applicaties wat een ontwikkelaar regelmatig gebruikt om software te schrijven. Sommige van deze applicaties zijn aangepast voor de specifieke eisen die de ontwikkelaar heeft en kunnen veranderen over de tijd. Dit kan te maken hebben met het type werk wat de ontwikkelaar uitvoert, bijvoorbeeld persoonlijke projecten versus projecten voor werk, of als er een andere programmeertaal moet worden gebruikt. Ontwikkelomgevingen zijn zo uniek als de ontwikkelaars die ze gebruiken. ### Editors -Een van de meest cruciale applicaties voor software ontwikkeling is de code editor. In een editor schrijf je je code en soms run je daar ook je code. +Een van de meest cruciale applicaties voor software ontwikkeling is de code editor. In een editor schrijft u uw code en soms runt u daar ook uw code. Ontwikkelaars gebruiken editors ook om de volgende redenen: -- *Debugging* Het regel voor regel runnen van je code om bugs te ontdekken. Sommige editors hebben debugging mogelijkheden, of kunnen aangepast worden voor specifieke programmeertalen. -- *Syntax markering* Voegt kleuren en tekst opmaak toe aan code om het leesbaarder te maken. De meeste editors hebben de mogelijkheid om dit aan te passen naar je eigen smaak. +- *Debugging* Het regel voor regel runnen van uw code om bugs te ontdekken. Sommige editors hebben debugging mogelijkheden, of kunnen aangepast worden voor specifieke programmeertalen. +- *Syntax markering* Voegt kleuren en tekst opmaak toe aan code om het leesbaarder te maken. De meeste editors hebben de mogelijkheid om dit aan te passen naar uw eigen smaak. - *Extensies en Integraties* Uitbreidingen van de editor, speciaal voor ontwikkelaars en gemaakt door ontwikkelaars, om extra functionaliteiten toe te voegen die standaard niet in de editor inzitten. Bijvoorbeeld een spellingscontrole extensie wat documentatie kan controleren op spelfouten. Vaak zijn extensies ontwikkeld voor een specifieke code editor. De meeste editors bieden een zoekfunctie om relevante extensies te vinden. - *Persoonlijke instellingen* De meeste editors hebben instellingen die volledig aan te passen zijn naar de wens van de ontwikkelaar. Elke ontwikkelaar zal daarom een unieke ontwikkelomgeving hebben wat voldoet aan hun specifieke wensen. @@ -131,11 +131,11 @@ Veel browsers hebben ingebouwd *ontwikkel gereedschap* (DevTools) waarmee ontwik ### Command Line Applicaties -Sommige ontwikkelaars hebben de voorkeur om minder grafische applicaties te gebruiken voor hun dagelijks werk. Zij gebruiken *command line applicaties* om hun werk te doen. Voor het schrijven van code is veel typewerk nodig, en aangezien sommige ontwikkelaars niet teveel afgeleid willen worden in hun keyboardgebruik maken zij daarom gebruik van keyboard shortcuts om bijvoorbeeld met verschillende bestanden te werken en tussen applicaties te wisselen. De meeste taken kunnen met een muis worden uitgevoerd, maar één van de voordelen van de command line is dat je heel veel kunt doen zonder te wisselen van keyboard en muis. Een bijkomend voordeel is dat command line applicaties aanpasbaar zijn en je deze naar wens kunt instellen. De instellingen kunnen opgeslagen worden op een andere computer weer herbruikt worden. Omdat elke ontwikkelaar een andere voorkeur heeft qua ontwikkelomgeving, gebruiken sommigen de command line nooit, sommigen doen juist alles ermee, en anderen gebruiken zowel de command line als grafische applicaties. +Sommige ontwikkelaars hebben de voorkeur om minder grafische applicaties te gebruiken voor hun dagelijks werk. Zij gebruiken *command line applicaties* om hun werk te doen. Voor het schrijven van code is veel typewerk nodig, en aangezien sommige ontwikkelaars niet teveel afgeleid willen worden in hun keyboardgebruik maken zij daarom gebruik van keyboard shortcuts om bijvoorbeeld met verschillende bestanden te werken en tussen applicaties te wisselen. De meeste taken kunnen met een muis worden uitgevoerd, maar één van de voordelen van de command line is dat u heel veel kunt doen zonder te wisselen van keyboard en muis. Een bijkomend voordeel is dat command line applicaties aanpasbaar zijn en u deze naar wens kunt instellen. De instellingen kunnen opgeslagen worden op een andere computer weer herbruikt worden. Omdat elke ontwikkelaar een andere voorkeur heeft qua ontwikkelomgeving, gebruiken sommigen de command line nooit, sommigen doen juist alles ermee, en anderen gebruiken zowel de command line als grafische applicaties. ### Populaire Command Lines -Beschikbaarheid van command lines verschilt op basis van het besturingssysteem wat je gebruikt. +Beschikbaarheid van command lines verschilt op basis van het besturingssysteem wat u gebruikt. *💻 = is geïnstalleerd met het besturingssysteem.* @@ -173,7 +173,7 @@ Wanneer een ontwikkelaar iets nieuws wil leren dan zullen ze waarschijnlijk de b - [Mozilla Developer Network](https://developer.mozilla.org/docs/Web) - [Frontend Masters](https://frontendmasters.com/learn/) -✅ Doe wat onderzoek: Nu je de basis weet van de omgeving van een web ontwikkelaar, probeer eens uit te zoeken in hoeverre dit verschilt van een omgeving voor een web designer. +✅ Doe wat onderzoek: Nu u de basis weet van de omgeving van een web ontwikkelaar, probeer eens uit te zoeken in hoeverre dit verschilt van een omgeving voor een web designer. --- @@ -186,7 +186,7 @@ Vergelijk wat programmeertalen. Wat zijn unieke kenmerken van JavaScript vs. Jav ## Review & Zelfstudie -Bestudeer wat voor verschillende programmeertalen er zijn. Zoek in 3 talen een 'Hello World' voorbeeld op. Zo krijg je een goed idee wat er voor nodig is om tekst in de browser te tonen. +Bestudeer wat voor verschillende programmeertalen er zijn. Zoek in 3 talen een 'Hello World' voorbeeld op. Zo krijgt u een goed idee wat er voor nodig is om tekst in de browser te tonen. ## Opdracht diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-cn.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-cn.md new file mode 100644 index 00000000..240028e1 --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-cn.md @@ -0,0 +1,192 @@ +# 编程语言概述与工具介绍 + +这节课涵盖了编程语言的基础知识,涉及到的内容适用于如今大多数现代编程语言。在“工具介绍”部分,你会了解到一些对开发者很有用的软件。 + + +> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac) + +## 课前小测 +[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/1?loc=zh_cn) + +## 大纲 + +这节课我们将会介绍: + +- 什么是编程? +- 编程语言的种类 +- 程序的基本要素 +- 对专业开发者很有用的软件和工具 + +## 什么是编程? + +编程(programming) ,俗称写代码(coding),是向诸如计算机或移动设备之类的设备写入指令的过程。我们使用编程语言来编写这些指令,然后交由设备去解释(interpret)。这些指令的集合有许多叫法,常见的有*程序(program)*、*计算机程序(computer program)*、*应用程序(application / app)*和*可执行文件(executable)*。 + +*程序*可以是任何由代码编写的东西,比如网站、游戏和手机应用。尽管的确有办法不编写任何代码就创建一个程序,但是设备还是会去解析其底层逻辑,这个逻辑大概率是由代码编写的。所谓*正在运行*或是*执行代码*的程序所做的其实都是执行指令。你现在用来阅读这段文字的设备,也正在运行一个将文字输出到你的屏幕上的程序。 + +✅ 查一查:谁被认为是世界上第一位计算机程序员? + +## 编程语言 + +编程语言的主要目的是:让开发者可以构建指令并将它们传递给设备。设备只能理解二进制(一堆 0 和 1),这对*大多数*开发者来说实在不算是高效的交流方式,而编程语言正是人类与计算机之间沟通的桥梁。 + +编程语言有着不同的形式,也可能用于不同的目的。比如 JavaScript 主要用于 Web 应用,而 Bash 则主要用于操作系统。 + +对于设备来说看,解释*低级语言(low level languages)*的指令一般会比解释*高级语言(high level languages)*的指令需要更少的步骤。然而,高级语言因为其可读性和兼容性会更加常用。JavaScript 就是一种高级语言。 + +下面的代码展示了高级语言(以 JavaScript 为例)和低级语言(以 ARM 汇编代码为例)的区别: + +```javascript +let number = 10 +let n1 = 0, n2 = 1, nextTerm; + +for (let i = 1; i <= number; i++) { + console.log(n1); + nextTerm = n1 + n2; + n1 = n2; + n2 = nextTerm; +} +``` + +```c + area ascen,code,readonly + entry + code32 + adr r0,thumb+1 + bx r0 + code16 +thumb + mov r0,#00 + sub r0,r0,#01 + mov r1,#01 + mov r4,#10 + ldr r2,=0x40000000 +back add r0,r1 + str r0,[r2] + add r2,#04 + mov r3,r0 + mov r0,r1 + mov r1,r3 + sub r4,#01 + cmp r4,#00 + bne back + end +``` + +不管你信不信,*它们做的事完全相同*:打印斐波那契数列的前 10 位。 + +✅ [斐波那契数列](https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97)是一个由 0 和 1 开头,每个数字都是它之前两个数字之和的数列。 + +## 程序的基本要素 + +程序中的单条指令(instruction)被称作*语句(statement)*,常用一个字符或是空行来标识指令结束的位置,这种标识可被称为*终止符(terminates)*。程序的结束方式也因语言而异。 + +多数程序都需要用到从用户或其他地方获取到的数据(data),此时语句会根据这些数据来执行指令。数据会改变程序的行为,所以编程语言提供了一种临时存储此后会被用到的数据的方法。这些数据被称作*变量(variables)*。变量也是语句,用来指示设备将数据存到它的内存中。和代数学中的变量类似,程序中的变量也有独立的命名,其值在之后也可能发生改变。 + +有的语句可能不会被设备执行,这通常是开发者有意为之,否则就是发生了意外的错误。这样的控制可以让应用程序更加稳定和可维护。一般来说这些控制的切换会在满足特定条件的情况下发生。`if..else` 语句就是一个在现代编程语言中常见的用于控制程序的语句。 + +✅ 你会在此后的课程中学到更多关于此类语句的知识 + +## 工具介绍 + +[](https://youtube.com/watch?v=69WJeXGBdxg "工具介绍") + +在这一部分,你将会了解到一些能在你的专业开发之旅中颇有帮助的软件。 + +**开发环境(development environment)** 指的是一位开发者自己在编写软件时常会用到的工具和功能的集合。其中一些工具会按照开发者的特定需求被自定义配置,这些工具集也会随着时间发生变化,原因可能是开发者在工作或个人项目中改变了需求的优先级,抑或是切换到了另一种编程语言。开发环境往往因人而异。 + +### 编辑器 + +编辑器(Editors)是软件开发中最关键的工具之一,是你用来编写甚至运行你的代码的地方。 + +开发者选用编辑器还有这些原因: + +- *调试(Debugging)* 通过逐步或逐行地运行代码来发现漏洞和错误。一些编辑器自身带有调试功能,或者可以被自定义添加对特定编程语言的调试功能。 +- *语法高亮(Syntax highlighting)* 为代码添加颜色和文本格式以便阅读。多数编辑器都可以对语法高亮进行自定义。 +- *插件和集成(Extensions and Integrations)* 开发者可以根据自身需要为编辑器添加其原生本不包含的功能。比如,许多开发者需要为代码撰写文档来解释其工作原理,就会安装一个拼写检查插件来检查有没有拼写错误。多数插件都只支持特定的编辑器,多数编辑器也会提供搜索可用插件的方法。 +- *自定义(Customization)* 多数编辑器都是高度可自定义的,每一位开发者都能根据自身需要来自定义自己的开发环境。许多开发者还会编写自己的插件。 + +#### 主流编辑器和 Web 开发插件 + +- [Visual Studio Code](https://code.visualstudio.com/) + - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) + - [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) + - [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [Atom](https://atom.io/) + - [spell-check](https://atom.io/packages/spell-check) + - [teletype](https://atom.io/packages/teletype) + - [atom-beautify](https://atom.io/packages/atom-beautify) + +### 浏览器 + +另一个关键工具是浏览器。Web 开发者需要用浏览器来观察它们的代码如何在网页上运行,还可以看到编辑器中编写的元素(如 HTML 元素)如何展现在网页上。 + +许多浏览器都提供了*开发者工具*(DevTools),包括一系列有用的功能和信息,用以辅助开发者收集和捕获它们应用程序的重要信息。例如当网页发生错误时,获知错误是何时发生的有助于帮助解决错误,而浏览器 DevTools 就可以被配置来捕获这个信息。 + +#### 主流浏览器和 DevTools + +- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium?WT.mc_id=academic-13441-cxa) +- [Chrome](https://developers.google.com/web/tools/chrome-devtools/) +- [Firefox](https://developer.mozilla.org/docs/Tools) + +### 命令行工具(Command Line Tools) + +一些开发者更喜欢使用较少的图形化界面来执行日常任务,因此选择使用命令行。开发代码需要大量的文字输入,一些开发者不喜欢自己在键盘上的工作流被打断,会使用键盘快捷键来切换桌面窗口、切换工作文件、使用工具等。大多数任务都可以通过鼠标完成,而使用命令行的一个好处就是无需再鼠标和键盘之间切换就能完成多数工作。命令行的另一个好处是它们是可配置的,所以你可以保存你的配置并随时修改,还可以将其导入到新的开发设备上。但开发环境毕竟因人而异,有人完全不想用命令行,有人则希望在命令行做所有事,还有一些人两种方式都乐意接受。 + +### 常用命令行选择 + +命令行选择基于你使用的操作系统会有所不同。 + +*💻 表示会预装在对应操作系统上* + +#### Windows + +- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7?WT.mc_id=academic-13441-cxa) 💻 +- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands?WT.mc_id=academic-13441-cxa) (即 CMD) 💻 +- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-13441-cxa) +- [mintty](https://mintty.github.io/) + +#### MacOS + +- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻 +- [iTerm](https://iterm2.com/) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### Linux + +- [Bash](https://www.gnu.org/software/bash/manual/html_node/index.html) 💻 +- [KDE Konsole](https://docs.kde.org/trunk5/en/applications/konsole/index.html) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### 常用命令行工具 + +- [Git](https://git-scm.com/) (💻 <- 在多数操作系统上) +- [NPM](https://www.npmjs.com/) +- [Yarn](https://classic.yarnpkg.com/en/docs/cli/) + +### 文档 + +当一位开发者想要学点新东西,他们基本都会去找文档(Documentation)来学习如何使用。开发者会依靠文档来指引他们如何合理地使用工具和语言,并且从中获取更多关于实现原理的深层知识。 + +#### Web 开发常用文档 + +- [Mozilla Developer Network](https://developer.mozilla.org/docs/Web) +- [Frontend Masters](https://frontendmasters.com/learn/) + +✅ 查一查:既然你已经对 Web 开发者的环境有所了解,何不比较一下其与 Web 设计师的环境的差异? + +--- + +## 🚀 挑战 + +比较一些编程语言。JavaScript 和 Java 相互之间有什么独特的特征?COBOL 和 Go 之间呢? + +## 课后小测 +[课后小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/2?loc=zh_cn) + +## 复习 & 自学 + +尝试接触一些不同的编程语言,用一种语言写一行代码,然后用另外两种语言重写这一行代码,你有什么感悟吗? + +## 作业 + +[阅读文档](assignment.zh-cn.md) diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-tw.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-tw.md new file mode 100644 index 00000000..29b71a3e --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/README.zh-tw.md @@ -0,0 +1,193 @@ +# 程式語言概論與必備工具 + +這堂課程解釋程式語言的基礎。這項主題能應用到當代多數的程式語言。關於必備工具的部分,你會學到許多實用的開發者軟體。 + + +> 由[Tomomi Imura](https://twitter.com/girlie_mac) 繪製。 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/1?loc=zh_tw) + +## 大綱 + +在這堂課中,包含: + +- 什麼是程式設計? +- 程式語言的種類 +- 程式的基本架構 +- 給專業開發者的實用軟體與工具 + +## 什麼是程式設計? + +程式設計,又稱作Coding,是編寫電腦或手機裝置的指令過程。我們以裝置看得懂的程式語言來編寫這些指令,這些指令集涉及到常見的*程式*、*電腦程式*、*應用程式(App)*或*執行檔*。 + +一個*程式*以程式碼任意創作出來,網頁、遊戲、手機應用都是程式的一種。雖然我們可以在不編寫程式碼的情況下建出程式,但裝置底下的邏輯概念還是以程式碼為主。一個*執行中*、*執行編碼*的程式都是仰賴著指令。你眼前正閱讀的文字就是由程式輸出到螢幕。 + +✅ 課外研究: 誰被認為是世界上第一位電腦工程師? + +## 撰寫程式語言 + +編寫程式語言的主要目的是讓開發者得以指示裝置。裝置只能讀懂二元格式 ( 1 與 0 ),對於*大多數*的開發者而言,這並不是個很好理解溝通的方式。程式語言就像人類與電腦之間溝通的橋梁。 + +程式語言有不同的格式與滿足的目的。舉例來說,JavaScript 常被用在網頁應用上,而 Bash 主要是用在作業系統上。 + +*低階語言(Low level languages)* 通常比 *高階語言(high level languages)* 要求更少的裝置指示步數。然而,高階語言的閱讀性與支援性讓它成為最普及的程式語言。JavaScript 即是一種高階語言。 + +下列程式碼說明高階語言(JavaScript)與低階語言(ARM assembly code)的差異: + +```javascript +let number = 10 +let n1 = 0, n2 = 1, nextTerm; + +for (let i = 1; i <= number; i++) { + console.log(n1); + nextTerm = n1 + n2; + n1 = n2; + n2 = nextTerm; +} +``` + +```c + area ascen,code,readonly + entry + code32 + adr r0,thumb+1 + bx r0 + code16 +thumb + mov r0,#00 + sub r0,r0,#01 + mov r1,#01 + mov r4,#10 + ldr r2,=0x40000000 +back add r0,r1 + str r0,[r2] + add r2,#04 + mov r3,r0 + mov r0,r1 + mov r1,r3 + sub r4,#01 + cmp r4,#00 + bne back + end +``` + +事實上,*他們都做一樣的事情* ── 印出前十項費氏數列。 + +✅ 費氏數列的[定義](https://zh.wikipedia.org/zh-tw/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97)為該數是由之前的兩數相加而得出。初始值為 0 與 1。 + +## 程式的基本架構 + +程式中的一行指令(instruction)被稱做*陳述式(statement)*,通常會由特定符號或分行來決定結尾處,或是執行*程式終止*。程式終止的方式會依不同程式語言而有所不同。 + +大多數程式需要使用用戶或其他位置的資料,陳述式依照這些資料決定指令。資料會影響程式的運作方式,編寫程式語言便是一種暫時性儲存資料的途徑。這些資料稱為*變數(Variables)*。變數會指引資料儲存到裝置上的位置,它們就像代數一樣:有自己的名稱、數值隨時間改變。 + +有些情況裝置不會執行到陳述式。通常是開發者故意的選擇或意外性地輸入錯誤,讓應用程式變得更豐富且需要被維護。常見的發生情況在決定條件的時候,如當代程式語言以 `if..else` 條件式來決定程式的執行方式。 + +✅ 往後的課程會講解各式各樣的陳述式型態。 + +## 工欲善其事,必先利其器 + +[](https://youtube.com/watch?v=69WJeXGBdxg "謀生工具 Tools of the Trade") + +在這個章節,你會學習到一些實用的軟體來開始你的開發旅程。 + +一個**開發環境**包含許多開發者撰寫程式需要用到的工具。它們會依照開發者的需求而不同,隨著時間、專案大小、程式語言而有所調整。每個開發者都有自己獨特的開發環境。 + +### 文字編輯器 + +文字編輯器可說是最重要的軟體開發工具。開發者可以在其中撰寫並執行程式。 + +還有許多原因讓開發者選擇文字編輯器: + +- *偵錯(Debugging)* 在程式碼中一行一行地找尋錯誤。有些文字編輯器有偵錯的功能,可以依照不同的程式語言而調整。 +- *語法突顯(Syntax highlighting)* 將程式碼加上顏色並自動排版,方便開發者閱讀。文字編輯器也支援語法突顯的客製化。 +- *整合擴充插件(Extensions and Integrations)* 擴充插件不包含在預設的文字編輯器當中,開發者依照自己的需求建立並新增到文字編輯器當中。舉例來說,許多開發者需要統整程式文檔並註解這些檔案,他們就會加裝檢查拼字的插件。有些插件功能只支援特定的文字編輯器,文字編輯器也提供搜尋擴充插件的功能。 +- *客製化(Customization)* 大多數的文字編輯器都允許開發者做客製化,開發者依照自己的習慣,建立自己順手的開發環境。其中也包含建立自己的擴充插件。 + +#### 常見文字編輯器與網頁開發插件 + +- [Visual Studio Code](https://code.visualstudio.com/) + - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) + - [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) + - [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [Atom](https://atom.io/) + - [spell-check](https://atom.io/packages/spell-check) + - [teletype](https://atom.io/packages/teletype) + - [atom-beautify](https://atom.io/packages/atom-beautify) + +### 瀏覽器 + +另一款重要的工具是瀏覽器。網頁開發人員會藉由瀏覽器觀察程式的執行情況,瀏覽器也是常見的網頁編輯與檢視器,顯示來自檔案的可見物件,如 HTML 檔。 + +許多瀏覽器都附加*開發者工具(DevTools)*,內含實用的功能協助開發者蒐集與取得重要的程式資訊。假設有一頁網頁出現錯誤,了解它出錯的時間與狀況就很重要,配置開發者工具即可蒐集這些資訊。 + +#### 常見瀏覽器與網頁開發工具 + +- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium?WT.mc_id=academic-13441-cxa) +- [Chrome](https://developers.google.com/web/tools/chrome-devtools/) +- [Firefox](https://developer.mozilla.org/docs/Tools) + +### 常用指令 + +有些開發者偏好較少的介面,通常會使用指令來完成工作;撰寫程式碼要求大量的文字輸入,有些開發者偏好以不中斷文字輸入為首要條件,常用快捷鍵做視窗與檔案的切換。多數工作能以滑鼠操作,但為了減少鍵盤與滑鼠間的切換,指令輸入會是實踐上較合適的方式。另一項指令輸入的好處是它們彈性很高,隨時可以更新設定,甚至移植到其他機器上。每一位開發者有各自的開發習慣,開發環境也有所不同。 + +### 常用指令選項 + +指令選項(Command Line Options)會依不同的作業系統而有所不同。 + +*💻 表示預設已安裝在作業系統上。* + +#### Windows + +- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7?WT.mc_id=academic-13441-cxa) 💻 +- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands?WT.mc_id=academic-13441-cxa) (又稱作 CMD) 💻 +- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-13441-cxa) +- [mintty](https://mintty.github.io/) + +#### MacOS + +- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻 +- [iTerm](https://iterm2.com/) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### Linux + +- [Bash](https://www.gnu.org/software/bash/manual/html_node/index.html) 💻 +- [KDE Konsole](https://docs.kde.org/trunk5/en/applications/konsole/index.html) +- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7?WT.mc_id=academic-13441-cxa) + +#### 其他常用指令 + +- [Git](https://git-scm.com/) (💻 已支援大多數的作業系統。) +- [NPM](https://www.npmjs.com/) +- [Yarn](https://classic.yarnpkg.com/en/docs/cli/) + +### 技術文件 + +若開發人員想學新的事物,技術文件會是很好的幫手。他們會參照文件來學習如何使用工具與新的程式語言,並瞭解如何鑽研更深入的用法。 + +#### 常用的網頁開發文件 + +- [Mozilla Developer Network](https://developer.mozilla.org/docs/Web) +- [Frontend Masters](https://frontendmasters.com/learn/) + +✅ 研究項目: 現在你已經了解基本的網頁開發環境了。請比較「網頁開發環境」與「網頁設計環境」之間的差異。 + +--- + +## 🚀 挑戰 + +比較不同的程式語言: JavaScript 與 Java 間有什麼獨特的特徵? 那 COBOL 與 Go 呢? + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/2?loc=zh_tw) + +## 複習與自學 + +學習不同的程式語言。試著在三種不同的程式語言寫幾行程式碼。你學到了什麼? + +## 作業 + +[閱讀技術文件](assignment.zh-tw.md) + diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.fr.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.fr.md new file mode 100644 index 00000000..6deab32e --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.fr.md @@ -0,0 +1,11 @@ +# Lire la documentation + +## Instructions + +Un développeur Web peut avoir besoin de nombreux outils qui se trouvent sur le [Documentation MDN pour l'outillage côté client](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Sélectionnez 3 outils non traités dans la leçon, expliquez pourquoi un développeur Web l'utiliserait, recherchez un outil qui relève de cette catégorie et partagez sa documentation. N'utilisez pas le même exemple d'outil sur les documents MDN. + +## Rubrique + +Exemplaire | Adéquat | A besoin d'amélioration +--- | --- | -- | +| Expliqué pourquoi le développeur Web utiliserait l'outil | Expliqué comment, mais pas pourquoi le développeur utiliserait l'outil | N'a pas mentionné comment ou pourquoi un développeur utiliserait l'outil | \ No newline at end of file diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.gr.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.gr.md index 8e05de68..0929d7f8 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.gr.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.gr.md @@ -2,7 +2,7 @@ ## Οδηγίες -Υπάρχουν πολλά εργαλεία που μπορεί να χρειαστεί ένας web developer και τα οποία βρίσκονται στο [MDN έγγραφα για client-side tooling](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Επιλέξτε 3 εργαλεία που δεν αναφέρονται στο μάθημα, εξηγήστε γιατί θα τα χρησιμοποιούσε ένας web developer, αναζητήστε ένα εργαλείο που ανήκει σε αυτήν την κατηγορία και μοιραστείτε την τεκμηρίωσή σας. Μην χρησιμοποιήσετε το ίδιο παράδειγμα εργαλείου που αναφέρεται στα έγγραφα MDN. +Υπάρχουν πολλά εργαλεία που μπορεί να χρειαστεί ένας web developer και τα οποία βρίσκονται στο [MDN έγγραφα για client-side tooling](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Επιλέξτε 3 εργαλεία που δεν αναφέρονται στο μάθημα, εξηγήστε γιατί θα τα χρησιμοποιούσε ένας web developer, αναζητήστε ένα εργαλείο που ανήκει σε αυτήν την κατηγορία και μοιραστείτε την τεκμηρίωσή σας. Μην χρησιμοποιήσετε το ίδιο παράδειγμα εργαλείου που αναφέρεται στα έγγραφα MDN. ## diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.hi.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.hi.md index ded90c34..8c73b4be 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.hi.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.hi.md @@ -2,7 +2,7 @@ ## अनुदेश -ऐसे कई उपकरण हैं जिनकी आवश्यकता वेब डेवलपर को हो सकती है जो [एमडीएन प्रलेखन के क्लाइंट-साइड टूलिंग](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview) पे उपलब्ध है । पाठ में शामिल नहीं किए गए 3 टूल चुनें, बताएं कि एक वेब डेवलपर इसका उपयोग क्यों करेगा, और इस टूल के लिए खोज करेगा जो इस श्रेणी में आता है और इसके प्रलेखन को साझा करता है । MDN डॉक्स पर समान टूल उदाहरण का उपयोग न करें. +ऐसे कई उपकरण हैं जिनकी आवश्यकता वेब डेवलपर को हो सकती है जो [एमडीएन प्रलेखन के क्लाइंट-साइड टूलिंग](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview) पे उपलब्ध है । पाठ में शामिल नहीं किए गए 3 टूल चुनें, बताएं कि एक वेब डेवलपर इसका उपयोग क्यों करेगा, और इस टूल के लिए खोज करेगा जो इस श्रेणी में आता है और इसके प्रलेखन को साझा करता है । MDN डॉक्स पर समान टूल उदाहरण का उपयोग न करें. ## सरनामा diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.id.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.id.md index a9d0ece7..870ed91d 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.id.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.id.md @@ -2,7 +2,7 @@ ## Instruksi -Ada banyak alat yang mungkin diperlukan pengembang web yang ada di [dokumentasi MDN untuk alat sisi klien](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview) . Pilih 3 alat yang tidak tercakup dalam pelajaran, jelaskan mengapa pengembang web akan menggunakannya, dan cari alat yang termasuk dalam kategori ini dan bagikan dokumentasinya. Jangan gunakan contoh alat yang sama pada dokumen MDN. +Ada banyak alat yang mungkin diperlukan pengembang web yang ada di [dokumentasi MDN untuk alat sisi klien](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview) . Pilih 3 alat yang tidak tercakup dalam pelajaran, jelaskan mengapa pengembang web akan menggunakannya, dan cari alat yang termasuk dalam kategori ini dan bagikan dokumentasinya. Jangan gunakan contoh alat yang sama pada dokumen MDN. ## Rubrik diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.it.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.it.md index 10da2236..36c8f18d 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.it.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.it.md @@ -2,7 +2,7 @@ ## Istruzioni -Ci sono molti strumenti dei quali uno sviluppatore web potrebbe avere bisogno che non sono nella [documentazione MDN per strumenti lato client](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Selezionare 3 strumenti non trattati nella lezione, spiegare perchè uno sviluppatore web dovrebbe usarli, cercare uno strumento che possa rientrare in questa categoria e condivere la sua documentazione. Non usare lo stesso strumento di esempio citato nei documenti MDN. +Ci sono molti strumenti dei quali uno sviluppatore web potrebbe avere bisogno che non sono nella [documentazione MDN per strumenti lato client](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Selezionare 3 strumenti non trattati nella lezione, spiegare perchè uno sviluppatore web dovrebbe usarli, cercare uno strumento che possa rientrare in questa categoria e condivere la sua documentazione. Non usare lo stesso strumento di esempio citato nei documenti MDN. ## Rubrica diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ja.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ja.md index a5057354..9c18dc8d 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ja.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ja.md @@ -2,7 +2,7 @@ ## 説明書 -Web 開発者が必要とする可能性のあるツールは、[クライアントサイドツールの MDN ドキュメント](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)に記載されているものが多くあります。このレッスンでカバーされていないツールを3つ選び、Web 開発者がそれを使う理由を説明し、このカテゴリに該当するツールを検索し、そのドキュメントを共有してください。同じツールの例を MDN ドキュメント上で使用しないでください。 +Web 開発者が必要とする可能性のあるツールは、[クライアントサイドツールの MDN ドキュメント](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)に記載されているものが多くあります。このレッスンでカバーされていないツールを3つ選び、Web 開発者がそれを使う理由を説明し、このカテゴリに該当するツールを検索し、そのドキュメントを共有してください。同じツールの例を MDN ドキュメント上で使用しないでください。 ## ルーブリック diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ko.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ko.md index 2249bd03..ff32c318 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ko.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ko.md @@ -2,7 +2,7 @@ ## 설명 -웹 개발자들이 필요할 만한 도구들이 [MDN 클라이언트 사이드 도구 문서](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)에 소개되어있습니다. 이번 수업내용에 포함되지 않은 3개의 도구를 선택하고, 왜 웹 개발자들이 사용할만한지를 설명해봅시다. 그리고 이 범주에 속하는 도구를 찾아서 문서를 공유해봅시다. MDN문서에 있는 똑같은 예시를 사용하면 안 됩니다. +웹 개발자들이 필요할 만한 도구들이 [MDN 클라이언트 사이드 도구 문서](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)에 소개되어있습니다. 이번 수업내용에 포함되지 않은 3개의 도구를 선택하고, 왜 웹 개발자들이 사용할만한지를 설명해봅시다. 그리고 이 범주에 속하는 도구를 찾아서 문서를 공유해봅시다. MDN문서에 있는 똑같은 예시를 사용하면 안 됩니다. ## 평가 기준 diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ms.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ms.md index c687eb01..13a6d9c4 100644 --- a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ms.md +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.ms.md @@ -1,7 +1,7 @@ # Membaca Docs ## Arahan -Terdapat banyak alat yang mungkin diperlukan oleh pembangun web adalah di [Dokumentasi MDN untuk perkakas sisi pelanggan](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Pilih 3 alat yang tidak diliputi dalam pelajaran, terangkan mengapa pembangun web menggunakannya, dan mencari alat yang terdapat dalam kategori ini dan kongsikan dokumentasinya. Jangan menggunakan contoh alat yang sama pada MDN. +Terdapat banyak alat yang mungkin diperlukan oleh pembangun web adalah di [Dokumentasi MDN untuk perkakas sisi pelanggan](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Pilih 3 alat yang tidak diliputi dalam pelajaran, terangkan mengapa pembangun web menggunakannya, dan mencari alat yang terdapat dalam kategori ini dan kongsikan dokumentasinya. Jangan menggunakan contoh alat yang sama pada MDN. ## Rubrik diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.nl.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.nl.md new file mode 100644 index 00000000..157eb54d --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# De Documenten lezen + +## Instructies + +Er zijn veel tools die een webontwikkelaar nodig heeft en die staan in de [MDN-documentatie voor client-side tooling](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Selecteer 3 tools die niet in de les worden behandeld, leg uit waarom een webontwikkelaar deze zou gebruiken en zoek naar een tool die onder deze categorie valt en deel de documentatie ervan. Gebruik niet hetzelfde toolvoorbeeld voor MDN-documenten. + +## Rubriek + +Voorbeeldig | Voldoende | Moet Worden Verbeterd +--- | --- | -- | +|Uitgelegd waarom webontwikkelaar een tool zou gebruiken| Uitgelegd hoe, maar niet waarom de ontwikkelaar de tool zou gebruiken| Niet vermeld hoe of waarom een ontwikkelaar een tool zou gebruiken | \ No newline at end of file diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-cn.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-cn.md new file mode 100644 index 00000000..cba5ab16 --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-cn.md @@ -0,0 +1,11 @@ +# 阅读文档 + +## 说明 + +[MDN 客户端工具文档](https://developer.mozilla.org/zh-CN/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)中介绍了需要 Web 开发者可能需要用到的工具。从中选取三种本节课中没有提到的工具,并说明为什么 Web 开发者需要用到它们,搜索其中一种工具并给出它的文档。不要直接使用 MDN 中给出的示例。 + +## 评价表 + +| 优秀 | 良好 | 尚可进步 | +| --- | --- | -- | +| 解释了 Web 开发者为什么需要这些工具 | 解释了开发者如何使用这些工具,但却没有解释为什么需要它们 | 既没有解释为什么使用这些工具,也没有给出使用它们的方法 | diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-tw.md b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-tw.md new file mode 100644 index 00000000..ff989c4e --- /dev/null +++ b/1-getting-started-lessons/1-intro-to-programming-languages/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 閱讀技術文件 + +## 說明 + +網頁開發人員所需要使用的工具套件可以參考 [MDN Client端技術開發文件](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview)。 請選擇三種未被本課程提及的工具,試解釋為何網頁開發人員使用它,並搜尋其相關的工具與它的技術文件。這些資料不能出現在前述的 MDN 文件當中。 + +## 學習評量 + +| 優良 | 普通 | 待改進 | +| ------------------------------ | -------------------- | ------------------------------ | +| 解釋為何網頁開發人員會用此工具 | 只解釋工具的使用方法 | 未提及工具的使用意義與使用方法 | \ No newline at end of file diff --git a/1-getting-started-lessons/2-github-basics/README.md b/1-getting-started-lessons/2-github-basics/README.md index 0b89459c..9f7645ac 100644 --- a/1-getting-started-lessons/2-github-basics/README.md +++ b/1-getting-started-lessons/2-github-basics/README.md @@ -2,7 +2,7 @@ This lesson covers the basics of GitHub, a platform to host and manage changes to your code. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz diff --git a/1-getting-started-lessons/2-github-basics/translations/README.es.md b/1-getting-started-lessons/2-github-basics/translations/README.es.md index 826f4d38..48dee394 100644 --- a/1-getting-started-lessons/2-github-basics/translations/README.es.md +++ b/1-getting-started-lessons/2-github-basics/translations/README.es.md @@ -1,6 +1,9 @@ # Introducción a GitHub -Esta lección cubre los conceptos básicos de GitHub, una plataforma para alojar y administrar cambios en su código. +Esta lección cubre los conceptos básicos de GitHub, una plataforma para alojar y administrar cambios en tu código. + + +> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/3) @@ -8,64 +11,64 @@ Esta lección cubre los conceptos básicos de GitHub, una plataforma para alojar En esta lección, cubriremos: -- seguimiento del trabajo que realiza en su máquina +- dando seguimiento al trabajo que realizas en tu máquina - trabajar en proyectos con otros -- cómo contribuir al software de código abierto +- cómo contribuir al software de código abierto (open source) ### Prerrequisitos -Antes de comenzar, deberá verificar si Git está instalado. En el tipo de terminal: +Antes de comenzar, verifica si Git está instalado. Escribe en tu terminal: `git --version` -Si Git no está instalado, [descargar Git](https://git-scm.com/downloads). Luego, configure su perfil de Git local en la terminal: +Si Git no está instalado, [descarga Git aquí](https://git-scm.com/downloads). Luego, configura tu perfil de Git local en la terminal: `git config --global user.name "tu-nombre"` `git config --global user.email "tu-email"` -Para comprobar si Git ya está configurado, puede escribir: +Para comprobar si Git ya está configurado, escribe: `git config --list` -También necesitará una cuenta de GitHub, un editor de código (como Visual Studio Code) y deberá abrir su terminal (o: símbolo del sistema). +También necesitarás una cuenta de GitHub, un editor de código (como Visual Studio Code) y deberás abrir tu terminal. -Vaya a [github.com](https://github.com/) y cree una cuenta si aún no lo ha hecho, o inicie sesión y complete su perfil. +Ve a [github.com](https://github.com/) y crea una cuenta si aún no lo has hecho, o inicia sesión y completa tu perfil. ✅ GitHub no es el único repositorio de código del mundo; hay otros, pero GitHub es el más conocido. ### Preparación -Necesitará una carpeta con un proyecto de código en su máquina local (computadora portátil o PC) y un repositorio público en GitHub, que le servirá como ejemplo de cómo contribuir a los proyectos de otros. +Necesitarás una directorio con un proyecto de código en tu máquina local (computadora portátil o PC) y un repositorio público en GitHub, que te servirá como ejemplo de cómo contribuir a los proyectos de otros. --- ## Gestión de código -Digamos que tiene una carpeta localmente con algún proyecto de código y desea comenzar a rastrear su progreso usando git, el sistema de control de versiones. Algunas personas comparan el uso de git con escribir una carta de amor a su yo futuro. Al leer sus mensajes de confirmación días, semanas o meses después, podrá recordar por qué tomó una decisión o "revertir" un cambio, es decir, cuando escribe buenos "mensajes de confirmación". +Digamos que tienes una directorio local con algún proyecto de código y deseas rastrear tu progreso usando git, el sistema de control de versiones. Algunas personas comparan el uso de git con escribir una carta de amor a tu futuro. Al leer tus mensajes de confirmación días, semanas o meses después, podrás recordar por qué tomaste una decisión o "revertiste" un cambio, es decir, cuando escribes buenos "mensajes de confirmación". -### Tarea: hacer un repositorio y enviar código +### Tarea: hacer un repositorio git y enviar código -1. **Crear repositorio en GitHub**. En GitHub.com, en la pestaña de repositorios, o en la barra de navegación superior derecha, busque el botón **nuevo repositorio**. +1. **Crear repositorio en GitHub**. En GitHub.com, en la pestaña de repositorios, o en la barra de navegación superior derecha, busca el botón **nuevo repositorio**. - 1. Dale un nombre a tu repositorio (carpeta) - 1. Seleccione **crear repositorio**. + 1. Dale un nombre a tu repositorio (directorio) + 1. Selecciona **crear repositorio**. -1. **Navegue a su carpeta de trabajo**. En su terminal, cambie a la carpeta (también conocida como directorio) que desea comenzar a rastrear. Tipo: +1. **Navegue a su directorio de trabajo**. En tu terminal, cambia a la directorio (también conocida como directorio) que deseas comenzar a rastrear. Escribe: ```bash - cd [nombre de tu carpeta] + cd [nombre de tu directorio] ``` -1. **Inicializar un repositorio de git**. En su tipo de proyecto: +1. **Inicializar un repositorio de git**. En tu proyecto escribe: ```bash git init ``` -1. **Comprobar estado**. Para comprobar el estado de su tipo de repositorio: +1. **Comprobar estado**. Para checar el estado del proyecto escribe: ```bash git status ``` - la salida puede verse así: + La respuesta de la terminal (CLI) probablemente se verá así: ```output Changes not staged for commit: @@ -76,7 +79,7 @@ Digamos que tiene una carpeta localmente con algún proyecto de código y desea modified: file2.txt ``` - Por lo general, un comando `git status` le dice cosas como qué archivos están listos para ser guardados en el repositorio o tiene cambios que es posible que desee conservar. + Por lo general, un comando `git status` te dice cosas como qué archivos están listos para ser guardados en el repositorio o cambios en tu codigo que puedes conservar. 1. **Agregar archivos al seguimiento** @@ -84,27 +87,25 @@ Digamos que tiene una carpeta localmente con algún proyecto de código y desea git add . ``` - El argumento `git add` más `.` indica que todos sus archivos y cambios para el seguimiento. + El argumento `git add` más `.` indica que todos tus archivos y cambios están listos para darles seguimiento. -1. **Persistir en tu trabajo**. En este punto, ha agregado los archivos a lo que se denomina _área de preparación_. Un lugar donde Git rastrea sus archivos. Para que el cambio sea permanente, debe _commitir_ los archivos. Para hacerlo, crea un _commit_ con el comando `git commit`. Un _commit_ representa un punto de ahorro en el historial de su repositorio. Escriba lo siguiente para crear un _commit_: +1. **Persistir en tu trabajo**. En este punto, has agregado los archivos a lo que se denomina _área de preparación_. Un lugar donde Git rastrea tus archivos. Para que el cambio sea permanente, debes _commitir_ los archivos. Para hacerlo, creas un _commit_ con el comando `git commit`. Un _commit_ representa un punto en el historial de tu repositorio que estás guardando. Escribe lo siguiente para crear un _commit_: ```bash git commit -m "first commit" ``` - Esto confirma todos sus archivos, agregando el mensaje "primer compromiso". Para futuros mensajes de confirmación, querrá ser más descriptivo en su descripción para transmitir qué tipo de cambio ha realizado. - -1. **Conecte su repositorio de Git local con GitHub**. Un repositorio de Git es bueno en su máquina, pero en algún momento desea tener una copia de seguridad de sus archivos en algún lugar y también invitar a otras personas a trabajar con usted en su repositorio. Un gran lugar para hacerlo es GitHub. Recuerde que ya hemos creado un repositorio en GitHub, por lo que lo único que debemos hacer es conectar nuestro repositorio de Git local con GitHub. El comando `git remote add` hará precisamente eso. Escriba el siguiente comando: + Esto confirma todos tus archivos, agregando el mensaje "primer compromiso". Para futuros mensajes de confirmación, querrás ser más descriptivo en tu descripción para transmitir qué tipo de cambio has realizado. +1. **Conecta tu repositorio de Git local con GitHub**. Es bueno tener un repositorio de Git en tu máquina, pero también tienes que guarder todos sus archivos en algún lugar e invitar a otras personas a trabajar contigo en tu repositorio. Un buen lugar para hacerlo es GitHub. Recuerda que ya hemos creado un repositorio en GitHub, por lo que lo único que debemos hacer es conectar nuestro repositorio de Git local con GitHub. El comando `git remote add` hará precisamente eso. Escribe el siguiente comando: - > Tenga en cuenta que antes de escribir el comando, vaya a la página de su repositorio de GitHub para encontrar la URL del repositorio. Lo usará en el siguiente comando. Reemplaza `repository_name` con tu URL de GitHub. - + > Nota, antes de escribir el comando, ve a la página de tu repositorio de GitHub para encontrar el URL del repositorio. Lo usarás en el siguiente comando. Reemplaza `repository_name` con tu URL de GitHub. ```bash git remote add origin https://github.com/username/repository_name.git ``` - Esto crea un _remote_, o conexión, llamado "origin" que apunta al repositorio de GitHub que creó anteriormente. + Esto crea un _remote_, o conexión, llamado "origin" que apunta al repositorio de GitHub que creaste anteriormente. 1. **Envía archivos locales a GitHub**. Hasta ahora ha creado una _conexión_ entre el repositorio local y el repositorio de GitHub. Enviemos estos archivos a GitHub con el siguiente comando `git push`, así: @@ -113,9 +114,9 @@ Digamos que tiene una carpeta localmente con algún proyecto de código y desea git push -u origin main ``` - Esto envía sus confirmaciones en su rama "principal" a GitHub. + Esto envía una confirmación en tu rama "principal" a GitHub. -1. **Para agregar más cambios**. Si desea continuar haciendo cambios y enviarlos a GitHub, solo necesitará usar los siguientes tres comandos: +1. **Para agregar más cambios**. Si deseas continuar haciendo cambios y enviarlos a GitHub, solo necesitas usar los siguientes tres comandos: ```bash git add . @@ -123,83 +124,84 @@ Digamos que tiene una carpeta localmente con algún proyecto de código y desea git push ``` - > Sugerencia: es posible que también desee adoptar un archivo `.gitignore` para evitar que los archivos que no desea rastrear aparezcan en GitHub, como el archivo de notas que almacena en la misma carpeta pero no tiene lugar para escribir su mensaje de confirmación aquí repositorio público. Puede encontrar plantillas para archivos `.gitignore` en [.gitignore templates](github.com/github/gitignore). + > Sugerencia: es posible que también desees adoptar un archivo `.gitignore` para evitar que los archivos que no deseas rastrear aparezcan en GitHub. Puedes encontrar plantillas para archivos `.gitignore` en [.gitignore templates](github.com/github/gitignore). #### Confirmar mensajes -Una gran línea de asunto de confirmación de Git completa la siguiente oración: +Una buena línea de asunto (subject line) de confirmación de Git completa la siguiente oración: Si se aplica, esta confirmación será <su línea de asunto aquí> -Para el sujeto use el imperativo, tiempo presente: "cambiar" no "cambiar" ni "cambiar". +Para el sujeto use el imperativo, tiempo presente: "cambiar" no "cambió" ni "cambiara". Como en el sujeto, en el cuerpo (opcional) también use el imperativo, presente. El cuerpo debe incluir la motivación para el cambio y contrastarla con la conducta anterior. Estás explicando el "por qué", no el "cómo". ✅ Tómate unos minutos para navegar por GitHub. ¿Puedes encontrar un mensaje de compromiso realmente bueno? ¿Puedes encontrar uno realmente mínimo? ¿Qué información crees que es la más importante y útil de transmitir en un mensaje de compromiso? ### Tarea: Colaborar + La razón principal para poner cosas en GitHub fue hacer posible la colaboración con otros desarrolladores. ## Trabajando en proyectos con otros -En su repositorio, vaya a `Insights > Community` para ver cómo se compara su proyecto con los estándares comunitarios recomendados. +En tu repositorio, ve a `Insights > Community` para ver cómo se compara tu proyecto con los estándares comunitarios recomendados. - Aquí hay algunas cosas que pueden mejorar su repositorio de GitHub: + Aquí hay algunas cosas que pueden mejorar tu repositorio de GitHub: - **Descripción**. ¿Agregaste una descripción para tu proyecto? - **README**. ¿Agregaste un archivo README? GitHub proporciona una guía para escribir un [README](https://docs.github.com/articles/about-readmes/). - - **Pauta de contribución**. ¿Su proyecto tiene [pautas de contribución](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/), - - **Código de Conducta**. un [Código de conducta](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/), - - **Licencia**. Quizás lo más importante, una [licencia](https://docs.github.com/articles/adding-a-license-to-a-repository/)? + - **Guía de contribución**. ¿Tiene [guías de contribución](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/) tu proyecto? + - **Código de Conducta**. Crea un [Código de conducta](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/). + - **Licencia**. Quizás lo más importante, una [licencia](https://docs.github.com/articles/adding-a-license-to-a-repository/). -Todos estos recursos beneficiarán la incorporación de nuevos miembros del equipo. Y esos son típicamente el tipo de cosas que los nuevos colaboradores miran antes incluso de mirar su código, para descubrir si su proyecto es el lugar adecuado para que ellos pasen su tiempo. +Todos estos recursos beneficiarán la incorporación de nuevos miembros del equipo. Y esos son típicamente el tipo de cosas que los nuevos colaboradores miran antes incluso de mirar tu código, para descubrir si tu proyecto es el lugar adecuado para que ellos pasen su tiempo. -✅ Los archivos README, aunque requieren tiempo para prepararse, a menudo son descuidados por los ocupados mantenedores. ¿Puede encontrar un ejemplo de uno particularmente descriptivo? Nota: hay algunas [herramientas para ayudar a crear buenos archivos READMEs](https://www.makeareadme.com/) que le gustaría probar. +✅ Los archivos README, aunque requieren tiempo para prepararse, a menudo son descuidados por los mantenedores. ¿Puedes encontrar un ejemplo de uno particularmente descriptivo? Nota: aquí hay algunas [herramientas para ayudar a crear buenos archivos READMEs](https://www.makeareadme.com/) que te puedes probar. -### Tarea: Fusionar código +### Tarea: Fusionar (merging) código -Los documentos que contribuyen ayudan a las personas a contribuir al proyecto. Explica qué tipos de contribuciones está buscando y cómo funciona el proceso. Los colaboradores deberán seguir una serie de pasos para poder contribuir a su repositorio en GitHub: +Los documentos que contribuyes ayudan a las personas a contribuir al proyecto. Explica qué tipos de contribuciones estás buscando y cómo funciona el proceso. Los colaboradores deberán seguir una serie de pasos para poder contribuir a tu repositorio en GitHub: -1. **Bifurcando su repositorio** Probablemente querrá que la gente _bifurque_ su proyecto. Bifurcar significa crear una réplica de su repositorio en su perfil de GitHub. +1. **Bifurcando (forking) tu repositorio** Probablemente querrás que la gente _bifurque_ (fork) tu proyecto. Bifurcar significa crear una réplica de tu repositorio en su perfil de GitHub. 1. **Clonar**. Desde allí, clonarán el proyecto en su máquina local. -1. **Crea una rama**. Querrá pedirles que creen una _ rama_ para su trabajo. -1. **Concentre su cambio en un área**. Pida a los colaboradores que concentren sus contribuciones en una cosa a la vez; de esa manera, las posibilidades de que pueda _fusionar_ en su trabajo son mayores. Imagine que escriben una corrección de errores, agregan una nueva función y actualizan varias pruebas; ¿qué sucede si lo desea o solo puede implementar 2 de 3 o 1 de 3 cambios? +1. **Crear una rama**. Querrás pedirles que creen una _ rama_ para su trabajo. +1. **Concentre su cambio en un área**. Pida a los colaboradores que concentren sus contribuciones en una cosa a la vez; de esa manera, las posibilidades de _fusionar_ su trabajo son mayores. Imagínate que escriben una corrección de errores, agregan una nueva función y actualizan varias pruebas; ¿qué sucede si quieres todos los cambios o solo puedes implementar 2 de 3 o 1 de 3 cambios? -✅ Imagine una situación en la que las sucursales son particularmente críticas para escribir y enviar un buen código. ¿En qué casos de uso se te ocurren? +✅ Imagínate una situación en la que las ramas (branches) de git son particularmente críticas para escribir y enviar buen código. ¿Qué casos de uso se te ocurren? -> Tenga en cuenta que sea el cambio que desea ver en el mundo y cree también sucursales para su propio trabajo. Todas las confirmaciones que realice se realizarán en la sucursal en la que está actualmente "registrado". Use `git status` para ver qué rama es esa. +> Se el cambio que deseas ver en el mundo y crea también ramas para tu propio trabajo. Todas las confirmaciones que realices se realizarán en la rama en la que estás actualmente "registrado". Usa `git status` para ver qué rama es. -Repasemos el flujo de trabajo de un colaborador. Suponga que el colaborador ya ha _bifurcado_ y _clonado_ el repositorio para que tenga un repositorio de Git listo para trabajar en su máquina local: +Repasemos el flujo de trabajo de un colaborador. Supon que el colaborador ya ha _bifurcado_ y _clonado_ el repositorio para que tenga un repositorio de Git listo para trabajar en su máquina local: -1. **Crea una rama**. Use el comando `git branch` para crear una rama que contendrá los cambios que pretenden contribuir: +1. **Crea una rama**. Usa el comando `git branch` para crear una rama que tendrá los cambios que quieres contribuir: ```bash git branch [branch-name] ``` -1. **Cambiar a rama de trabajo**. Cambie a la rama especificada y actualice el directorio de trabajo con `git checkout`: +1. **Cambiar a rama de trabajo**. Cambia a la rama especificada y actualiza tu directorio de trabajo con `git checkout`: ```bash git checkout [branch-name] ``` -1. **Trabaja**. En este punto, desea agregar sus cambios. No olvide informarle a Git con los siguientes comandos: +1. **Trabaja**. En este punto, deseas agregar tus cambios. No olvides informarle a Git con los siguientes comandos: ```bash git add . git commit -m "mis cambios" ``` - Asegúrese de darle un buen nombre a su compromiso, por su bien y por el mantenedor del repositorio en el que está ayudando. + Asegúrate de darle un buen nombre a tu commit, tanto por tu bien como por el mantenedor del repositorio en el que estás ayudando. -1. **Combine su trabajo con la rama `principal`**. En algún momento ha terminado de trabajar y desea combinar su trabajo con el de la rama `principal`. La rama `main` podría haber cambiado mientras tanto, así que asegúrese de actualizarla primero a la última con los siguientes comandos: +1. **Combina tu trabajo con la rama `principal`**. En algún momento has terminado de trabajar y deseas combinar tu trabajo con el de la rama `principal`. La rama `main` podría haber cambiado mientras tanto, así que asegúrate de actualizarla con los siguientes comandos: ```bash git checkout main git pull ``` - En este punto, querrá asegurarse de que cualquier _conflicto_, situaciones en las que Git no pueda _combinarse_ fácilmente los cambios, ocurra en su rama de trabajo. Por lo tanto, ejecute los siguientes comandos: + En este punto, querrás asegurarte de que cualquier _conflicto_, situaciones en las que Git no pueda _combinarse_ fácilmente los cambios, ocurren en tu rama de trabajo. Mientras tanto, ejecuta los siguientes comandos: ```bash git checkout [branch_name] @@ -208,69 +210,69 @@ Repasemos el flujo de trabajo de un colaborador. Suponga que el colaborador ya h Esto traerá todos los cambios de `main` a su rama y es de esperar que pueda continuar. De lo contrario, VS Code le dirá dónde está _confundido_ Git y simplemente modificará los archivos afectados para decir qué contenido es el más preciso. -1. **Envíe su trabajo a GitHub**. Enviar tu trabajo a GitHub significa dos cosas. Empujar su sucursal a su repositorio y luego abrir un PR, Pull Request. +1. **Envía tu trabajo a GitHub**. Enviar tu trabajo a GitHub significa dos cosas. Empujar tu rama a tu repositorio y luego abrir un PR (Pull Request). ```bash git push --set-upstream origin [branch-name] ``` - El comando anterior crea la rama en su repositorio bifurcado. + El comando anterior crea la rama en tu repositorio bifurcado. -1. **Abra una PR**. A continuación, desea abrir un PR. Para hacerlo, navegue al repositorio bifurcado en GitHub. Verá una indicación en GitHub donde le preguntará si desea crear un nuevo PR, haga clic en eso y lo llevará a una interfaz donde puede cambiar el título del mensaje de confirmación, asígnele una descripción más adecuada. Ahora, el mantenedor del repositorio que bifurcó verá este PR y _dedos cruzados_ apreciarán y _ fusionar_ su PR. Ahora eres un colaborador, yay :) +1. **Abre un PR**. A continuación, abre un PR. Para hacerlo, navega al repositorio bifurcado en GitHub. Verás una indicación en GitHub donde te preguntarán si deseas crear un nuevo PR. Haz clic en eso y lo llevará a una interfaz donde puedes cambiar el título del mensaje de confirmación, asignarle una descripción más adecuada. Ahora, el mantenedor del repositorio que bifurcaste verá este PR y _dedos cruzados_ apreciarán y _ fusionarán_ tu PR. Ahora eres un colaborador, yay :) -1. **Limpiar**. Se considera una buena práctica _limpiar_ después de ti. Desea limpiar tanto su sucursal local como la sucursal que envió a GitHub. Primero eliminémoslo localmente con el siguiente comando: +1. **Limpiar**. Se considera una buena práctica _limpiar_ después de ti. Limpiar tanto tu rama local como la rama que enviaste a GitHub. Primero eliminémoslo localmente con el siguiente comando: ```bash git branch -d [branch-name] ``` - Asegúrese de ir a la página de GitHub para el repositorio bifurcado a continuación y elimine la rama remota que acaba de ingresar. + Asegúrate de ir a la página de GitHub del repositorio bifurcado a continuación y elimina la rama remota que acabas de ingresar. -`Solicitud de extracción` parece un término tonto porque realmente desea impulsar los cambios al proyecto. Pero el mantenedor (propietario del proyecto) o el equipo central debe considerar sus cambios antes de fusionarlo con la rama "principal" del proyecto, por lo que realmente está solicitando una decisión de cambio a un mantenedor. +`Solicitud de extracción` parece un término tonto porque realmente deseas impulsar los cambios al proyecto. Pero el mantenedor (propietario del proyecto) o el equipo central debe considerar tus cambios antes de fusionarlo con la rama "principal" del proyecto, por lo que realmente estás solicitando una decisión de cambio a un mantenedor. -Una solicitud de extracción es el lugar para comparar y discutir las diferencias introducidas en una rama con revisiones, comentarios, pruebas integradas y más. Una buena solicitud de extracción sigue aproximadamente las mismas reglas que un mensaje de confirmación. Puede agregar una referencia a un problema en el rastreador de problemas, cuando su trabajo, por ejemplo, soluciona un problema. Esto se hace usando un '#' seguido del número de su problema. Por ejemplo, `#97`. +Una solicitud de extracción es el lugar para comparar y discutir las diferencias introducidas en una rama con revisiones, comentarios, pruebas integradas y más. Una buena solicitud de extracción sigue aproximadamente las mismas reglas que un mensaje de confirmación. Puedes agregar una referencia a un problema en el rastreador de problemas, cuando tu trabajo, por ejemplo, soluciona un problema. Esto se hace usando un '#' seguido del número de tu problema. Por ejemplo, `#97`. -🤞 Cruce los dedos para que todos los controles pasen y los propietarios del proyecto combinen sus cambios en el proyecto🤞 +🤞 Cruza los dedos para que todos los controles pasen y los propietarios del proyecto combinen tus cambios en el proyecto🤞 -Actualice su rama de trabajo local actual con todas las nuevas confirmaciones de la rama remota correspondiente en GitHub: +Actualice tu rama de trabajo local actual con todas las nuevas confirmaciones de la rama remota correspondiente en GitHub: `git pull` ## Cómo contribuir al código abierto -Primero, busquemos un repositorio (o: repositorio) en GitHub que le interese y al que le gustaría contribuir con un cambio. Querrá copiar el contenido de a nuestra máquina. +Primero, busquemos un repositorio en GitHub que te interese y al que te gustaría contribuir con un cambio. Querrás copiar el contenido a nuestra máquina. ✅ Una buena forma de encontrar repositorios 'aptos para principiantes' es [buscar por la etiqueta `buena-primera-edición`](https://github.blog/2020-01-22-browse-good-first-issues-para-empezar-a-contribuir-al-código-abierto/). Hay varias formas de copiar código. Una forma es "clonar" el contenido del repositorio, usando HTTPS, SSH o usando GitHub CLI (Interfaz de línea de comandos). -Abra su terminal y clone el repositorio así: +Abre tu terminal y clona el repositorio así: `git clone https://github.com/ProjectURL` -Para trabajar en el proyecto, cambie a la carpeta correcta: +Para trabajar en el proyecto, cambia al directorio correcto: `cd ProjectURL` -También puede abrir todo el proyecto utilizando [Codespaces](https://github.com/features/codespaces), el entorno de desarrollo en la nube / editor de código integrado de GitHub o [GitHub Desktop](https://desktop.github.com/). +También puedes abrir todo el proyecto utilizando [Codespaces](https://github.com/features/codespaces), el entorno de desarrollo en la nube / editor de código integrado de GitHub o [GitHub Desktop](https://desktop.github.com/). -Por último, puede descargar el código en una carpeta comprimida. +Por último, puedes descargar el código en un directorio comprimido. ### Algunas cosas más interesantes sobre GitHub -Puede destacar, ver y / o "fork" cualquier repositorio público en GitHub. Puede encontrar sus repositorios destacados en el menú desplegable de la parte superior derecha. Es como marcar como favorito, pero por código. +Puede destacar, ver y / o "fork" cualquier repositorio público en GitHub. Puedes encontrar tus repositorios destacados en el menú desplegable de la parte superior derecha. Es como marcar como favorito, pero por código. Los proyectos tienen un rastreador de problemas, principalmente en GitHub en la pestaña "Issues" a menos que se indique lo contrario, donde las personas debaten los problemas relacionados con el proyecto. Y la pestaña Solicitudes de extracción es donde las personas debaten y revisan los cambios que están en curso. Los proyectos también pueden tener discusiones en foros, listas de correo o canales de chat como Slack, Discord o IRC. -✅ Eche un vistazo a su nuevo repositorio de GitHub y pruebe algunas cosas, como editar la configuración, agregar información a su repositorio y crear un proyecto (como un tablero Kanban). ¡Hay muchas cosas que puedes hacer! +✅ Echa un vistazo a tu nuevo repositorio de GitHub y prueba algunas cosas, como editar la configuración, agregar información a tu repositorio y crear un proyecto (como un tablero Kanban). ¡Hay muchas cosas que puedes hacer! -🚀 Desafío: empareje con un amigo para trabajar en el código del otro. Cree un proyecto de forma colaborativa, bifurque el código, cree ramas y combine los cambios. +🚀 Desafío: empareja con un amigo(a) para trabajar en el código juntos. Crea un proyecto de forma colaborativa, bifurque el código, crea ramas y combina los cambios. ## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/4) ## Revisión y autoestudio -Obtenga más información sobre [contribución al software de código abierto](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution). +Obtén más información sobre [contribución al software de código abierto](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution). [Hoja de referencia de Git](https://training.github.com/downloads/github-git-cheat-sheet/). @@ -278,6 +280,6 @@ Práctica práctica práctica. GitHub tiene excelentes rutas de aprendizaje disp - [Primera semana en GitHub](https://lab.github.com/githubtraining/first-week-on-github) -También encontrará laboratorios más avanzados. +También encontrarás laboratorios más avanzados. **Tarea**: Completa [la primera semana en el laboratorio de capacitación de GitHub](https://lab.github.com/githubtraining/first-week-on-github) diff --git a/1-getting-started-lessons/2-github-basics/translations/README.id.md b/1-getting-started-lessons/2-github-basics/translations/README.id.md index 15e4b819..d01a1b2c 100644 --- a/1-getting-started-lessons/2-github-basics/translations/README.id.md +++ b/1-getting-started-lessons/2-github-basics/translations/README.id.md @@ -2,7 +2,7 @@ Pelajaran ini mencakup dasar-dasar GitHub, platform untuk menghosting dan mengelola perubahan pada kode Anda. - + > Catatan sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuis Pra-Kuliah diff --git a/1-getting-started-lessons/2-github-basics/translations/README.it.md b/1-getting-started-lessons/2-github-basics/translations/README.it.md index 8244de43..dbc795c1 100644 --- a/1-getting-started-lessons/2-github-basics/translations/README.it.md +++ b/1-getting-started-lessons/2-github-basics/translations/README.it.md @@ -2,7 +2,7 @@ Questa lezione tratta delle basi di GitHub, una piattaforma per ospitare e gestire modifiche al proprio codice. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-lezione diff --git a/1-getting-started-lessons/2-github-basics/translations/README.ko.md b/1-getting-started-lessons/2-github-basics/translations/README.ko.md index e91452ed..9363d5c9 100644 --- a/1-getting-started-lessons/2-github-basics/translations/README.ko.md +++ b/1-getting-started-lessons/2-github-basics/translations/README.ko.md @@ -2,7 +2,7 @@ 이 강의에서는 코드 변경점을 호스팅하고 관리하는 플랫폼인 GitHub의 기본 사항을 다룹니다. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 diff --git a/1-getting-started-lessons/2-github-basics/translations/README.ms.md b/1-getting-started-lessons/2-github-basics/translations/README.ms.md index 0cb56e2f..2af6937f 100644 --- a/1-getting-started-lessons/2-github-basics/translations/README.ms.md +++ b/1-getting-started-lessons/2-github-basics/translations/README.ms.md @@ -2,7 +2,7 @@ Pelajaran ini merangkumi pengetahuan asas tentang GitHub, dan adalah salah satu platform untuk menjadi tuan rumah dan menguruskan perubahan pada kod anda. - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra-Kuliah diff --git a/1-getting-started-lessons/2-github-basics/translations/README.nl.md b/1-getting-started-lessons/2-github-basics/translations/README.nl.md new file mode 100644 index 00000000..92a820c6 --- /dev/null +++ b/1-getting-started-lessons/2-github-basics/translations/README.nl.md @@ -0,0 +1,318 @@ +# Inleiding van GitHub + +Deze les behandelt de basisprincipes van GitHub, een platform voor het hosten en beheren van wijzigingen in uw code. + + +> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) + +## Quiz voorafgaand aan de lezing +[Quiz voorafgaand aan de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/3) + +## Inleiding + +In deze les behandelen we: + +- het volgen van het werk dat u op uw machine doet +- samen met anderen aan projecten werken +- hoe u kunt bijdragen aan open source software + +### Vereisten + +Voordat u begint, moet u controleren of Git is geïnstalleerd. In het terminal typ: +`git --version` + +Als Git niet is geïnstalleerd, [download Git](https://git-scm.com/downloads). Stel vervolgens uw lokale Git-profiel in de terminal in: +* `git config --global user.name "uw-naam"` +* `git config --global user.email "uw-email"` + +Om te controleren of Git al is geconfigureerd, kunt u het volgende typen: +`git config --list` + +U heeft ook een GitHub-account nodig, een code-editor (zoals Visual Studio Code) en u moet uw terminal openen (of: command prompt). + +Navigeer naar [github.com](https://github.com/) en maak een account aan als u dat nog niet heeft gedaan, of log in en vul uw profiel in. + +✅ GitHub is niet de enige coderepository ter wereld; er zijn anderen, maar GitHub is de bekendste + +### Voorbereiding + +U heeft zowel een map met een codeproject op uw lokale computer (laptop of pc) als een openbare repository op GitHub nodig, die als voorbeeld zal dienen voor hoe u kunt bijdragen aan de projecten van anderen. + +--- + +## Code beheer + +Laten we zeggen dat u lokaal een map hebt met een of ander codeproject en u wilt beginnen met het volgen van uw voortgang met git - het versiebeheersysteem. Sommige mensen vergelijken het gebruik van git met het schrijven van een liefdesbrief aan uw toekomstige zelf. Als u uw commitberichten dagen of weken of maanden later leest, zult u u kunnen herinneren waarom u een beslissing heeft genomen, of een wijziging "terugdraaien" - dat wil zeggen, wanneer u goede "commitberichten" schrijft. + +### Taak: maak een repository en leg code vast + +1. **Maak een repository op GitHub**. Zoek op GitHub.com, in het tabblad repositories, of in de navigatiebalk rechtsboven, de knop **new repo**. + + 1. Geef uw repository (map) een naam + 1. Selecteer **create repository**. + +1. **Navigeer naar uw werkmap**. Schakel in uw terminal naar de map (ook bekend als de directory) die u wilt beginnen met volgen. Typ: + + ```bash + cd [naam van uw map] + ``` + +1. **Initialiseer een git-repository**. In uw project, typ: + + ```bash + git init + ``` + +1. **Controleer de status**. Om de status van uw repository te controleren, typ: + + ```bash + git status + ``` + + de output kan er ongeveer zo uitzien: + + ```output + Changes not staged for commit: + (use "git add <file>..." to update what will be committed) + (use "git checkout -- <file>..." to discard changes in working directory) + + modified: file.txt + modified: file2.txt + ``` + + Typisch vertelt een `git status` commando u dingen zoals welke bestanden klaar zijn om _opgeslagen_ te worden naar de repo of bevat veranderingen die u misschien wilt behouden. + +1. **Voeg alle bestanden toe voor tracking** + Dit wordt ook wel staging-bestanden/ bestanden toevoegen aan het staging-gebied genoemd. + + ```bash + git add . + ``` + + Het `git add` plus `.` argument geeft aan dat al uw bestanden en wijzigingen voor tracking geselecteerd zijn. + +1. **Voeg geselecteerde bestanden toe voor tracking** + + ```bash + git add [bestands- of mapnaam] + ``` + + Dit helpt ons om alleen geselecteerde bestanden aan het staging-gebied toe te voegen als we niet alle bestanden tegelijk willen vastleggen. + +1. **Unstage alle bestanden** + + ```bash + git reset + ``` + + Dit commando helpt ons om alle bestanden tegelijk te unstagen. + +1. **Unstage een bepaald bestand** + + ```bash + git reset [bestands- of mapnaam] + ``` + + Dit commando helpt ons om alleen een bepaald bestand tegelijk te unstagen dat we niet willen opnemen voor de volgende commit. + +1. **Uw werk voortzetten**. Op dit punt heeft u de bestanden toegevoegd aan een zogenaamd _staging-gebied_. Een plek waar Git uw bestanden bijhoudt. Om de wijziging permanent te maken, moet u de bestanden _commiten_. Om dit te doen maakt u een _commit_ aan met het `git commit` commando. Een _commit_ vertegenwoordigt een besparingspunt in de geschiedenis van uw repo. Typ het volgende om een _commit_ te maken: + + ```bash + git commit -m "eerste commit" + ``` + + Dit commit al uw bestanden door het bericht "first commit" toe te voegen. Voor toekomstige commitberichten wilt u meer beschrijvend zijn in uw beschrijving om over te brengen wat voor soort wijziging u heeft aangebracht. + +1. **Verbind uw lokale Git-repo met GitHub**. Een Git-repo is goed op uw computer, maar op een gegeven moment wilt u ergens een back-up van uw bestanden hebben en ook andere mensen uitnodigen om met u aan uw opslagplaats te werken. Een geweldige plek om dat te doen is GitHub. Onthoud dat we al een repo op GitHub hebben gemaakt, dus het enige dat we hoeven te doen, is onze lokale Git-repo verbinden met GitHub. Het commando `git remote add` zal precies dat doen. Typ de volgende commando: + + > Let op: voordat u de opdracht typt, gaat u naar uw GitHub-repo-pagina om de repository-URL te vinden. U gebruikt het in het onderstaande commando. Vervang `repository_name` door uw GitHub-URL. + + ```bash + git remote add origin https://github.com/username/repository_name.git + ``` + + Dit creëert een _remote_, of verbinding, genaamd "origin", wijzend naar de GitHub-repository die u eerder heeft gemaakt. + +1. **Stuur lokale bestanden naar GitHub**. Tot nu toe heeft u een _verbinding_ gemaakt tussen de lokale repo en de GitHub-repo. Laten we deze bestanden naar GitHub sturen met het volgende commando `git push`, zoals zo: + + ```bash + git push -u origin main + ``` + + Dit stuurt uw commits in uw "main" tak naar GitHub. + +1. **Om meer wijzigingen toe te voegen**. Als u door wilt gaan met het aanbrengen van wijzigingen en ze naar GitHub wilt pushen, hoeft u alleen maar de volgende drie commando's te gebruiken: + + ```bash + git add . + git commit -m "typ hier uw commitbericht" + git push + ``` + + > Tip, misschien wilt u ook een `.gitignore`-bestand adopteren om te voorkomen dat bestanden die u niet wilt volgen, verschijnen op GitHub - zoals dat notitiesbestand dat u opslaat in dezelfde map maar geen plaats heeft op een openbare repository. U kunt sjablonen voor `.gitignore` bestanden vinden op [.gitignore templates](https://github.com/github/gitignore). + +#### Commit berichten + +Een geweldige onderwerpregel voor een commitbericht van Git maakt de volgende zin compleet: +Indien toegepast, zal deze commit <uw onderwerpregel hier> + +Gebruik voor het onderwerp de gebiedende wijs, tegenwoordige tijd: "verander" niet "veranderd" noch "veranderingen". +Net als in het onderwerp, gebruik in het lichaam (optioneel) ook de imperatieve tegenwoordige tijd. Het lichaam moet de motivatie voor de verandering opnemen en dit contrasteren met eerder gedrag. U legt het `waarom` uit, niet het `hoe`. + +✅ Neem een paar minuten de tijd om rond GitHub te surfen. Kunt u een echt geweldig commitbericht vinden? Kunt u een echt minimale vinden? Welke informatie is volgens u het belangrijkst en nuttigst om over te brengen in een commitbericht? + +### Taak: Samenwerken + +De belangrijkste reden om dingen op GitHub te zetten, was om het mogelijk te maken om samen te werken met andere ontwikkelaars. + +## Samen met anderen aan projecten werken + +Navigeer in uw repository naar `Insights > Community` om te zien hoe uw project zich verhoudt tot aanbevolen communitystandaarden. + + Hier zijn enkele dingen die uw GitHub-repo kunnen verbeteren: + - **Omschrijving**. Heeft u een beschrijving voor uw project toegevoegd? + - **README**. Heeft u een README toegevoegd? GitHub biedt richtlijnen voor het schrijven van een [README](https://docs.github.com/articles/about-readmes/). + - **Richtlijn voor bijdragen**. Heeft uw project [richtlijnen voor bijdragen](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/), + - **Gedragscode**. Een [Gedragscode](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/), + - **Licentie**. Misschien nog belangrijker, een [licentie](https://docs.github.com/articles/adding-a-license-to-a-repository/)? + + +Al deze middelen zullen nieuwe teamleden helpen. En dat zijn typisch het soort dingen waar nieuwe bijdragers naar kijken voordat ze zelfs maar naar uw code kijken, om erachter te komen of uw project de juiste plek is om hun tijd door te brengen. + +✅ README-bestanden, hoewel ze wat tijd nodig hebben om voor te bereiden, worden vaak genegeerd door drukke beheerders. Kunt u een voorbeeld vinden van een bijzonder beschrijvende? Opmerking: er zijn enkele [tools om goede README's te maken](https://www.makeareadme.com/) die u misschien zou willen proberen. + +### Taak: voeg een code samen + +Documenten voor bijdragen helpen mensen bij te dragen aan het project. Het legt uit wat voor soort bijdragen u zoekt en hoe het proces werkt. Bijdragers moeten een reeks stappen doorlopen om bij te dragen aan uw repo op GitHub: + + +1. **Uw repo forken** Waarschijnlijk wilt u dat mensen uw project _forken_. Forken betekent het maken van een replica van uw repository op hun GitHub-profiel. +1. **Kloon**. Van daaruit zullen ze het project naar hun lokale computer klonen (clone). +1. **Maak een tak**. U zult ze willen vragen om een _tak_ voor hun werk te creëren (branch). +1. **Richt hun verandering op één gebied**. Vraag bijdragers om hun bijdragen op één ding tegelijk te concentreren - op die manier is de kans groter dat u hun werk kan _samenvoegen_ (merge). Stelt u voor dat ze een bugfix schrijven, een nieuwe functie toevoegen en verschillende tests bijwerken - wat als u slechts 2 van de 3 of 1 van de 3 wijzigingen wilt of kunt implementeren? + +✅ Stelt u een situatie voor waarin takken bijzonder cruciaal zijn voor het schrijven en verzenden van goede code. Welke use-cases kunt u bedenken? + +> Let op: wees de verandering die u in de wereld wilt zien, en maak ook takken voor uw eigen werk. Alle commits die u maakt, worden gemaakt op de tak waar u momenteel naar "uitgecheckt" bent. Gebruik `git status` om te zien welke tak dat is. + +Laten we een workflow voor bijdragers doorlopen. Veronderstel dat de bijdrager de repo al _geforkt_ en _gekloond_ heeft, zodat ze een Git-repo hebben klaar om aan te werken, op hun lokale computer: + +1. **Maak een tak**. Gebruik het commando `git branch` om een branch te maken die de wijzigingen bevat die ze willen bijdragen: + + ```bash + git branch [taknaam] + ``` + +1. **Overschakelen naar werkende tak**. Schakel over naar de gespecificeerde tak en update de werkdirectory met `git checkout`: + + ```bash + git checkout [taknaam] + ``` + +1. **Werken**. Op dit punt wilt u uw wijzigingen toevoegen. Vergeet niet om Git erover te vertellen met de volgende commando's: + + ```bash + git add . + git commit -m "mijn veranderingen" + ``` + + Zorg ervoor dat u uw commit een goede naam geeft, zowel voor u als voor de beheerder van de repo waarmee u helpt. + +1. **Combineer uw werk met de `main` tak**. Op een gegeven moment bent u klaar met werken en wilt u uw werk combineren met dat van de `main` tak. De `main` tak kan ondertussen veranderd zijn, dus zorg ervoor dat u deze eerst bijwerkt naar de laatste versie met de volgende commando's: + + ```bash + git checkout main + git pull + ``` + + Op dit punt wilt u er zeker van zijn dat alle _conflicten_, situaties waarin Git niet gemakkelijk de veranderingen kan _combineren_ plaatsvinden in uw werkende tak. Voer daarom de volgende opdrachten uit: + + ```bash + git checkout [taknaam] + git merge main + ``` + + Dit brengt alle wijzigingen van `main` naar uw tak en hopelijk kunt u gewoon doorgaan. Als dit niet het geval is, zal VS Code u vertellen waar Git _in de war_ is en verandert u gewoon de betrokken bestanden om te zeggen welke inhoud het meest accuraat is. + +1. **Stuur uw werk naar GitHub**. Het verzenden van uw werk naar GitHub betekent twee dingen. Uw tak naar uw repo pushen en vervolgens een PR, Pull Request openen. + + ```bash + git push --set-upstream origin [taknaam] + ``` + + Het bovenstaande commando maakt de tak op uw geforkte repo. + +1. **Open een PR**. Vervolgens wilt u een PR openen. U doet dat door naar de geforkte repo op GitHub te navigeren. U ziet een indicatie op GitHub waar het vraagt of u een nieuwe PR wilt maken, u klikt erop en u wordt naar een interface geleid waar u de titel van het commitbericht kunt wijzigen, geef het een meer geschikte beschrijving. Nu zal de beheerder van de repo die u heeft geforkt deze PR zien en, _vingers gekruist_, zullen ze uw PR waarderen en _samenvoegen_. U bent nu een bijdrager, yay :) + +1. **Opruimen**. Het wordt als een goede gewoonte beschouwd om _op te ruimen_ nadat u met succes een PR hebt samengevoegd. U wilt zowel uw lokale tak opruimen als de tak die u naar GitHub hebt gepusht. Laten we het eerst lokaal verwijderen met het volgende commando: + + ```bash + git branch -d [taknaam] + ``` + + Zorg ervoor dat u naar de GitHub-pagina gaat voor de geforkte repo en verwijder de externe tak die u er zojuist naartoe hebt gepusht. + +`Pull request` lijkt een gekke term, omdat u uw wijzigingen echt in het project wilt pushen. Maar de onderhouder (projecteigenaar) of het kernteam moet rekening houden met uw wijzigingen voordat u deze samenvoegt met de "main" tak van het project, dus u vraagt echt om een wijzigingsbesluit van een onderhouder. + +Een pull request is de plek om de verschillen die op een tak zijn geïntroduceerd te vergelijken en te bespreken met recensies, opmerkingen, geïntegreerde tests en meer. Een goed pull request volgt ongeveer dezelfde regels als een commitbericht. U kunt een verwijzing naar een probleem (issue) toevoegen in de issue tracker, bijvoorbeeld wanneer uw werk een probleem oplost. Dit doet u met een `#` gevolgd door het nummer van uw probleem. Bijvoorbeeld `# 97`. + +🤞Duimen dat alle controles slagen en de projecteigenaar(s) uw wijzigingen in het project samenvoegen🤞 + +Update uw huidige lokale werkende tak met alle nieuwe commits van de corresponderende remote tak op GitHub: + +`git pull` + +## Hoe u kunt bijdragen aan open source + +Laten we eerst een repository - of: repo - op GitHub zoeken die voor u interessant is en waaraan u een wijziging zou willen bijdragen. U zult de inhoud ervan naar uw machine kopiëren. + +✅ Een goede manier om 'beginnersvriendelijke' repos te vinden, is door [te zoeken op de tag 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/). + + + +Er zijn verschillende manieren om code te kopiëren. Een manier is om de inhoud van de repository te "klonen" door HTTPS, SSH of de GitHub CLI (Command Line Interface) te gebruiken. + +Open uw terminal en kloon de repository op deze manier: +`git clone https://github.com/ProjectURL` + +Schakel naar de juiste map om aan het project te werken: +`cd ProjectURL` + +U kunt ook het hele project openen met [Codespaces](https://github.com/features/codespaces), GitHub's ingesloten code-editor /cloud-ontwikkelomgeving of [GitHub Desktop](https://desktop.github.com/). + +Ten slotte kunt u de code downloaden in een gecomprimeerde map. + +### Nog een paar interessante dingen over GitHub + +U kunt elke openbare repository op GitHub een ster geven, bekijken en/of "forken". U kunt uw repositories met ster vinden in het vervolgkeuzemenu rechtsboven. Het is net als bladwijzers, maar dan voor code. + +Projecten hebben een issue tracker, meestal op GitHub in de "Issues" tab, tenzij anders aangegeven, waar mensen problemen bespreken die verband houden met het project. En op het tabblad Pull Requests bespreken en beoordelen mensen lopende wijzigingen. + +Projecten kunnen ook worden besproken in forums, mailinglijsten of chatkanalen zoals Slack, Discord of IRC. + +✅ Kijk eens rond in uw nieuwe GitHub-repo en probeer een paar dingen, zoals het bewerken van instellingen, het toevoegen van informatie aan uw repo en het maken van een project (zoals een Kanban-bord). U kunt veel doen! + +--- + +## 🚀 Uitdaging + +Koppel met een vriend om aan elkaars code te werken. Creëer gezamenlijk een project, fork code, maak takken en voeg wijzigingen samen. + +## Quiz na de lezing +[Quiz na de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/4) + +## Beoordeling en zelfstudie + +Lees meer over [bijdragen aan open source software](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution). + +[Git-cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/). + +Oefenen, oefenen, oefenen. GitHub heeft geweldige leertrajecten beschikbaar via [lab.github.com](https://lab.github.com/): + +- [Eerste week op GitHub](https://lab.github.com/githubtraining/first-week-on-github) + +U zult ook meer geavanceerde labs vinden. + +## Toewijzing + +Voltooi [de eerste week op GitHub-trainingslaboratorium](https://lab.github.com/githubtraining/first-week-on-github) diff --git a/1-getting-started-lessons/2-github-basics/translations/README.zh-cn.md b/1-getting-started-lessons/2-github-basics/translations/README.zh-cn.md new file mode 100644 index 00000000..5a97fc30 --- /dev/null +++ b/1-getting-started-lessons/2-github-basics/translations/README.zh-cn.md @@ -0,0 +1,318 @@ +# GitHub 介绍 + +这节课涵盖了 GitHub 的基础知识,这是一个可以用来存放代码和管理代码变更的平台。 + + +> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac) + +## 课前小测 +[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/3?loc=zh_cn) + +## 大纲 + +这节课我们将会介绍: + +- 在你的电脑上追踪你的工作 +- 与他人协同开发项目 +- 如何参与开源软件贡献 + +### 开始之前 + +开始之前,你需要确保安装了 Git,在终端(译注:即上一节课中介绍的命令行)中输入: +`git --version` + +如果没有安装 Git,请先[下载并安装 Git](https://git-scm.com/downloads)。然后用如下命令设置你的本地 Git 使用者配置文件: +* `git config --global user.name "your-name"` +* `git config --global user.email "your-email"` + +要检查 Git 使用者是否配置完成,可以输入: +`git config --list` + +你还需要一个 GitHub 账户,一个代码编辑器(比如 Visual Studio Code),并且要打开你的终端(或者其他命令行)。 + +如果你没有现成的 Github 账号,去 [github.com](https://github.com/) 创建一个。如果已经有账号,就登录进去并且完成个人资料的配置。 + +✅ GitHub 并不是世界上唯一的代码仓库,但是最知名的。 + +### 课前准备 + +你需要在本地(你的笔记本或 PC)创建一个项目文件夹,还需要在 GitHub 上创建一个公开的仓库(译注:后文会有指引),作为本节课中向其他人的项目提贡献的示例。 + +--- + +## 代码管理 + +假如你在本地有一个代码项目的文件夹,你希望开始使用 Git (版本控制系统)来追踪你的进度。有的人将使用 Git 比作给未来的你自己写一封情书,在数日、数周乃至数月后阅读你的提交信息(commit messages)时,你就可以想起你做出某个决定的原因,或者回滚(rollback)一次变更 —— 前提是你写了不错的提交信息。 + +### 任务:创建仓库并提交代码 + +1. **在 GitHub 上创建仓库**。进入 GitHub.com,在 “Repositories” 标签或者右上角导航栏找到 **New repository** 按钮。 + + 1. 给你的仓库取个名字; + 1. 点击 **Create repository**。 + +1. **前往你的工作目录**。在你的终端中,通过输入下方命令切换到你希望开始追踪的文件夹(即目录): + + ```bash + cd [文件名称/目录路径] + ``` + +1. **初始化一个 Git 仓库**。在你的项目下输入: + + ```bash + git init + ``` + +1. **检查状态**。要检查你的仓库状态,输入: + + ```bash + git status + ``` + + 输出看起来将会像这样: + + ```output + Changes not staged for commit: + (use "git add <file>..." to update what will be committed) + (use "git checkout -- <file>..." to discard changes in working directory) + + modified: file.txt + modified: file2.txt + ``` + + 一般来说 `git status` 命令会告诉你诸如什么文件已经 _被保存到_ 仓库内或者有一些你可能想要保留的变更之类的事。 + +1. **追踪所有文件** + 这个操作也叫做暂存(stage)文件或者将文件添加到暂存区(staging area)。 + + ```bash + git add . + ``` + + `git add` 命令加上 `.` 参数将会追踪你的所有文件和变更。 + +1. **只追踪选定的文件** + + ```bash + git add [文件或文件夹名] + ``` + + 如果你不想一次性将所有文件添加到暂存区,可以用这个命令仅仅添加选定的文件。 + +1. **取消所有文件的追踪** + + ```bash + git reset + ``` + + 这条命令可以帮我们取消暂存(unstage)所有文件。 + +1. **取消特定文件的追踪** + + ```bash + git reset [文件或文件夹名] + ``` + + 如果你在下次提交中不希望提交某个已经暂存的文件,可以用这条命令取消它的暂存。 + +1. **保存你的工作**。现在你应该已经将文件添加到了所谓 _暂存区_ 中,这是 Git 追踪你的文件的地方。为了永久地保存变更,你需要 _提交(commit)_ 这些文件。你可以用 `git commit` 命令创建一次 _提交_。一次 _提交_ 代表你的仓库历史中的一个存档点。输入下方命令来创建一次 _提交_: + + ```bash + git commit -m "first commit" + ``` + + 这会提交你暂存区中的所有文件,并带上一条提交信息 —— “first commit”。在以后的提交信息中你会想要加入更加准确的描述,比如一些表示你这次变更的类型的信息。 + +1. **将你的本地仓库连接到 GitHub**。现在 Git 仓库已经能在你的本地机器上正常运作,但是有时候你会想要将你的文件备份到别处,或者希望邀请其他人来一起参与这个仓库的协作。GitHub 就是一个可以满足你要求的好地方。我们此前已经在 GitHub 上创建了一个仓库,现在只需要将本地 Git 仓库连接到 GitHub 就可以了,用 `git remote add` 命令就可以做到。输入下面的命令: + + > 注意,在你输入命令前,需要前往你的 GitHub 仓库而页面来找到仓库的地址(URL),用它来替换命令中 `username/repository_name` 这一部分。 + + ```bash + git remote add origin https://github.com/username/repository_name.git + ``` + + 这会创建一个被命名为 “origin” 的 _远程仓库位置(remote)_,也可以理解为一个连接,指向你早先创建的 GitHub 仓库。 + +1. **将本地文件上传至 GitHub**。现在你已经创建了一个本地仓库和 GitHub 仓库间的 _连接_。让我们通过 `git push` 命令将这些文件上传至 GitHub,就像这样: + + ```bash + git push -u origin main + ``` + + 这样就会把你的提交上传到 GitHub 上你的 “main” 分支了。 + +1. **添加更多的变更**。如果你想继续搞点变更并且将它们传到 GitHub 上,你只需要使用下面的三行命令: + + ```bash + git add . + git commit -m "在这里填写你的提交信息" + git push + ``` + + > 提示,你可能还需要建立一个 `.gitignore` 文件来防止 Git 追踪一些文件并且让它们不会被上传到 GitHub,比如一些你写在本地仓库但并不想放到公开仓库的笔记文件。你可以在 [.gitignore templates](https://github.com/github/gitignore) 找到一些现成的 `.gitignore` 文件模板。 + +#### 提交信息(Commit Messages) + +一条好的 Git 提交信息标题(subject line)可以理解为下方句子的填空: +如果生效,这次提交将会 <你的提交信息标题> + +在标题内,使用祈使语气和现在时态,即使用 “change” 而非 “changed” 或 “changes”。 +同理,在正文(body,可选)中也要用祈使语气和现在时态。正文中需要包括更改的动机,并对比与更改前后行为的变化。确保你说明的是`为什么`,而不是`怎么做`。 + +✅ 花几分钟逛逛 GitHub。你能找到感觉非常棒的提交信息吗?你可以找到非常简洁的提交信息吗?你认为在一条提交信息中,传达什么信息是最重要和有用的? + +### 任务:协作 + +将项目放到 GitHub 的主要原因是让和其他开发者协作开发成为可能。 + +## 和其他人协作开发项目 + +在你的仓库中,前往 `Insights > Community` 来查看你的项目和推荐的社区规范的对比。 + + 这里有一些你可以改进你的项目仓库的点: + - **项目描述(Description)**。你为你的项目添加了描述吗? + - **README**。你有添加 README 吗?GitHub 提供了撰写 [README](https://docs.github.com/articles/about-readmes/) 的指南。 + - **贡献指南(Contributing guideline)**。你的项目是否有[贡献指南](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/)? + - **行为准则(Code of Conduct)**。添加一份 [行为准则](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/) + - **开源协议(License)**。或许是最重要的,添加一个[开源协议](https://docs.github.com/articles/adding-a-license-to-a-repository/) + + +所有这些资源对于新加入的团队成员都是很有好处的,这些一般是新的贡献者在看你的代码前会更先去看的东西,以确认你的项目是否值得他们在这上面花费时间。 + +✅ 尽管很多人都准备了 README 文件,但常常会因为太忙而疏于维护。你能找到一个这样的例子吗?注:这里有一些可以[用于创建优秀的 README 的工具](https://www.makeareadme.com/),你或许愿意试试。 + +### 任务:合并(Merge)一些代码 + +贡献文档帮助人们对项目做贡献,其中说明了你正需要什么样的贡献以及贡献的过程该是怎样的。贡献者需要完成一系列步骤才能在 GitHub 上参与你项目的贡献: + + +1. **复刻(Fork)你的仓库**。你可能希望人们 _复刻_ 你的项目。复刻意味着在他们自己的 GitHub 账户下创建你的项目的一份副本。 +1. **克隆(Clone)**。在这里他们将会将项目克隆到他们的本地机器上。 +1. **创建一个分支(Branch)**。你可能希望他们能创建一个 _分支_ 来进行他们的工作。 +1. **集中进行一个区域的修改**。要求贡献者每次贡献只专注做一件事,这样你才更可能 _合并_ 他们的工作。想象一下如果他们修了一个 BUG,添加了一个新特性,然后更新了几个测试,而你其实只想要其中的一个或两个更改时该怎么办? + +✅ 想一想分支在什么情况下对于编写和发布优质的代码非常重要?你能想到哪些使用实例? + +> 注意,要以身作则,对你自己的工作也要创建分支。任何提交都需要在当前“检出(checked out)”的分支上进行。使用 `git status` 来查看是哪一个分支。 + +让我们走一遍贡献者的工作流程。假设贡献者已经 _复刻_ 并 _克隆_ 了仓库,他们在本地机器已经有了一个可以工作的仓库: + +1. **创建一个分支**。使用命令 `git branch` 来创建一个他们希望用来包含计划进行的变更的分支: + + ```bash + git branch [分支名] + ``` + +1. **切换到工作分支**。使用 `git checkout` 来切换到指定分支并且更新工作目录中的文件: + + ```bash + git checkout [分支名] + ``` + +1. **干活**。现在你可以添加你的变更了,别忘了用下面的命令告诉 Git 你所做的工作: + + ```bash + git add . + git commit -m "变更内容" + ``` + + 确保你的提交有一个好名字,不论是对你自己还是你正在帮助的仓库维护者来说都有好处。 + +1. **将你的工作合入 `main` 分支**。在完成工作后,你打算将你的工作和 `main` 分支上的合并。`main` 分支可能同时有了一些新的变更,所以要先用以下命令确保将其更新至最新版本: + + ```bash + git checkout main + git pull + ``` + + 这时你想确认是否存在 _冲突(conflicts)_,即 Git 没法简单地将这些变化 _合入_ 你的分支的情况。为此运行下面的命令: + + ```bash + git checkout [分支名] + git merge main + ``` + + 这将会把所有 `main` 分支上的变更带入到你的分支上。运气好的话一切都会自动搞定,否则 VS Code 会告诉你哪些文件 Git _不确定_ 该如何合并,你只需要手动修改对应文件来解决冲突即可。 + +1. **将你的工作上传至 GitHub**。将你的工作上传至 GitHub 意味着两件事:把你的分支上传到你自己的仓库,然后开启一个 PR(Pull Request): + + ```bash + git push --set-upstream origin [分支名] + ``` + + 上述命令在你复刻的仓库中创建了一个分支。 + +1. **开启一个 PR**。接下来,你打算开启一个 PR。前往 GitHub 上你打算贡献的仓库,你将会看到一个消息条询问你是否想要创建一个新的 PR,点击后即可进入创建 PR 的界面。在这里你可以更改提交标题,给出更准确的描述。创建 PR 后,仓库维护者将会看到这个,如果 _一切顺利_ 的话他们会表示感谢并且 _合并_ 你的 PR。你现在就是一位贡献者啦! :) + +1. **清理**。成功合入一个 PR 后,做做 _清理_ 是一个好习惯。你会想要清理本地和你上传到 GitHub 的分支。首先让我们通过下面的命令来删除本地的分支: + + ```bash + git branch -d [分支名] + ``` + + 接下来请确保前往 GitHub 中对应仓库的页面并删除你刚才上传的分支。 + +`Pull request` 这个术语看起来有些憨,因为你确实打算把你的变更提交到这个项目中。但是在将你的变更合入到项目的 `main` 分支前,维护者(项目拥有者)或者核心团队需要考虑和检查你的变更,这意味着你实际上是在请求(request)维护者的变更决定。 + +Pull Request 是一个可以用来比较和讨论一个分支引入的改动的地方,并有代码审查、评论、集成测试等功能。优质的 Pull Request 严格遵照与提交信息相同的规则。如果你的工作是为了修复一个 Issues 面板中的事项,你可以在 PR 中提及这个事项。具体做法是写一个 `#` 加上事项的编号,比如 `#97`。 + +🤞如果一切顺利,所有的检查都通过后项目拥有者就会将你的变更合入项目🤞 + +使用这个命令即可将 GitHub 上对应远程分支的所有新提交更新到当前本地的工作分支上: + +`git pull` + +## 如何参与开源贡献 + +首先,让我们在 GitHub 上找到一个你感兴趣且愿意参与贡献的仓库(**repo**),你会复制一份它的内容到你的机器上。 + +✅ 一个寻找对入门者友好的仓库的好办法是[搜索 “good-first-issue” 标签](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)。 + + + +有很多种复制代码的方法,其中一种就是“克隆”仓库的内容,可以用 HTTPS、SSH 或者 GitHub CLI(Command Line Interface)来做到。 + +打开你的终端并且用类似下方的命令来克隆仓库: +`git clone https://github.com/ProjectURL` + +切换到正确的工作目录: +`cd ProjectURL` + +你也可以用 [Codespaces](https://github.com/features/codespaces) 来打开整个项目,这是 GitHub 内置的代码编辑器和云开发环境,或者用 [GitHub Desktop](https://desktop.github.com/)。 + +当然,你也可以直接下载代码的压缩包。 + +### 更多 GitHub 的有趣小知识 + +你可以收藏(star)、关注(watch)和/或复刻(fork)GitHub 上的任何公开仓库。可以在右上角的下拉菜单找到你收藏的仓库,这就像书签一样,但收藏的是代码。 + +项目都有一个事项面板(issue tracker),用于让人们讨论和这个项目相关的事项,事项面板基本都在 GitHub 的 “Issues” 标签页中,偶尔也会指明在其他地方。而 “Pull Requests” 标签页则是人们讨论和检查正在进行的变更的地方。 + +项目也可能会在论坛、邮件列表或者如 Slack、Discord、IRC 这样的聊天频道进行讨论。 + +✅ 看看你新建立的 GitHub 仓库,尝试做一些其他事,比如编辑设置、为仓库增加信息、创建一个 Project(类似看板),有很多可以尝试的东西! + +--- + +## 🚀 挑战 + +找朋友一起编辑彼此的代码。协作创建一个项目、复刻代码、创建分支,然后合并变更。 + +## 课后小测 +[课后小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/4?loc=zh_cn) + +## 复习 & 自学 + +了解更多 [如何提交贡献](https://opensource.guide/zh-hans/how-to-contribute/#%E5%A6%82%E4%BD%95%E6%8F%90%E4%BA%A4%E8%B4%A1%E7%8C%AE)。 + +[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/)。 + +练习,练习,再练习。GitHub 在 [lab.github.com](https://lab.github.com/) 提供了很棒的学习路径: + +- [在 GitHub 的第一周](https://lab.github.com/githubtraining/first-week-on-github) + +你还可以在上面找到更多高阶的实验内容。 + +## 作业 + +完成 [在 GitHub 的第一周](https://lab.github.com/githubtraining/first-week-on-github) diff --git a/1-getting-started-lessons/2-github-basics/translations/README.zh-tw.md b/1-getting-started-lessons/2-github-basics/translations/README.zh-tw.md new file mode 100644 index 00000000..bcf3bf2a --- /dev/null +++ b/1-getting-started-lessons/2-github-basics/translations/README.zh-tw.md @@ -0,0 +1,319 @@ +# GitHub 簡介 + +這堂課程講述一個提供加設與管理程式碼的平台 ── Github的基本功能。 + + +> 由[Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/3?loc=zh_tw) + +## 大綱 + +在這堂課中,包含: + +- 追蹤裝置上的工作專案 +- 與其他人共同開發專案 +- 如何貢獻網路上的開源軟體 + +### 開始之前 + +在你開始課程之前,你需要安裝 Git 這套套件。在你的終端機上輸入: +`git --version` + +若你的裝置上沒有安裝 Git,[請下載並安裝 Git](https://git-scm.com/downloads)。 安裝完之後,請設定裝置本地 Git 的使用者設定。 +* `git config --global user.name "your-name"` +* `git config --global user.email "your-email"` + +要確認 Git 使用者設定是否完成,你可以輸入: +`git config --list` + +此外,你需要一組 GitHub 的帳戶、一款文字編輯器 (如:Visual Studio Code) 與你的終端機 (或 command prompt)。 + +若你缺少 GitHub 帳戶,請前往 [github.com](https://github.com/)建立並登入一組帳戶,遵循指示完成資料的填寫。 + +✅ GitHub 不是唯一的程式碼數據庫,但 GitHub 是家喻戶曉的。 + +### 課前準備 + +你需要在裝置(筆電或電腦)上建立程式專案的資料夾,與 GitHub 公共的數據庫(Public Repository)。之後的例子會使用到此公共數據庫來與他人分享程式碼。 + +--- + +## 程式碼管理 + +假設你的本地端資料夾存放著一些程式專案,你想利用 Git 來作專案追蹤與版本控制,甚至是對未來的你寫一封情書。在一天、一週甚至是一個月後閱讀你的提交紀錄,了解當初你的決定,回想之前的更動。前提是當初你有寫一條完整的提交紀錄。 + +### 課題:建立數據庫並提交程式碼 + +1. **在 GitHub 上建立數據庫** 在 GitHub.com 上,在 "Repositories" 的標籤或導航欄的右上方,找到 **new repo** 的按鈕。 + + 1. 為你的數據庫資料夾取個名字。 + 1. 選擇 **建立數據庫(create repository)**. + +1. **調查本地的專案資料夾** 在終端機中開啟儲存程式碼的資料夾,在你想追蹤的目錄下輸入: + + ```bash + cd [資料夾名稱] + ``` + +1. **初始化 git 數據庫(repo)** 在目錄下輸入: + + ```bash + git init + ``` + +1. **檢查狀態** 若想檢查目前數據庫的狀態,輸入: + + ```bash + git status + ``` + + 它會輸出類似以下的訊息: + + ```output + Changes not staged for commit: + (use "git add <file>..." to update what will be committed) + (use "git checkout -- <file>..." to discard changes in working directory) + + modified: file.txt + modified: file2.txt + ``` + + 指令 `git status` 會回報那些檔案已經準備 _被存到_ 數據庫或是被更動過但不想更新上去。 + +1. **開始追蹤所有檔案** + 新增檔案到暫存區(staging area)。 + + ```bash + git add . + ``` + + `git add` 加上路徑 `.` 表示追蹤該路徑下所有的檔案。 + +1. **只追蹤選擇的檔案** + + ```bash + git add [檔案或資料夾路徑] + ``` + + 上述指令幫助你只追蹤被選取的檔案,允許使用者分批提交。 + +1. **取消追蹤所有檔案** + + ```bash + git reset + ``` + + 上述指令能取消追蹤(unstage)暫存區的檔案。 + +1. **取消追蹤特定的檔案** + + ```bash + git reset [檔案或資料夾路徑] + ``` + + 上述指令只取消追蹤單一檔案,在下一次提交時不被圈選在裡面。 + +1. **保存工作狀態** 現在,已經有一些檔案被標記在 _暫存區(staging area)_。 Git 會追蹤區域內的檔案。若要保存這些檔案的狀態,你需要 _提交(commit)_ 這些檔案。 _提交_ 會記錄當下數據庫中檔案的狀態到歷史紀錄中。 你需要指令`git commit` 完成這項工作。 + + ```bash + git commit -m "first commit" + ``` + + 這會提交暫存區內的檔案,"first commit"即提交紀錄。提交紀錄最好能識別出這次的提交主要做了那些更動。 + +1. **連接本地數據庫到 GitHub 遠端數據庫** 現在 Git 數據庫已經成功運行在你的本地裝置上,但有時候你希望能將檔案備份到其他地方,或是邀請他人參與這項程式專案。 GitHub 便是一個好地方。先前我們已經建立遠端數據庫在 GitHub 上,現在我們只要連接本地數據庫到 GitHub上。指令 `git remote add` 能完成這項課題: + + > 注意,在輸入指令前,你需要取得 GitHub 遠端數據庫的 URL 位置。請將下列的 `repository_name` 替換為你的遠端數據庫路徑。 + + ```bash + git remote add origin https://github.com/username/repository_name.git + ``` + + 這會在 GitHub 遠端數據庫上建立一個名叫 "origin" 的 _遠端位置(remote)_ ,或稱 _連接(connection)_。 + +1. **上傳本地檔案到 GitHub** 現在已經建好了遠端與本地的 _連接_。 利用指令 `git push` 可以將本地檔案上傳到遠端數據庫當中: + + ```bash + git push -u origin main + ``` + + 所有的提交都會加到 GitHub 上 "main" 的分支當中。 + +1. **增加更多的更動** 若之後再對程式碼有所更動、提交並上傳到 GitHub 上,只要輸入: + + ```bash + git add . + git commit -m "type your commit message here" + git push + ``` + + > 提示:建立 `.gitignore` 檔案可以讓你自動排除的特定檔案項目不被 GitHub 追蹤。好比是有一個在同一個目錄下的筆記檔不想被上傳到遠端數據庫。以下是 `.gitignore` 的參考版型: [.gitignore 參考版型](https://github.com/github/gitignore)。 + +#### 提交紀錄(Commit Messages) + +一條好的 Git 提交標題行最好滿足下列條件: +提交完後,提交紀錄會顯示 <你的標題> + +標題使用祈使語句,如使用 "change" 而非 "changed" 或 "changes"。 +同理地,內文(選擇性)也使用祈使語句。內文須包含改動的動機與改動前後的差異。你需要解釋「為什麼改」而非「怎麼改」。 + +✅ 花點時間在 GitHub 上閒晃。你能找到很棒的提交紀錄嗎? 你能找到簡潔的提交紀錄嗎? 哪些資訊是你認為一個提交紀錄要有的重要資訊? + +### 課題:多人合作 + +另一個將專案上傳到 GitHub 的主要原因是讓其他開發者能參與其中。 + +## 與其他人共同開發專案 + +在你的遠端資料庫中,前往 `Insights > Community` 來對比你的專案與其他推薦社群專案。 + + 以下是一些你的 GitHub 數據庫需要精進的地方: + - **專案描述(Description)** 你有為你的專案新增描述嗎? + - **README** 你有新增 README 嗎? GitHub 提供編寫 README 的指引與參考: [README](https://docs.github.com/articles/about-readmes/) + - **開發指引(Contributing guideline)** 你的專案內有[開發指引](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/)嗎? + - **行為準則(Code of Conduct)** [行為準則](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/) + - **授權條款License** 這或許是最重要的:[授權條款](https://docs.github.com/articles/adding-a-license-to-a-repository/) + + +這些資源對剛加入到專案的新成員有所幫助。這些是新的合作夥伴比看程式碼還優先查詢的地方。完善它們能有效縮減他人消化的時間。 + +✅ README 檔,雖然多數人都會配置,但忙碌的開發者都會疏於管理。 你能在社群中找到相關的例子嗎? 這邊有[關於建立 READMEs 的有利工具](https://www.makeareadme.com/)可以嘗試。 + +### 課題:合併程式碼 + +開發指引文件幫助他人了解如何共同開發專案。它提供專案需要被貢獻的部分與該如何運作。共同開發者需要經過下列步驟來與他人在 GitHub 共同開發專案: + +1. **分叉(Fork)專案** 你或許希望別人能 _分叉(fork)_ 你的專案。 分叉代表別人建立一份你的專案副本到他人的 GitHub 數據庫中。 +1. **複製(Clone)** 複製專案到他人的本地裝置中。 +1. **建立分支(branch)** 依照工作需求建立 _分支(branch)_。 +1. **專注在他人投入的工作範圍** 要求他人只專注在單一課題上,這樣能提升他們工作 _合併(merge)_ 的機會。想像他們在修正錯誤,同時又新增新功能、更新測試機制......這時如果你只想合併其中的一個、或者是兩個功能呢? + +✅ 想像一個情況:一個重要的分支是編輯與分享的主軸,它能被如何應用? + +> 注意,在做更動前,記得建立新的分支。任何提交都會在你所在的分支上,指令 `git status` 可以檢查你現在所在的分支。 + +現在,我們以共同開發者的角度來看。假設開發者已經 _分支_ 且 _複製_ 了他人的數據庫到自己的 Git 數據庫上,準備開始編輯檔案: + +1. **建立新的分支** 利用指令 `git branch` 來建立新的分支,只做相關的工作改動。 + + ```bash + git branch [分支名稱] + ``` + +1. **切換到該工作分支** 使用指令 `git checkout` 來切換到特定分支,更新分支的檔案狀態: + + ```bash + git checkout [分支名稱] + ``` + +1. **程式設計** 記得追蹤你所更改的地方,利用下列的指令來告訴 Git: + + ```bash + git add . + git commit -m "my changes" + ``` + + 請確保提交都有適當的名稱,對管理者與你自己都有好處。 + +1. **將工作分支與 `main` 分支進行合併** 當工作完成時,你會需要將工作分支與 `main` 分支進行合併。 `main` 分支可能會被他人更新,在合併之前記得更新主分支: + + ```bash + git checkout main + git pull + ``` + + 這項步驟可能會面臨到 _衝突(conflicts)_,代表 Git 無法將本地的更動作 _合併(combine)_ 。此時你需要執行下列的指令: + + ```bash + git checkout [分支名稱] + git merge main + ``` + + 這會將所有 `main` 分支的改動加入到你的本地目錄中。若出現狀況,VS Code會告訴你 Git 會對衝突的檔案感到 _困惑(confused)_, 你需要判斷哪一項檔案或程式碼才是最適當的選擇。 + +1. **將你的成果上傳到 GitHub** 這代表著兩件事:將分支推到你的遠端數據庫以及準備建立 Pull Request(PR)。 + + ```bash + git push --set-upstream origin [分支名稱] + ``` + + 上述的指令會在分叉的數據庫中新增分支。 + +1. **建立 PR** 藉由造訪分叉的數據庫中建立 PR,GitHub 會指示你是否要建立 PR,之後要填寫提交紀錄以及編寫詳細的說明。讓管理者了解你做了哪些更動並進行 _交叉比對(fingers crossed)_。 他們會感激你的貢獻並 _合併(merge)_ 你的 PR。完成這步後,你就成為了專案貢獻者,恭喜! + +1. **清理專案** 在 PR 被成功合併後, _清除專案(clean up)_ 會是一個好習慣。 你需要清除你的本地分支以及你的遠端數據庫分支。首先,你可以利用下列的指令清除本地分支: + + ```bash + git branch -d [分支名稱] + ``` + + 之後,請確保在 GitHub 頁面上刪除遠端分支。 + +`Pull request` 要求更新更動到「自己」的專案數據庫,這看起來很蠢。但管理者與核心組員必須謹慎地考量你的更動才能合併到專案的主分支中。這便是向管理者請求上傳許可。 + +一個 PR 提供比對以及討論的地方,解釋分支的意義、確認程式的合理性、留言與測試……等等。一個好的 PR 必須參照前述所說的提交紀錄準則。若你的 PR 有解決特定的 issue,記得標記在 PR 當中。使用 `#` 接在數字前面來標記 issue 編號,如 `#97`。 + +🤞 交叉比對每個程式環節都正確無誤後,專案管理者才合併你所作的更動 🤞 + +若要從 GitHub 遠端數據庫更新到目前的本地工作分支,使用: + +`git pull` + +## 如何貢獻網路上的開源軟體 + +首先,尋找一個你感興趣的數據庫,你會複製一份副本到自己的裝置上。 + +✅ 對新手而言,尋找「適合新手」的數據庫可以[搜尋 'good-first-issue' 標籤](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)。 + + + +有許多方式來複製數據庫。 一種是利用 "clone" 整個數據庫的內容。可以使用 HTTPS、SSH 或是 GitHub CLI (Command Line Interface)。 + +打開終端機並輸入下列指令來複製數據庫: +`git clone https://github.com/ProjectURL` + +複製完後記得切換到正確的資料夾當中: +`cd ProjectURL` + +你也可以利用[Codespaces](https://github.com/features/codespaces)來打開專案,一款嵌入在 GitHub 中的雲端開發環境,或是使用[GitHub Desktop](https://desktop.github.com/)。 + +最後,你也可以下載數據庫的壓縮檔。 + +### 有關 GitHub 的小知識 + +你可以為別人打星星(star)、追蹤(watch)或分叉(fork)任何一個 GitHub 上的共享數據庫。打上星星的數據庫會出現在右上方的導航欄中。就像是書籤,但是是給程式碼用的。 + +專案內會有 issue 追蹤器。大多數的 issue 會在 GitHub "Issue" 的標籤內(有些Issue會由作者另外說明),供大家進行討論。 Pull Requests 標籤內會有正在討論與審核的程式更動。 + +專案也會有討論區、寄信功能以及聊天室如 Slack、Discord 或 IRC。 + +✅ 花點時間觀察你的新專案,試著更新設定、新增描述、或架構成一個大型專案(像個大看板一樣!)。你可以創造出任何東西! + +--- + +## 🚀 挑戰 + +找朋友一起編輯彼此的程式。共同建立一項專案、分叉程式、建立分支、合併更動。 + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/4?loc=zh_tw) + +## 複習與自學 + +了解更多: + +[貢獻開源軟體](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) + +[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/) + +練習,練習,再練習! GitHub 有提供很好的學習管道:[lab.github.com](https://lab.github.com/) + +- [第一週在 GitHub 上](https://lab.github.com/githubtraining/first-week-on-github) + +你能找到更資深的實驗內容。 + +## 作業 + +完成[第一週在 GitHub 上](https://lab.github.com/githubtraining/first-week-on-github) diff --git a/1-getting-started-lessons/3-accessibility/README.md b/1-getting-started-lessons/3-accessibility/README.md index 99afa170..089302e9 100644 --- a/1-getting-started-lessons/3-accessibility/README.md +++ b/1-getting-started-lessons/3-accessibility/README.md @@ -1,6 +1,6 @@ # Creating Accessible Webpages - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -24,15 +24,15 @@ At its most basic, a screen reader will read a page from top to bottom audibly. Every web developer should familiarize themselves with a screen reader. As highlighted above, it's the client your users will utilize. Much in the same way you're familiar with how a browser operates, you should learn how a screen reader operates. Fortunately, screen readers are built into most operating systems. -Some browsers also have built-in tools and extensions that can read text aloud or even provide some basic navigational features, such as [these accessibility-focused Edge browser tools](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features). These are also important accessibility tools, but function very differently from screen readers and they should not be mistaken for screen reader testing tools. +Some browsers also have built-in tools and extensions that can read text aloud or even provide some basic navigational features, such as [these accessibility-focused Edge browser tools](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). These are also important accessibility tools, but function very differently from screen readers and they should not be mistaken for screen reader testing tools. -✅ Try a screen reader and browser text reader. On Windows [Narrator](https://support.microsoft.com/en-us/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1) is included by default, and [JAWS](https://webaim.org/articles/jaws/) and [NVDA](https://www.nvaccess.org/about-nvda/) can also be installed. On macOS and iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) is installed by default. +✅ Try a screen reader and browser text reader. On Windows [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1) is included by default, and [JAWS](https://webaim.org/articles/jaws/) and [NVDA](https://www.nvaccess.org/about-nvda/) can also be installed. On macOS and iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) is installed by default. ### Zoom -Another tool commonly used by people with vision impairments is zooming. The most basic type of zooming is static zoom, controlled through `Control + plus sign (+)` or by decreasing screen resolution. This type of zoom causes the entire page to resize, so using [responsive design](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design) is important to provide a good user experience at increased zoom levels. +Another tool commonly used by people with vision impairments is zooming. The most basic type of zooming is static zoom, controlled through `Control + plus sign (+)` or by decreasing screen resolution. This type of zoom causes the entire page to resize, so using [responsive design](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) is important to provide a good user experience at increased zoom levels. -Another type of zoom relies on specialized software to magnify one area of the screen and pan, much like using a real magnifying glass. On Windows, [Magnifier](https://support.microsoft.com/en-us/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) is built in, and [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) is a third-party magnification software with more features and a larger user base. Both macOS and iOS have a built-in magnification software called [Zoom](https://www.apple.com/accessibility/mac/vision/). +Another type of zoom relies on specialized software to magnify one area of the screen and pan, much like using a real magnifying glass. On Windows, [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) is built in, and [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) is a third-party magnification software with more features and a larger user base. Both macOS and iOS have a built-in magnification software called [Zoom](https://www.apple.com/accessibility/mac/vision/). ### Contrast checkers @@ -133,7 +133,7 @@ You can use `aria-label` to describe the link when the format of the page doesn' <a href="#" aria-label="Widget description">description</a> ``` -✅ In general, using Semantic markup as described above supersedes the use of ARIA, but sometimes there is no semantic equivalent for various HTML widgets. A good example is a Tree. There's no HTML equivalent for a tree, so you identify the generic `<div>` for this element with a proper role and aria values. The [MDN documentation on ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) contains more useful information. +✅ In general, using Semantic markup as described above supersedes the use of ARIA, but sometimes there is no semantic equivalent for various HTML widgets. A good example is a Tree. There's no HTML equivalent for a tree, so you identify the generic `<div>` for this element with a proper role and aria values. The [MDN documentation on ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) contains more useful information. ```html <h2 id="tree-label">File Viewer</h2> diff --git a/1-getting-started-lessons/3-accessibility/translations/README.es.md b/1-getting-started-lessons/3-accessibility/translations/README.es.md index 02e91081..3b3d8705 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.es.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.es.md @@ -1,6 +1,6 @@ # Creación de páginas web accesibles - + > Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5) @@ -9,7 +9,7 @@ > > \- Sir Timothy Berners-Lee, director del W3C e inventor de la World Wide Web -Esta cita destaca perfectamente la importancia de crear sitios web accesibles. Una aplicación a la que no pueden acceder todos es, por definición, excluyente. Como desarrolladores web, siempre debemos tener en cuenta la accesibilidad. Al tener este enfoque desde el principio, estará bien encaminado para garantizar que todos puedan acceder a las páginas que crea. En esta lección, aprenderá sobre las herramientas que pueden ayudarlo a asegurarse de que sus activos web sean accesibles y cómo construir teniendo en cuenta la accesibilidad. +Esta cita destaca perfectamente la importancia de crear sitios web accesibles. Una aplicación a la que no pueden acceder todos es, por definición, excluyente. Como desarrolladores web, siempre debemos tener en cuenta la accesibilidad. Al tener este enfoque desde el principio, estará bien encaminado para garantizar que todos puedan acceder a las páginas que crea. En esta lección, aprenderás sobre las herramientas que pueden ayudarlo a asegurarse de que sus activos web sean accesibles y cómo construir teniendo en cuenta la accesibilidad. ## Herramientas para usar @@ -19,56 +19,56 @@ Una de las herramientas de accesibilidad más conocidas son los lectores de pant [Lectores de pantalla](https://en.wikipedia.org/wiki/Screen_reader) son clientes de uso común para personas con problemas de visión. A medida que dedicamos tiempo a asegurarnos de que un navegador transmita correctamente la información que deseamos compartir, también debemos asegurarnos de que un lector de pantalla haga lo mismo. -En su forma más básica, un lector de pantalla leerá una página de arriba a abajo de forma audible. Si su página es todo texto, el lector transmitirá la información de manera similar a un navegador. Por supuesto, las páginas web rara vez son puramente texto; contendrán enlaces, gráficos, color y otros componentes visuales. Se debe tener cuidado para garantizar que un lector de pantalla lea correctamente esta información. +En su forma más básica, un lector de pantalla leerá una página de arriba a abajo de forma audible. Si la página es todo texto, el lector transmitirá la información de manera similar a un navegador. Por supuesto, las páginas web rara vez son puramente texto; contendrán enlaces, gráficos, color y otros componentes visuales. Se debe tener cuidado para garantizar que un lector de pantalla lea correctamente esta información. -Todo desarrollador web debería familiarizarse con un lector de pantalla. Como se destacó anteriormente, es el cliente que utilizarán sus usuarios. De la misma manera que está familiarizado con el funcionamiento de un navegador, debe aprender cómo funciona un lector de pantalla. Afortunadamente, los lectores de pantalla están integrados en la mayoría de los sistemas operativos y muchos navegadores contienen extensiones para emular un lector de pantalla. +Todo desarrollador web debería familiarizarse con un lector de pantalla. Como se destacó anteriormente, es el cliente que utilizarán sus usuarios. De la misma manera que estás familiarizado con el funcionamiento de un navegador, debes aprender cómo funciona un lector de pantalla. Afortunadamente, los lectores de pantalla están integrados en la mayoría de los sistemas operativos y muchos navegadores contienen extensiones para emular un lector de pantalla. -✅ Prueba una extensión o herramienta de navegador de lector de pantalla. Uno que solo funciona en Windows es [JAWS](https://webaim.org/articles/jaws/). Los navegadores también tienen herramientas integradas que se pueden utilizar para este propósito; Consulte estas [herramientas de navegador Edge centradas en la accesibilidad](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features). +✅ Prueba una extensión o herramienta de navegador de lector de pantalla. Uno que solo funciona en Windows es [JAWS](https://webaim.org/articles/jaws/). Los navegadores también tienen herramientas integradas que se pueden utilizar para este propósito; Consulta estas [herramientas de navegador Edge centradas en accesibilidad](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). -### Damas de contraste +### Checar contrastes Los colores en los sitios web deben elegirse cuidadosamente para responder a las necesidades de los usuarios daltónicos o de las personas que tienen dificultades para ver colores de bajo contraste. -✅ Pruebe un sitio web que le guste usar para el uso del color con una extensión de navegador como - [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US). ¿Qué aprendes? +✅ Prueba un sitio web que te guste usar para el uso del color con una extensión de navegador como + [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US). ¿Qué aprendiste? ### Lighthouse -En el área de herramientas para desarrolladores de su navegador, encontrará la herramienta Lighthouse. Esta herramienta es importante para obtener una primera visión de la accesibilidad (así como otros análisis) de un sitio web. Si bien es importante no depender exclusivamente de Lighthouse, una puntuación del 100% es muy útil como referencia. +En el área de herramientas para desarrolladores en tu navegador, encontrarás la herramienta Lighthouse. Esta herramienta es importante para obtener una primera visión de la accesibilidad (así como otros análisis) de un sitio web. Si bien es importante no depender exclusivamente de Lighthouse, una puntuación del 100% es muy útil como referencia. -✅ Busque Lighthouse en el panel de herramientas de desarrollo de su navegador y ejecute un análisis en cualquier sitio. ¿Qué descubres? +✅ Busca Lighthouse en el panel de herramientas de desarrollo de su navegador y ejecuta un análisis en cualquier sitio. ¿Qué descubres? ## Diseñar para la accesibilidad -La accesibilidad es un tema relativamente extenso. Para ayudarlo, existen numerosos recursos disponibles. +La accesibilidad es un tema relativamente extenso. Para ayudarte, existen numerosos recursos disponibles. - [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers) -Si bien no podremos cubrir todos los aspectos de la creación de sitios accesibles, a continuación se muestran algunos de los principios básicos que querrá implementar. Diseñar una página accesible desde el principio es ** siempre ** más fácil que volver a una página existente para hacerla accesible. +Si bien no podremos cubrir todos los aspectos de la creación de sitios accesibles, a continuación se muestran algunos de los principios básicos que querrá implementar. Diseñar una página accesible desde el principio es **siempre** más fácil que volver a una página existente para hacerla accesible. ## Buenos principios de visualización ### Paletas de colores seguros -La gente ve el mundo de diferentes formas, y esto incluye los colores. Al seleccionar un esquema de color para su sitio, debe asegurarse de que sea accesible para todos. Uno genial [herramienta para generar paletas de colores es Color Safe](http://colorsafe.co/). +La gente ve el mundo de diferentes formas, y esto incluye los colores. Al seleccionar un esquema de color para tu sitio, debes asegurarte de que sea accesible para todos. Una [herramiento genial para generar paletas de colores es Color Safe](http://colorsafe.co/). -✅ Identifique un sitio web que sea muy problemático en el uso del color. ¿Por qué? +✅ Identifica un sitio web que sea muy problemático en el uso del color. ¿Por qué? ### Resaltar correctamente el texto -Resaltar texto por color, [peso de fuente](https://developer.mozilla.org/docs/Web/CSS/font-weight) u otra [decoración de texto](https://developer.mozilla.org/docs/Web/CSS/text-decoration) no informa inherentemente a un lector de pantalla de su importancia. Una palabra puede ser en negrita porque es una palabra clave o porque es la primera palabra y el diseñador decidió que debería ser en negrita. +Resaltar texto por color, [peso de fuente](https://developer.mozilla.org/docs/Web/CSS/font-weight) u otra [decoración de texto](https://developer.mozilla.org/docs/Web/CSS/text-decoration) no informa inherentemente a un lector de pantalla de su importancia. Una palabra puede estar en negrita porque es una palabra clave o porque es la primera palabra, y el diseñador decidió que debería estar en negrita. -Cuando sea necesario resaltar una frase en particular, utilice los elementos `<strong>` o `<em>`. Estos le indicarán a un lector de pantalla que esos elementos son importantes. +Cuando sea necesario resaltar una frase en particular, utilice los elementos `<strong>` o `<em>`. Estos te indicarán a un lector de pantalla que esos elementos son importantes. ### Usa el HTML correcto -Con CSS y JavaScript es posible que muchos elementos se parezcan a cualquier tipo de control. `<span>` podría usarse para crear un `<button>`, y `<b>` podría convertirse en un hipervínculo. Si bien esto podría considerarse más fácil de diseñar, es desconcertante para un lector de pantalla. Utilice el HTML apropiado al crear controles en una página. Si desea un hipervínculo, use `<a>`. Usar el HTML correcto para el control correcto se llama hacer uso de HTML semántico. +Con CSS y JavaScript es posible que muchos elementos se parezcan a cualquier tipo de control. `<span>` podría usarse para crear un `<button>`, y `<b>` podría convertirse en un enlace. Si bien esto podría considerarse más fácil de diseñar, es desconcertante para un lector de pantalla. Utiliza el HTML apropiado al crear controles en una página. Si deseas un enlace, usa `<a>`. Usar el HTML correcto para el control correcto se llama hacer uso de **HTML semántico**. -✅ Vaya a cualquier sitio web y vea si los diseñadores y desarrolladores están usando HTML correctamente. ¿Puedes encontrar un botón que debería ser un enlace? Sugerencia: haga clic derecho y elija 'View Page Source' en su navegador para ver el código subyacente. +✅ Vaya a cualquier sitio web y vea si los diseñadores y desarrolladores están usando HTML correctamente. ¿Puedes encontrar un botón que debería ser un enlace? Sugerencia: haga clic derecho y elige 'View Page Source' en tu navegador para ver el código subyacente. ### Usa buenas pistas visuales -CSS ofrece un control completo sobre el aspecto de cualquier elemento de una página. Puede crear cuadros de texto sin contorno o hipervínculos sin subrayado. Desafortunadamente, eliminar esas pistas puede hacer que sea más difícil para alguien que depende de ellas poder reconocer el tipo de control. +CSS ofrece un control completo sobre el aspecto de cualquier elemento de una página. Puedes crear cuadros de texto sin contorno o hipervínculos sin subrayado. Desafortunadamente, eliminar esas pistas puede hacer que sea más difícil para alguien que depende de ellas poder reconocer el tipo de control. ## La importancia del texto del enlace @@ -80,19 +80,19 @@ Como era de esperar, los lectores de pantalla leen el texto del enlace de la mis > El pequeño pingüino, a veces conocido como el pingüino de hadas, es el pingüino más pequeño del mundo. [Haga clic aquí](https://en.wikipedia.org/wiki/Little_penguin) para obtener más información. -> El pequeño pingüino, a veces conocido como el pingüino de hadas, es el pingüino más pequeño del mundo. Visite https://en.wikipedia.org/wiki/Little_penguin para obtener más información. +> El pequeño pingüino, a veces conocido como el pingüino de hadas, es el pingüino más pequeño del mundo. Visita https://en.wikipedia.org/wiki/Little_penguin para obtener más información. -> ** NOTA ** Mientras estás a punto de leer, ** nunca ** debes crear enlaces que se parezcan al anterior. +> **NOTA** Mientras estás a punto de leer, **nunca** debes crear enlaces que se parezcan al anterior. -Recuerde, los lectores de pantalla son una interfaz diferente de los navegadores con un conjunto diferente de características. +Recuerda, los lectores de pantalla son una interfaz diferente de los navegadores con diferentes características. -### El problema con el uso de la URL +### El problema con el uso de URLs -Los lectores de pantalla leen el texto. Si aparece una URL en el texto, el lector de pantalla leerá la URL. En términos generales, la URL no transmite información significativa y puede sonar molesta. Es posible que haya experimentado esto si su teléfono alguna vez leyó de manera audible un mensaje de texto con una URL. +Los lectores de pantalla leen el texto. Si aparece un URL en el texto, el lector de pantalla leerá el URL. En términos generales, un URL no transmite información significativa y puede sonar molesto. Es posible que hayas experimentado esto si tu teléfono alguna vez leyó de manera audible un mensaje de texto con un URL. ### El problema con "haga clic aquí" -Los lectores de pantalla también tienen la capacidad de leer solo los hipervínculos en una página, de la misma manera que una persona con visión escanea una página en busca de enlaces. Si el texto del vínculo es siempre "haga clic aquí", todo lo que el usuario oirá es "haga clic aquí, haga clic aquí, haga clic aquí, haga clic aquí, haga clic aquí, ..." Todos los enlaces ahora son indistinguibles entre sí. +Los lectores de pantalla también tienen la capacidad de leer solo los enlaces en una página, de la misma manera que una persona con visión escanea una página en busca de enlaces. Si el texto del vínculo es siempre "haga clic aquí", todo lo que el usuario oirá es "haga clic aquí, haga clic aquí, haga clic aquí, haga clic aquí, haga clic aquí, ..." Todos los enlaces ahora son indistinguibles entre sí. ### Buen texto de enlace @@ -100,11 +100,11 @@ Un buen texto de enlace describe brevemente lo que está al otro lado del enlace > El [pingüino pequeño](https://en.wikipedia.org/wiki/Little_penguin), a veces conocido como el pingüino de hadas, es el pingüino más pequeño del mundo. -✅ Navegue por la web durante unos minutos para encontrar páginas que utilicen estrategias de enlace poco conocidas. Compárelos con otros sitios mejor vinculados. ¿Qué aprendes? +✅ Navega la web unos minutos hasta encontrar páginas que utilicen estrategias de enlace poco conocidas. Compáralos con otros sitios que demuestren mejores enlaces. ¿Qué aprendiste? -#### Notas del motor de búsqueda +#### Notas sobre motores de búsqueda (search engines) -Como una ventaja adicional para garantizar que su sitio sea accesible para todos, también ayudará a los motores de búsqueda a navegar por su sitio. Los motores de búsqueda utilizan el texto del enlace para conocer los temas de las páginas. ¡Así que usar un buen texto de enlace ayuda a todos! +Además de la ventaja de que ahora tu sitio sea accesible para todos, también ayudas a los motores de búsqueda a navegar mejor tu sitio. Los motores de búsqueda utilizan el texto del enlace para conocer los temas de las páginas. ¡Así que usar un buen texto de enlace ayuda a todos! ### ARIA @@ -115,11 +115,11 @@ Imagina la siguiente página: | Widget | [Descripción]('#') | [Orden]('#') | | Super widget | [Descripción]('#') | [Orden]('#') | -En este ejemplo, duplicar el texto de descripción y orden tiene sentido para alguien que usa un navegador. Sin embargo, alguien que use un lector de pantalla solo escuchará las palabras * descripción * y * orden * repetidas sin contexto. +En este ejemplo, duplicar el texto de descripción y orden tiene sentido para alguien que usa un navegador. Sin embargo, alguien que use un lector de pantalla solo escuchará las palabras *descripción* y *orden* repetidas sin contexto. -Para admitir este tipo de escenarios, HTML admite un conjunto de atributos conocidos como [Aplicaciones de Internet enriquecidas accesibles (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Estos atributos le permiten proporcionar información adicional a los lectores de pantalla. +Para apoyar este tipo de escenarios, HTML apoya un conjunto de atributos conocidos como [Aplicaciones de Internet enriquecidas accesibles (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Estos atributos te permiten proporcionar información adicional a los lectores de pantalla. -> **NOTA**: Al igual que muchos aspectos de HTML, la compatibilidad con el navegador y el lector de pantalla puede variar. Sin embargo, la mayoría de los clientes de la línea principal admiten atributos ARIA. +> **NOTA**: Al igual que muchos aspectos de HTML, la compatibilidad con el navegador y el lector de pantalla pueden variar. Sin embargo, la mayoría de los clientes de la línea principal apoyan atributos ARIA. Puedes usar `aria-label` para describir el enlace cuando el formato de la página no te lo permite. La descripción del widget podría establecerse como @@ -127,14 +127,14 @@ Puedes usar `aria-label` para describir el enlace cuando el formato de la págin <a href="#" aria-label="Widget description">descripción</a> ``` -✅ En general, el uso de marcado semántico como se describe arriba reemplaza el uso de ARIA, pero a veces no existe un equivalente semántico para varios widgets HTML. Un buen ejemplo es una barra de progreso. No hay un equivalente HTML para una barra de progreso, por lo que identifica el `<div>` genérico para este elemento con un rol y valores de aria adecuados. La [documentación de MDN sobre ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) contiene más información útil. +✅ En general, el uso de HTML semántico como se describe arriba reemplaza el uso de ARIA, pero a veces no existe un equivalente semántico para varios widgets HTML. Un buen ejemplo es una barra de progreso. No hay un equivalente HTML para una barra de progreso, por lo que identifica el `<div>` genérico para este elemento con un rol y valores de aria adecuados. La [documentación de MDN sobre ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) contiene más información útil. ```html <div id="percent-loaded" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> </div> ``` -## Imagenes +## Imágenes No hace falta decir que los lectores de pantalla no pueden leer automáticamente lo que hay en una imagen. Asegurarse de que las imágenes sean accesibles no requiere mucho trabajo; de eso se trata el atributo ʻalt`. Todas las imágenes deben tener un ʻalt` para describir lo que son. @@ -142,74 +142,74 @@ No hace falta decir que los lectores de pantalla no pueden leer automáticamente ## El teclado -Algunos usuarios no pueden usar un mouse o trackpad, sino que dependen de las interacciones del teclado para pasar de un elemento al siguiente. Es importante que su sitio web presente su contenido en un orden lógico para que un teclado pueda acceder a cada elemento a medida que el usuario avanza por un documento. Si construye sus páginas web con marcado semántico y usa CSS para diseñar su diseño visual, su sitio debe ser navegable por teclado, pero es importante probar este aspecto manualmente. Obtenga más información sobre las [estrategias de navegación por teclado](https://webaim.org/techniques/keyboard/). +Algunos usuarios no pueden usar un mouse o trackpad, sino que dependen de las interacciones del teclado para pasar de un elemento al siguiente. Es importante que tu sitio web presente tu contenido en un orden lógico para que un teclado pueda acceder a cada elemento a medida que el usuario avanza por un documento. Si construyes tus páginas web con HTML semántico y usas CSS para diseñar tu diseño visual, tu sitio debe ser navegable por teclado, pero es importante comprobar este aspecto manualmente. Obtén más información sobre las [estrategias de navegación por teclado](https://webaim.org/techniques/keyboard/). -✅ Vaya a cualquier sitio web e intente navegar por él utilizando solo la tecla de tabulación. ¿Qué funciona, qué no funciona? ¿Por qué? +✅ Ve a cualquier sitio web e intenta navegar por él, utilizando solo la tecla de tabulación. ¿Qué funciona, qué no funciona? ¿Por qué? ## Resumen -Una web accesible para algunos no es una verdadera "red mundial". La mejor manera de garantizar que los sitios que cree sean accesibles es incorporar las mejores prácticas de accesibilidad desde el principio. Si bien hay pasos adicionales involucrados, incorporar estas habilidades en su flujo de trabajo ahora significará que todas las páginas que cree serán accesibles. +Una web accesible para algunos no es una verdadera "red mundial". La mejor manera de garantizar que los sitios que creas sean accesibles, es incorporar las mejores prácticas de accesibilidad desde el principio. Si bien hay pasos adicionales involucrados, incorporar estas habilidades en tu flujo de trabajo ahora significará que todas las páginas que creas sean accesibles. -🚀 Desafío: tome este HTML y vuelva a escribirlo para que sea lo más accesible posible, dados los temas que aprendió. +🚀 Desafío: toma este HTML y vuelve a escribirlo para que sea lo más accesible posible, dados los temas que aprendiste. ```html <!DOCTYPE html> <html> <head> <title> - Example + Ejemplo </title> <link href='../assets/style.css' rel='stylesheet' type='text/css'> </head> <body> <div class="site-header"> - <p class="site-title">Turtle Ipsum</p> - <p class="site-subtitle">The World's Premier Turtle Fan Club</p> + <p class="site-title">Tortuga Ipsum</p> + <p class="site-subtitle">El club de fans de tortugas más importante del mundo</p> </div> <div class="main-nav"> - <p class="nav-header">Resources</p> + <p class="nav-header">Recursos</p> <div class="nav-list"> - <p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"I like turtles"</a></p> - <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtle">Basic Turtle Info</a></p> - <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtles_(chocolate)">Chocolate Turtles</a></p> + <p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"Me gustan las tortugas"</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Tortuga">Info básico de tortugas</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Tortugas_(chocolate)">Tortugas de chocolate</a></p> </div> </div> <div class="main-content"> <div> - <p class="page-title">Welcome to Turtle Ipsum. - <a href="">Click here</a> to learn more. + <p class="page-title">Bienvenida a la Tortuga Ipsum. + <a href="">Haz clic aquí</a> para aprender más. </p> <p class="article-text"> - Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + Tortuga ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum </p> </div> </div> <div class="footer"> <div class="footer-section"> - <span class="button">Sign up for turtle news</span> + <span class="button">Regístrese para recibir 'Noticias Tortuga'</span> </div><div class="footer-section"> <p class="nav-header footer-title"> Internal Pages </p> <div class="nav-list"> - <p class="nav-item nav-item-bull"><a href="../">Index</a></p> - <p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p> + <p class="nav-item nav-item-bull"><a href="../">Índice</a></p> + <p class="nav-item nav-item-bull"><a href="../semantic">Ejemplo Semántico</a></p> </div> </div> - <p class="footer-copyright">© 2016 Instrument</span> + <p class="footer-copyright">© Instrument 2016</span> </div> </body> </html> ``` -## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6) +## [Post-lectura prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6) -## Revisión y autoestudio +## Revisión y auto-estudio -Muchos gobiernos tienen leyes sobre los requisitos de accesibilidad. Lea sobre las leyes de accesibilidad de su país de origen. ¿Qué está cubierto y qué no? Un ejemplo es [este sitio web del gobierno](https://accessibility.blog.gov.uk/). +Muchos gobiernos tienen leyes sobre los requisitos de accesibilidad. Lee sobre las leyes de accesibilidad de tu país de origen. ¿Qué está cubierto y qué no? Un ejemplo es [este sitio web de gobierno](https://accessibility.blog.gov.uk/). ** Tarea **: [Analizar un sitio web no accesible](assignment.es.md) -Credits: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) por Instrument +Créditos: [Tortuga Ipsum](https://github.com/Instrument/semantic-html-sample) por Instrument -> Autor: Christopher Harrison +> Autor: Christopher Harrison \ No newline at end of file diff --git a/1-getting-started-lessons/3-accessibility/translations/README.id.md b/1-getting-started-lessons/3-accessibility/translations/README.id.md index 2cd48518..d3238408 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.id.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.id.md @@ -1,6 +1,6 @@ # Membuat Halaman Web yang Dapat Diakses (oleh Semua Orang) - + > Catatan sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuis Pra-Kuliah @@ -25,7 +25,7 @@ Pada dasarnya, pembaca layar akan membaca halaman dari atas ke bawah dengan suar Setiap pengembang web harus membiasakan diri dengan pembaca layar. Seperti yang disorot di atas, itu adalah klien yang akan digunakan pengguna Anda. Sama seperti saat Anda memahami cara kerja browser, Anda juga harus mempelajari cara kerja pembaca layar. Untungnya, pembaca layar sudah terpasang di sebagian besar sistem operasi, dan banyak browser berisi ekstensi untuk meniru pembaca layar. -✅ Coba ekstensi atau alat browser pembaca layar. Salah satu yang hanya berfungsi di Windows adalah [JAWS](https://webaim.org/articles/jaws/). Peramban (browser) juga memiliki alat bawaan yang dapat digunakan untuk tujuan ini; lihat [alat browser Edge yang berfokus pada aksesibilitas ini](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features). +✅ Coba ekstensi atau alat browser pembaca layar. Salah satu yang hanya berfungsi di Windows adalah [JAWS](https://webaim.org/articles/jaws/). Peramban (browser) juga memiliki alat bawaan yang dapat digunakan untuk tujuan ini; lihat [alat browser Edge yang berfokus pada aksesibilitas ini](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). ### Pemeriksa kontras @@ -129,7 +129,7 @@ Anda dapat menggunakan `aria-label` untuk mendeskripsikan link jika format halam <a href="#" aria-label="Deskripsi widget">deskripsi</a> ``` -✅ Secara umum, menggunakan markup Semantik seperti yang dijelaskan di atas menggantikan penggunaan ARIA, tetapi terkadang tidak ada padanan semantik untuk berbagai widget HTML. Contoh yang bagus adalah Progressbar. Tidak ada HTML yang setara untuk bilah kemajuan, jadi Anda mengidentifikasi `<div>` generik untuk elemen ini dengan peran yang tepat dan nilai aria. [Dokumentasi MDN tentang ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) berisi informasi yang lebih berguna. +✅ Secara umum, menggunakan markup Semantik seperti yang dijelaskan di atas menggantikan penggunaan ARIA, tetapi terkadang tidak ada padanan semantik untuk berbagai widget HTML. Contoh yang bagus adalah Progressbar. Tidak ada HTML yang setara untuk bilah kemajuan, jadi Anda mengidentifikasi `<div>` generik untuk elemen ini dengan peran yang tepat dan nilai aria. [Dokumentasi MDN tentang ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) berisi informasi yang lebih berguna. ```html <div id="percent-loaded" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> diff --git a/1-getting-started-lessons/3-accessibility/translations/README.it.md b/1-getting-started-lessons/3-accessibility/translations/README.it.md index 5781d5ff..a4b5f051 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.it.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.it.md @@ -1,6 +1,6 @@ # Creare Pagine Web Accessibili - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione @@ -24,15 +24,15 @@ Nella sua forma più elementare, uno screen reader leggerà una pagina dall'alto Ogni sviluppatore web dovrebbe acquisire familiarità con uno screen reader. Come evidenziato sopra, è il client che gli utenti dello sviluppatore utilizzeranno. Allo stesso modo in cui si ha familiarità con il funzionamento di un browser, si dovrebbe imparare come funziona uno screen reader. Fortunatamente, gli screen reader sono integrati nella maggior parte dei sistemi operativi. -Alcuni browser hanno anche strumenti incorporati ed estensioni che possono leggere il testo ad alta voce o persino fornire alcune funzionalità di navigazione di base, come [questi strumenti orientati all'accessibilità del browser Edge](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features) . Anche questi sono importanti strumenti di accessibilità, ma funzionano in modo molto diverso dagli screen reader e non dovrebbero essere scambiati per strumenti di test per uno screen reader. +Alcuni browser hanno anche strumenti incorporati ed estensioni che possono leggere il testo ad alta voce o persino fornire alcune funzionalità di navigazione di base, come [questi strumenti orientati all'accessibilità del browser Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features) . Anche questi sono importanti strumenti di accessibilità, ma funzionano in modo molto diverso dagli screen reader e non dovrebbero essere scambiati per strumenti di test per uno screen reader. -✅ Provare un lettore di schermo e un lettore di testo del browser. In Windows, l'[Assistente vocale](https://support.microsoft.com/en-us/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1) (Narrator) è incluso per impostazione predefinita e anche [JAWS](https://webaim.org/articles/jaws/) e [NVDA](https://www.nvaccess.org/about-nvda/) possono essere installati Su macOS e iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) è installato per impostazione predefinita. +✅ Provare un lettore di schermo e un lettore di testo del browser. In Windows, l'[Assistente vocale](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1) (Narrator) è incluso per impostazione predefinita e anche [JAWS](https://webaim.org/articles/jaws/) e [NVDA](https://www.nvaccess.org/about-nvda/) possono essere installati Su macOS e iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) è installato per impostazione predefinita. ### Zoom -Un altro strumento comunemente utilizzato dalle persone con problemi di vista è lo zoom. Il tipo più semplice di zoom è lo zoom statico, controllato tramite `Control + segno più (+)` o diminuendo la risoluzione dello schermo. Questo tipo di zoom provoca il ridimensionamento dell'intera pagina, quindi l'utilizzo [di una progettazione responsive](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design) della pagina è importante per fornire una buona esperienza utente a livelli di zoom aumentati. +Un altro strumento comunemente utilizzato dalle persone con problemi di vista è lo zoom. Il tipo più semplice di zoom è lo zoom statico, controllato tramite `Control + segno più (+)` o diminuendo la risoluzione dello schermo. Questo tipo di zoom provoca il ridimensionamento dell'intera pagina, quindi l'utilizzo [di una progettazione responsive](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) della pagina è importante per fornire una buona esperienza utente a livelli di zoom aumentati. -Un altro tipo di zoom si basa su un software specializzato per ingrandire un'area dello schermo e fare una panoramica, proprio come usare una vera lente di ingrandimento. Su Windows, [Magnifier](https://support.microsoft.com/en-us/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) è integrato e [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) è un software di ingrandimento di terze parti con più funzionalità e una base di utenti più ampia. Sia macOS che iOS hanno un software di ingrandimento integrato chiamato [Zoom](https://www.apple.com/accessibility/mac/vision/). +Un altro tipo di zoom si basa su un software specializzato per ingrandire un'area dello schermo e fare una panoramica, proprio come usare una vera lente di ingrandimento. Su Windows, [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) è integrato e [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) è un software di ingrandimento di terze parti con più funzionalità e una base di utenti più ampia. Sia macOS che iOS hanno un software di ingrandimento integrato chiamato [Zoom](https://www.apple.com/accessibility/mac/vision/). ### Verificatori di contrasto @@ -133,7 +133,7 @@ E' possibile utilizzare `aria-label` per descrivere il collegamento quando il fo <a href="#" aria-label="Widget description">description</a> ``` -✅ In generale, l'uso del markup semantico come descritto sopra sostituisce l'uso di ARIA, ma a volte non esiste un equivalente semantico per diversi widget HTML. Un buon esempio è una struttura ad albero. Non esiste un equivalente HTML per una struttura ad albero, quindi si identifica il generico `<div>` per questo elemento con un ruolo e valori aria appropriati. La [documentazione MDN su ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) contiene ulteriori utili informazioni. +✅ In generale, l'uso del markup semantico come descritto sopra sostituisce l'uso di ARIA, ma a volte non esiste un equivalente semantico per diversi widget HTML. Un buon esempio è una struttura ad albero. Non esiste un equivalente HTML per una struttura ad albero, quindi si identifica il generico `<div>` per questo elemento con un ruolo e valori aria appropriati. La [documentazione MDN su ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) contiene ulteriori utili informazioni. ```html <h2 id="tree-label">File Viewer</h2> @@ -223,6 +223,6 @@ Molti governi hanno leggi riguardanti i requisiti di accessibilità. Consultare ## Assegnazione -[Analizzare un sito web non accessibile](assignment.md) +[Analizzare un sito web non accessibile](assignment.it.md) Crediti: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) da Instrument \ No newline at end of file diff --git a/1-getting-started-lessons/3-accessibility/translations/README.ja.md b/1-getting-started-lessons/3-accessibility/translations/README.ja.md index f30838d3..c2a31987 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.ja.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.ja.md @@ -1,6 +1,6 @@ # アクセシブルな Web ページの作成 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/1-getting-started-lessons/3-accessibility/translations/README.ko.md b/1-getting-started-lessons/3-accessibility/translations/README.ko.md index ada79dda..fed53308 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.ko.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.ko.md @@ -1,6 +1,6 @@ # 접근 가능한 웹 페이지 생성하기 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -24,7 +24,7 @@ 모든 웹 개발자는 스크린 리더에 익숙해야합니다. 위에서 강조한 것처럼 사용자가 활용할 클라이언트입니다. 브라우저가 작동하는 방식에 익숙한 것과 마찬가지로 스크린 리더가 작동하는 방식을 배워야합니다. 다행히 스크린 리더는 대부분의 운영체제에 내장되어 있으며, 많은 브라우저에는 스크린 리더를 모방하는 확장이 포함되어 있습니다. -✅ 스크린 리더 브라우저 확장이나 도구를 시도해보세요.[JAWS](https://webaim.org/articles/jaws/)는 윈도우에서만 작동합니다. 브라우저에는 이러한 목적으로 사용할 수 있는 내장 도구도 있습니다; [these accessibility-focused Edge browser tools](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features) 확인합니다. +✅ 스크린 리더 브라우저 확장이나 도구를 시도해보세요.[JAWS](https://webaim.org/articles/jaws/)는 윈도우에서만 작동합니다. 브라우저에는 이러한 목적으로 사용할 수 있는 내장 도구도 있습니다; [these accessibility-focused Edge browser tools](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features) 확인합니다. ### Contrast checkers @@ -127,7 +127,7 @@ CSS는 페이지에 있는 모든 요소의 형태를 완벽하게 제어합니 <a href="#" aria-label="Widget description">description</a> ``` -✅ 일반적으로, 위에서 설명한 시맨틱 마크업을 사용하는 것은 ARIA의 사용을 대체하지만, 때때로 다양한 HTML 위젯에 해당하는 시맨틱이 없습니다. 좋은 예는 Progressbar입니다. 진행률 표시줄에 해당하는 HTML이 없으므로 적절한 역할 및 aria 값을 사용하여 일반 `<div>`를 식별합니다. [AMDN documentation on ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA)에 더 유용한 정보가 포함되어 있습니다. +✅ 일반적으로, 위에서 설명한 시맨틱 마크업을 사용하는 것은 ARIA의 사용을 대체하지만, 때때로 다양한 HTML 위젯에 해당하는 시맨틱이 없습니다. 좋은 예는 Progressbar입니다. 진행률 표시줄에 해당하는 HTML이 없으므로 적절한 역할 및 aria 값을 사용하여 일반 `<div>`를 식별합니다. [AMDN documentation on ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)에 더 유용한 정보가 포함되어 있습니다. ```html <div id="percent-loaded" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> diff --git a/1-getting-started-lessons/3-accessibility/translations/README.ms.md b/1-getting-started-lessons/3-accessibility/translations/README.ms.md index 20afd58f..47071921 100644 --- a/1-getting-started-lessons/3-accessibility/translations/README.ms.md +++ b/1-getting-started-lessons/3-accessibility/translations/README.ms.md @@ -1,6 +1,6 @@ # Membuat Halaman Web yang Boleh Diakses - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -24,7 +24,7 @@ Pada asasnya, pembaca skrin akan membaca halaman dari atas ke bawah dengan diden Setiap pembangun web harus membiasakan diri dengan pembaca skrin. Seperti yang dinyatakan di atas, ini adalah pelanggan yang akan digunakan pengguna anda Sama seperti anda mengetahui bagaimana penyemak imbas beroperasi, anda harus mengetahui cara pembaca skrin beroperasi. Nasib baik pembaca skrin dimasukkan ke dalam kebanyakan sistem operasi, dan banyak penyemak imbas mengandungi sambungan untuk meniru pembaca skrin. -✅ Cuba pelanjutan atau alat penyemak imbas pembaca skrin. Yang hanya berfungsi pada Windows ialah [JAWS](https://webaim.org/articles/jaws/). Penyemak imbas juga mempunyai alat bawaan yang dapat digunakan untuk tujuan ini; cuba [alat penyemak imbas Edge yang berfokus kebolehaksesan ini](https://support.microsoft.com/en-us/help/4000734/microsoft-edge-accessibility-features). +✅ Cuba pelanjutan atau alat penyemak imbas pembaca skrin. Yang hanya berfungsi pada Windows ialah [JAWS](https://webaim.org/articles/jaws/). Penyemak imbas juga mempunyai alat bawaan yang dapat digunakan untuk tujuan ini; cuba [alat penyemak imbas Edge yang berfokus kebolehaksesan ini](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). ### Pemeriksa Kontras @@ -127,7 +127,7 @@ Anda boleh menggunakan `aria-label` untuk menerangkan pautan apabila format hala <a href="#" aria-label="Widget description">description</a> ``` -✅ Secara umum, menggunakan markup Semantik seperti yang dijelaskan di atas menggantikan penggunaan ARIA, tetapi kadang-kadang tidak ada yang setara dengan semantik untuk pelbagai widget HTML. Contoh yang baik ialah Progressbar. Tidak ada setara HTML untuk bar kemajuan, jadi anda mengenal pasti generik `<div>` untuk elemen ini dengan peranan dan nilai aria yang betul. [MDN documentation on ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) mengandungi maklumat yang lebih berguna. +✅ Secara umum, menggunakan markup Semantik seperti yang dijelaskan di atas menggantikan penggunaan ARIA, tetapi kadang-kadang tidak ada yang setara dengan semantik untuk pelbagai widget HTML. Contoh yang baik ialah Progressbar. Tidak ada setara HTML untuk bar kemajuan, jadi anda mengenal pasti generik `<div>` untuk elemen ini dengan peranan dan nilai aria yang betul. [MDN documentation on ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) mengandungi maklumat yang lebih berguna. ```html <div id="percent-loaded" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> diff --git a/1-getting-started-lessons/3-accessibility/translations/README.nl.md b/1-getting-started-lessons/3-accessibility/translations/README.nl.md new file mode 100644 index 00000000..d2e3017f --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/README.nl.md @@ -0,0 +1,229 @@ +# Toegankelijke webpagina's maken + + +> Sketchnote door [Tomomi Imura](https://twitter.com/girlie_mac) + +## Quiz voorafgaand aan de lezing +[Quiz voorafgaand aan de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5) + +> De kracht van het web zit in zijn universaliteit. Toegang voor iedereen, ongeacht hun handicap, is een essentieel aspect. +> +> \- Sir Timothy Berners-Lee, W3C-directeur en uitvinder van het World Wide Web + +Deze quote benadrukt perfect het belang van het creëren van toegankelijke websites. Een applicatie die niet voor iedereen toegankelijk is, is per definitie uitsluiting. Als webontwikkelaars moeten we altijd rekening houden met toegankelijkheid. Door deze focus vanaf het begin te hebben, bent u goed op weg om ervoor te zorgen dat iedereen toegang heeft tot de pagina's die u maakt. In deze les leert u over de tools die u kunnen helpen ervoor te zorgen dat uw webitems toegankelijk zijn en hoe u kunt bouwen met toegankelijkheid in gedachten. + +## Tools om te gebruiken + +### Schermlezers + +Een van de bekendste toegankelijkheidstools zijn schermlezers. + +[Schermlezers](https://nl.wikipedia.org/wiki/Schermlezer) zijn veelgebruikte clients voor mensen met een visuele beperking. Omdat we er tijd voor besteden om ervoor te zorgen dat een browser de informatie die we willen delen correct overbrengt, moeten we er ook voor zorgen dat een schermlezer hetzelfde doet. + +In de basis leest een schermlezer een pagina hoorbaar van boven naar beneden. Als uw pagina alleen uit tekst bestaat, zal de lezer de informatie op dezelfde manier overbrengen naar een browser. Webpagina's zijn natuurlijk zelden louter tekst; ze bevatten links, afbeeldingen, kleur en andere visuele componenten. Er moet voor worden gezorgd dat deze informatie correct wordt gelezen door een schermlezer. + +Elke webontwikkelaar moet vertrouwd raken met een schermlezer. Zoals hierboven aangegeven, is het de client die uw gebruikers zullen gebruiken. Net zoals u bekend bent met hoe een browser werkt, moet u leren hoe een schermlezer werkt. Gelukkig zijn schermlezers in de meeste besturingssystemen ingebouwd. + +Sommige browsers hebben ook ingebouwde tools en extensies die tekst hardop kunnen voorlezen of zelfs enkele basisnavigatiefuncties bieden, zoals [deze op toegankelijkheid gerichte Edge-browserhulpmiddelen](https://support.microsoft.com/nl-nl/microsoft-edge/toegankelijkheidsfuncties-in-microsoft-edge-4c696192-338e-9465-b2cd-bd9b698ad19a). Dit zijn ook belangrijke toegankelijkheidstools, maar ze werken heel anders dan schermlezers en ze mogen niet worden aangezien voor testtools voor schermlezers. + +✅ Probeer een schermlezer en browsertekstlezer. Op Windows is [Narrator](https://support.microsoft.com/nl-nl/windows/volledige-handleiding-voor-verteller-e4397a0d-ef4f-b386-d8ae-c172f109bdb1) standaard inbegrepen, en [JAWS](https://webaim.org/articles/jaws/) en [NVDA](https://www.nvaccess.org/about-nvda/) kunnen ook worden geïnstalleerd. Op macOS en iOS is [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) standaard geïnstalleerd. + +### Zoom + +Een ander hulpmiddel dat vaak wordt gebruikt door mensen met een visuele beperking, is zoomen. De meest basale manier van zoomen is statische zoom, bestuurd via `Control + plusteken (+)` of door de schermresolutie te verlagen. Dit type zoom zorgt ervoor dat het formaat van de hele pagina wordt aangepast, dus het gebruik van [responsive design](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design) is belangrijk om een goede gebruikerservaring te bieden bij verhoogde zoomniveaus. + +Een ander type zoom is afhankelijk van gespecialiseerde software om een deel van het scherm te vergroten en te pannen, net zoals bij het gebruik van een echt vergrootglas. Op Windows is [Magnifier](https://support.microsoft.com/nl-nl/windows/vergrootglas-gebruiken-voor-een-betere-zichtbaarheid-op-het-scherm-414948ba-8b1c-d3bd-8615-0e5e32204198) ingebouwd en [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) is vergrotingssoftware van derden met meer functies en een groter gebruikersbestand. Zowel macOS als iOS hebben ingebouwde vergrotingssoftware genaamd [Zoom](https://www.apple.com/nl/accessibility/vision/). + +### Contrast checkers + +Kleuren op websites moeten zorgvuldig worden gekozen om tegemoet te komen aan de behoeften van kleurenblinde gebruikers of mensen die moeite hebben met het zien van kleuren met een laag contrast. + +✅ Test een website die u graag gebruikt voor kleurgebruik met een browserextensie zoals [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US). Wat leer je? + +### Lighthouse + +In het ontwikkelaarstoolgedeelte van uw browser vindt u de Lighthouse-tool. Deze tool is belangrijk om een eerste beeld te krijgen van de toegankelijkheid (en ook andere analyses) van een website. Hoewel het belangrijk is om niet uitsluitend op Lighthouse te vertrouwen, is een score van 100% erg nuttig als uitgangspunt. + +✅ Zoek Lighthouse in het ontwikkelaarstoolpaneel van uw browser en voer een analyse uit op elke site. wat ontdek je? + +## Ontwerpen voor toegankelijkheid + +Toegankelijkheid is een relatief groot onderwerp. Om u te helpen, zijn er tal van bronnen beschikbaar. + +- [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers) + +Hoewel we niet elk aspect van het maken van toegankelijke sites kunnen behandelen, staan hieronder enkele van de kernprincipes die u wilt implementeren. Het ontwerpen van een toegankelijke pagina vanaf het begin is **altijd** gemakkelijker dan teruggaan naar een bestaande pagina om deze toegankelijk te maken. + +## Goede weergaveprincipes + +### Kleur veilige paletten + +Mensen zien de wereld op verschillende manieren, inclusief kleuren. Wanneer u een kleurenschema voor uw site selecteert, moet u ervoor zorgen dat het voor iedereen toegankelijk is. Een geweldig [hulpmiddel voor het genereren van kleurenpaletten is Color Safe](http://colorsafe.co/). + +✅ Identificeer een website die erg problematisch is in het gebruik van kleur. Waarom? + +### Gebruik de juiste HTML + +Met CSS en JavaScript is het mogelijk om elk element eruit te laten zien als elk type besturingselement. `<span>` kan worden gebruikt om een `<button>` te maken en `<b>` kan een hyperlink worden. Hoewel dit misschien als gemakkelijker te stylen wordt beschouwd, brengt het niets over op een schermlezer. Gebruik de juiste HTML bij het maken van besturingselementen op een pagina. Als u een hyperlink wilt, gebruik dan `<a>`. Het gebruik van de juiste HTML voor de juiste besturing wordt het gebruik van Semantische HTML genoemd. + +✅ Ga naar een website en kijk of de ontwerpers en ontwikkelaars HTML correct gebruiken. Kunt u een button vinden die een link zou moeten zijn? Tip: klik met de rechtermuisknop en kies 'View Page Source' in uw browser om de onderliggende code te bekijken. + +### Maak een beschrijvende kophiërarchie + +Gebruikers van schermlezers [zijn sterk afhankelijk van koppen](https://webaim.org/projects/screenreadersurvey8/#finding) om informatie te vinden en door een pagina te navigeren. Het schrijven van beschrijvende koptekst en het gebruik van semantische koptags zijn belangrijk voor het maken van een gemakkelijk navigeerbare site voor gebruikers van schermlezers. + +### Gebruik goede visuele aanwijzingen + +CSS biedt volledige controle over het uiterlijk van elk element op een pagina. U kunt tekstvakken zonder omtreklijn of hyperlinks zonder onderstreping maken. Helaas kan het verwijderen van die aanwijzingen het voor iemand die van hen afhankelijk is, uitdagender maken om het type controle te herkennen. + +## Het belang van linktekst + +Hyperlinks zijn essentieel voor het navigeren op internet. Als gevolg hiervan kunnen alle gebruikers door uw site navigeren door ervoor te zorgen dat een schermlezer links correct kan lezen. + +### Schermlezers en links + +Zoals u zou verwachten, lezen schermlezers linktekst op dezelfde manier als andere tekst op de pagina. Met dit in gedachten kan de onderstaande tekst volkomen acceptabel aanvoelen. + +> De Dwergpinguïn, ook wel bekend als de sprookjespinguïn, is de kleinste pinguïn ter wereld. [Klik hier](https://nl.wikipedia.org/wiki/Dwergpingu%C3%AFn) voor meer informatie. + +> De Dwergpinguïn, ook wel bekend als de sprookjespinguïn, is de kleinste pinguïn ter wereld. Bezoek https://nl.wikipedia.org/wiki/Dwergpingu%C3%AFn voor meer informatie. + +> **OPMERKING** Zoals u gaat lezen, moet u **nooit** links maken die er als hierboven uitzien. + +Onthoud dat schermlezers een andere interface zijn dan browsers met een andere set functies. + +### Het probleem met het gebruik van de URL + +Schermlezers lezen de tekst. Als er een URL in de tekst voorkomt, leest de schermlezer de URL. Over het algemeen geeft de URL geen zinvolle informatie over en kan deze vervelend klinken. Mogelijk heeft u dit ondervonden als uw telefoon ooit een sms-bericht met een URL hoorbaar heeft gelezen. + +### Het probleem met "klik hier" + +Schermlezers hebben ook de mogelijkheid om alleen de hyperlinks op een pagina te lezen, net zoals een ziende een pagina zou scannen op links. Als de linktekst altijd "klik hier" is, hoort de gebruiker alleen "klik hier, klik hier, klik hier, klik hier, klik hier, ..." Alle links zijn nu niet meer van elkaar te onderscheiden. + +### Goede linktekst + +Een goede linktekst beschrijft in het kort wat er aan de andere kant van de link staat. In het bovenstaande voorbeeld over Dwergpinguïns, is de link naar de Wikipedia-pagina over de soort. De zin *Dwergpinguïns* zou zorgen voor perfecte linktekst, omdat het duidelijk maakt wat iemand zal leren als ze op de link klikken - Dwergpinguïns. + +> De [Dwergpinguïn](https://nl.wikipedia.org/wiki/Dwergpingu%C3%AFn), ook wel bekend als de sprookjespinguïn, is de kleinste pinguïn ter wereld. + +✅ Surf een paar minuten op internet om pagina's te vinden die obscure koppelingsstrategieën gebruiken. Vergelijk ze met andere, beter gekoppelde sites. Wat leer je? + +#### Aantekeningen bij zoekmachines + +Als extra bonus om ervoor te zorgen dat uw site voor iedereen toegankelijk is, helpt u zoekmachines ook bij het navigeren op uw site. Zoekmachines gebruiken linktekst om de onderwerpen van pagina's te leren. Het gebruik van goede linkteksten helpt dus iedereen! + +### ARIA + +Stelt u de volgende pagina voor: + +| Product | beschrijving | Volgorde | +| ------------ | ------------------ | ------------ | +| Widget | [beschrijving]('#') | [Volgorde]('#') | +| Super widget | [beschrijving]('#') | [Volgorde]('#') | + +In dit voorbeeld is het zinvol om de tekst van de beschrijving en volgorde te dupliceren voor iemand die een browser gebruikt. Iemand die een schermlezer gebruikt, hoort echter alleen de woorden *beschrijving* en *volgorde* herhaald zonder context. + +Om dit soort scenario's te ondersteunen, ondersteunt HTML een set attributen die bekend staan als [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA). Met deze attributen kunt u aanvullende informatie verstrekken aan schermlezers. + +> **OPMERKING**: Zoals veel aspecten van HTML, kan de ondersteuning van browser en schermlezer variëren. De meeste mainline-clients ondersteunen echter ARIA-attributen. + +U kunt `aria-label` gebruiken om de link te beschrijven als het formaat van de pagina dat niet toestaat. De beschrijving voor widget kan worden ingesteld als + +``` html +<a href="#" aria-label="Widget description">beschrijving</a> +``` + +✅ Over het algemeen vervangt het gebruik van semantische opmaak zoals hierboven beschreven het gebruik van ARIA, maar soms is er geen semantisch equivalent voor verschillende HTML-widgets. Een goed voorbeeld is een boom. Er is geen HTML-equivalent voor een boomstructuur, dus identificeert u de generieke `<div>` voor dit element met een juiste rol en aria-waarden. De [MDN-documentatie over ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) bevat meer nuttige informatie. + +```html +<h2 id="tree-label">File Viewer</h2> +<div role="tree" aria-labelledby="tree-label"> + <div role="treeitem" aria-expanded="false" tabindex="0">Uploads</div> +</div> +``` + +## Afbeeldingen + +Het spreekt voor zich dat schermlezers niet automatisch kunnen lezen wat er in een afbeelding staat. Ervoor zorgen dat afbeeldingen toegankelijk zijn, kost niet veel werk - daar gaat het bij het `alt`-attribuut om. Alle betekenisvolle afbeeldingen moeten een `alt` hebben om te beschrijven wat ze zijn. +Voor afbeeldingen die puur decoratief zijn, moet het `alt`-attribuut worden ingesteld op een lege tekenreeks: `alt=""`. Hiermee wordt voorkomen dat schermlezers de decoratieve afbeelding onnodig aankondigen. + +✅ Zoals u zou verwachten, kunnen zoekmachines ook niet begrijpen wat er in een afbeelding staat. Ze gebruiken ook alt-tekst. Dus nogmaals, ervoor zorgen dat uw pagina toegankelijk is, levert extra bonussen op! + +## Het toetsenbord + +Sommige gebruikers kunnen geen muis of trackpad gebruiken, maar vertrouwen op toetsenbordinteracties om van het ene element naar het andere te gaan. Het is belangrijk dat uw website uw inhoud in een logische volgorde presenteert, zodat een toetsenbordgebruiker toegang heeft tot elk interactief element terwijl ze door een document bladeren. Als u uw webpagina's bouwt met semantische opmaak en CSS gebruikt om hun visuele lay-out op te maken, moet uw site toetsenbord-navigeerbaar zijn, maar het is belangrijk om dit aspect handmatig te testen. Meer informatie over [strategieën voor toetsenbordnavigatie](https://webaim.org/techniques/keyboard/). + +✅ Ga naar een website en probeer er doorheen te navigeren met alleen uw toetsenbord. Wat werkt, wat werkt niet? Waarom? + +## Overzicht + +Een web dat voor sommigen toegankelijk is, is niet echt een 'world-wide web'. De beste manier om ervoor te zorgen dat de sites die u maakt, toegankelijk zijn, is door vanaf het begin de best practices voor toegankelijkheid op te nemen. Hoewel er extra stappen bij betrokken zijn, betekent het opnemen van deze vaardigheden in uw workflow dat alle pagina's die u maakt, toegankelijk zijn. + +--- + +## 🚀 Uitdaging + +Neem deze HTML en herschrijf deze zodat deze zo toegankelijk mogelijk is, gezien de strategieën die u hebt geleerd. + +```html +<!DOCTYPE html> +<html> + <head> + <title> + Example + </title> + <link href='../assets/style.css' rel='stylesheet' type='text/css'> + </head> + <body> + <div class="site-header"> + <p class="site-title">Turtle Ipsum</p> + <p class="site-subtitle">The World's Premier Turtle Fan Club</p> + </div> + <div class="main-nav"> + <p class="nav-header">Resources</p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"I like turtles"</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtle">Basic Turtle Info</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtles_(chocolate)">Chocolate Turtles</a></p> + </div> + </div> + <div class="main-content"> + <div> + <p class="page-title">Welcome to Turtle Ipsum. + <a href="">Click here</a> to learn more. + </p> + <p class="article-text"> + Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + </p> + </div> + </div> + <div class="footer"> + <div class="footer-section"> + <span class="button">Sign up for turtle news</span> + </div><div class="footer-section"> + <p class="nav-header footer-title"> + Internal Pages + </p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="../">Index</a></p> + <p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p> + </div> + </div> + <p class="footer-copyright">© 2016 Instrument</span> + </div> + </body> +</html> +``` + +## Quiz na de lezing +[Quiz na de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6) + +## Beoordeling en zelfstudie + +Veel regeringen hebben wetten met betrekking tot toegankelijkheidseisen. Lees de toegankelijkheidswetten van uw thuisland. Wat wordt er gedekt en wat niet? Een voorbeeld is [deze overheidswebsite](https://accessibility.blog.gov.uk/). + +## Toewijzing + +[Analyseer een niet-toegankelijke website](assignment.nl.md) + +Credits: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) door instrument diff --git a/1-getting-started-lessons/3-accessibility/translations/README.zh-cn.md b/1-getting-started-lessons/3-accessibility/translations/README.zh-cn.md new file mode 100644 index 00000000..c2e9c18c --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/README.zh-cn.md @@ -0,0 +1,228 @@ +# 创造无障碍网页 + + +> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac) + +## 课前小测 +[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5?loc=zh_cn) + +> 互联网的力量存在于其普适性中,让包括残障人士在内的每个人都能访问互联网,是其中不可或缺的一方面。 +> +> —— Timothy Berners-Lee, W3C(万维网联盟)主席、万维网发明者 + +这段引言恰当地强调了创造无障碍网页的重要性。一个无法被所有人顺畅访问的应用按照定义来说是排他的,作为 Web 开发者我们应该始终将无障碍性牢记在心中。从一开始就关注到这一点,可以让你在确保每个人都能顺利访问你创造的页面这一方面做得很优秀。这节课中,你会了解到一些能帮助你确保你的网站资源无障碍的工具,也会学到该怎样将无障碍性牢记在心中。 + +## 相关工具 + +### 屏幕阅读器(Screen readers) + +屏幕阅读器可以说是最知名的无障碍工具之一。 + +[屏幕阅读器](https://zh.wikipedia.org/wiki/%E8%9E%A2%E5%B9%95%E9%96%B1%E8%AE%80%E5%99%A8)在视力障碍者中被广泛使用。就像我们会花时间来确保浏览器正确地传达了我们想要分享的信息, 我们也必须要确保屏幕阅读器也可以达到同样的效果。 + +一般来说,屏幕阅读器会从上到下用语音阅读一个页面。如果你的页面全是文字,阅读器传达信息的方式和浏览器会是基本相似的。当然,网页几乎不会只有文字,还会包含链接、图像、颜色以及其他视觉组件。我们也必须得确保这些信息可以被屏幕阅读器正确阅读。 + +每一位 Web 开发者都需要去熟悉屏幕阅读器。正如上面强调的一样,这是你的用户会用到的一种客户端。就像你很熟悉浏览器的操作一样,你也应该去学习如何操作屏幕阅读器。幸运的是,多数操作系统都内置了屏幕阅读器。 + +一些浏览器也有内置的工具和扩展程序,可以读出文字甚至提供一些基本的导航功能,比如[这些以无障碍为目的的 Edge 浏览器工具](https://support.microsoft.com/zh-cn/microsoft-edge/microsoft-edge-%E4%B8%AD%E7%9A%84%E8%BE%85%E5%8A%A9%E5%8A%9F%E8%83%BD-4c696192-338e-9465-b2cd-bd9b698ad19a)。这些也是重要的无障碍工具,但是工作方式和屏幕阅读器非常不同,所以不该被错误地用来作为屏幕阅读器的测试工具。 + +✅ 试用一下屏幕阅读器和浏览器文本阅读器。在 Windows 系统中默认带有[讲述人](https://support.microsoft.com/zh-cn/windows/%E8%AE%B2%E8%BF%B0%E4%BA%BA%E5%AE%8C%E6%95%B4%E6%8C%87%E5%8D%97-e4397a0d-ef4f-b386-d8ae-c172f109bdb1),也可以安装 [JAWS](https://webaim.org/articles/jaws/) 和 [NVDA](https://www.nvaccess.org/about-nvda/)。在 macOS 和 iOS 中默认装有[旁白](https://support.apple.com/zh-cn/guide/voiceover/welcome/10)。 + +### 缩放(Zoom) + +另一个视力障碍者常用的工具是缩放。最基本的缩放功能是静态缩放,通过 `Control + 加号(+)` 或者降低屏幕分辨率达成。这样的缩放会导致整个页面尺寸被调整,所以使用[响应式设计(responsive design)](https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Responsive_Design)对于提高了缩放级别的情况下的用户体验非常重要。 + +另一类缩放需要借助特定的软件来放大屏幕上的部分区域,就像一个真正的放大镜一样。在 Windows 上内置了[放大镜](https://support.microsoft.com/zh-cn/windows/%E4%BD%BF%E7%94%A8%E6%94%BE%E5%A4%A7%E9%95%9C%E5%8F%AF%E4%BD%BF%E5%B1%8F%E5%B9%95%E4%B8%8A%E7%9A%84%E5%86%85%E5%AE%B9%E6%9B%B4%E6%98%93%E4%BA%8E%E6%9F%A5%E7%9C%8B-414948ba-8b1c-d3bd-8615-0e5e32204198),也可以使用 [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) 这样有更多特性和更大用户群体的第三方软件。在 macOS 和 iOS 上则内置了[放大器](https://www.apple.com.cn/accessibility/vision/) + +### 对比度检查器(Contrast checkers) + +我们要谨慎地挑选网页上的配色,以照顾到色盲人群和难以区分低对比度颜色的用户的需要。 + +✅ 用类似 [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=zh-CN) 这样的浏览器插件来检测一下你喜爱的网站的颜色使用情况。你学到了什么? + +### Lighthouse + +在浏览器开发者工具中,你可以找到 Lighthouse 工具。这个工具可以让你一睹一个网站的无障碍性(以及其他性能分析)。尽管并不建议完全依赖 Lighthouse,但将 100% 满分作为一个基础将会很有用。 + +✅ 在你的浏览器开发者工具中找到 Lighthouse 栏,然后用它分析任何一个网站。你发现了什么? + +## Designing for accessibility + +无障碍性(accessibility)是一个相对比较大的主题,为了帮助你更深入地了解,这里许多你可以参考的资源。 + +- [Accessible U - 明尼苏达大学](https://accessibility.umn.edu/your-role/web-developers) + +尽管我们没法在这里涵盖创建一个无障碍网站的方方面面,但下面还是提供了一些你会想要去实践的核心信条。从一开始就设计一个无障碍页面**总是**比回过头来让一个已经存在的页面变得无障碍会更容易。 + +## 不错的展示原则 + +### 使用安全色色板 + +每个人看待世界的方式都不尽相同,当然也包括颜色。当你为你的站点选择一套配色时,应该确保其对所有人都是无障碍的。这里有一个非常棒的[生成安全色色板的工具](http://colorsafe.co/)。 + +✅ 举出一个配色非常糟糕的网站的例子。你认为它糟糕在哪? + +### 正确使用 HTML + +使用 CSS 和 JavaScript 有能力让任何元素看起来在控制效果上是任何一种类型的元素。比如 `<span>` 可以被用来创建出一个 `<button>`,而 `<b>` 则可能会被弄成一个超链接。尽管有人可能认为这样会更加容易调整样式,但是它不会传达任何有效信息给屏幕阅读器。请使用合适的 HTML 来建立对于页面的控制效果,比如你想要一个超链接,请使用 `<a>` 标签。用正确的 HTML 来实现正确的控制效果,这就叫做实践了“语义化 HTML”(Semantic HTML)。 + +✅ 去任意一个网站看看设计师和开发者是否合理使用了 HTML。你能不能找出一个本该是链接的按钮?提示:在浏览器中右键点击并且选择“查看网页源代码”来查看底层代码(译注:此处使用“检查”/“审查元素”来观察或许会更加合适)。 + +### 建立描述性的标题层级 + +屏幕阅读器使用者为了寻找信息和在页面中导航,会[非常依赖页面中的标题](https://webaim.org/projects/screenreadersurvey8/#finding)。使用描述性的标题内容和语义化的标题标签,对于创建一个对屏幕阅读器使用者友好的网站是非常重要的。 + +### 使用良好的视觉线索 + +CSS 让你可以完全随意地控制页面中任何元素的外观。你可以创建一个没有轮廓的文本框或者一个没有下划线的超链接。但不幸的是,移除这些视觉线索会让一些习惯依靠这些线索的使用者难以认出它们的控制功能。 + +## 链接文本的重要性 + +对于网页导航来说,超链接非常关键。因此,确保屏幕阅读器可以准确阅读链接才能保证所有用户都可以顺利地在你的网站导航。 + +### 屏幕阅读器与链接 + +可想而知,屏幕阅读器会像阅读页面中其他文本一样阅读链接的文本。将这点牢记在心后,可以看看下面两种看起来似乎还能接受的写法。 + +> 小蓝企鹅,有时也被称作仙企鹅,是世界上最小的企鹅。[点击这里](https://zh.wikipedia.org/wiki/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D)来查看更多信息。 + +> 小蓝企鹅,有时也被称作仙企鹅,是世界上最小的企鹅。访问 https://zh.wikipedia.org/wiki/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D 来查看更多信息。 + +> **注意** 下文即将提到,你应该 **避免** 使用上面这两种写法。 + +记住,屏幕阅读器和浏览器功能上有一些差异,是不同的交互媒介。 + +### 使用 URL 的问题 + +屏幕阅读器会阅读文本,如果 URL 出现在了文本里,屏幕阅读器就会直接读出这段 URL。一般来说,URL 直接传递的信息都意义不大,而且听起来会很吵。如果你曾经在手机中将一段包含 URL 的文字用语音播放出来,就可能有类似体会。 + +### 使用“点击这里”的问题 + +屏幕阅读器也有只阅读页面中超链接的功能,就仿佛一个有视力的人扫视页面来找到所有链接一样。如果所有的链接文本都是“点击这里”,用户听到的就会一直是“点击这里,点击这里,点击这里,点击这里,点击这里……”,完全无法区分各个链接。 + +### 优秀的链接文本 + +优秀的链接文本会简要地描述链接另一侧是什么。在上面谈论小蓝企鹅的例子中,链接到的是关于这个物种的维基百科页面。使用*小蓝企鹅*作为链接文本将会非常合适,因为它能清楚地告诉人们如果他们点击了这个链接会了解到什么 —— 小蓝企鹅。 + +> [小蓝企鹅](https://zh.wikipedia.org/wiki/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D),有时也被称作仙企鹅,是世界上最小的企鹅。 + +✅ 上网随便逛几分钟,找一找使用了难以理解的链接策略的网页。对比一下其他有更好的链接的网站,你有何体会? + +#### 关于搜索引擎 + +保证你的网站对所有人都无障碍还能带来一个额外的好处:可以帮助搜索引擎导航你的网站。搜索引擎会使用链接文本来了解页面的主题,所以使用好的链接文本其实利人利己! + +### ARIA + +想象一个下面这样的网页: + +| 产品 | 详情 | 预订 | +| ------------ | ------------------ | ------------ | +| 小玩意 | [详情]('#') | [预订]('#') | +| 超棒的小玩意 | [详情]('#') | [预订]('#') | + +在这个例子中,复制“详情”和“预订”这两个文本对于使用浏览器的用户来说是没有理解障碍的。然而,使用屏幕阅读器的用户则只会听到对 *详情* 和 *预订* 这两个词的两次毫无上下文的复读。 + +为了处理这类情况,HTML 支持一些被称为 [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA) 的属性。这些属性让你可以为屏幕阅读提供一些额外的信息。 + +> **注意**:正如 HTML 的其他方面一样,浏览器和屏幕阅读器对 ARIA 的支持情况可能会不同,但是多数主流客户端都是支持 ARIA 属性的。 + +当页面格式不允许你直接用文本描述链接时,你可以使用 `aria-label` 属性来对链接进行描述。对于一个小玩意的详情描述可以被设置为: + +``` html +<a href="#" aria-label="小玩意的详情">详情</a> +``` + +✅ 一般来说,使用此前提到的语义化标签会比使用 ARIA 更好,但是有时确实存在没法找到合适的语义标签来描述一些 HTML 元素。比如“树”,没有和“树”语义等价的 HTML 标签,所以你可以给这个元素选用一般的 `<div>` 标签,然后加上合理的 role 和 aria 属性值。[MDN ARIA 文档](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA)有更多有用的相关信息。 + +```html +<h2 id="tree-label">文件查看器</h2> +<div role="tree" aria-labelledby="tree-label"> + <div role="treeitem" aria-expanded="false" tabindex="0">上传</div> +</div> +``` + +## 图像 + +毫无疑问,屏幕阅读器是没法自动阅读图像内容的,但是让图像变得无障碍并不会很麻烦 —— 这正是 `alt` 属性所做的事。所有有意义的图像都应该有一个 `alt` 属性来描述它们的内容是什么。纯装饰性的图像应该有一个被设为空字符串的 `alt` 属性:`alt=""`,这样可以防止屏幕阅读器画蛇添足地描述这些装饰性图像。 + +✅ 没错,搜索引擎也无法理解图片的内容,它们也会使用 alt 属性中的文本。这又一次证明,确保你的页面无障碍可以带来额外的好处! + +## 键盘 + +一些用户没法使用鼠标或者触控板,而是只能依赖键盘交互来从一个元素切换到下一个元素。在你的网站上以有逻辑的顺序来展示内容是很重要的,这样一来键盘用户可以在往下浏览页面时访问到每一个可交互元素。如果你用你语义化标签来构建页面并且用 CSS 来控制它们的视觉外观,你的页面就应该会是可用键盘导航的,但是最好还是手动测试一遍。可在[键盘导航策略](https://webaim.org/techniques/keyboard/)了解更多关于这方面的内容。 + +✅ 前往任意一个网站然后尝试只使用你的键盘来导航。哪些可以正常使用?哪些不可以?为什么? + +## 总结 + +只有部分人才能顺利访问的网页算不上真正的万维网(world-wide web)。确保你创造的网站无障碍地最好方式就是从一开始就贯彻无障碍的最佳实践。尽管这可能会引入额外的步骤,但现在就将这些技术包含在你的工作流程中将意味着你创造的所有页面都会是无障碍的。 + +--- + +## 🚀 挑战 + +利用你学到的策略,尽可能将下方的 HTML 代码重写为无障碍的。 + +```html +<!DOCTYPE html> +<html> + <head> + <title> + Example + </title> + <link href='../assets/style.css' rel='stylesheet' type='text/css'> + </head> + <body> + <div class="site-header"> + <p class="site-title">Turtle Ipsum</p> + <p class="site-subtitle">The World's Premier Turtle Fan Club</p> + </div> + <div class="main-nav"> + <p class="nav-header">Resources</p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"I like turtles"</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtle">Basic Turtle Info</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtles_(chocolate)">Chocolate Turtles</a></p> + </div> + </div> + <div class="main-content"> + <div> + <p class="page-title">Welcome to Turtle Ipsum. + <a href="">Click here</a> to learn more. + </p> + <p class="article-text"> + Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + </p> + </div> + </div> + <div class="footer"> + <div class="footer-section"> + <span class="button">Sign up for turtle news</span> + </div><div class="footer-section"> + <p class="nav-header footer-title"> + Internal Pages + </p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="../">Index</a></p> + <p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p> + </div> + </div> + <p class="footer-copyright">© 2016 Instrument</span> + </div> + </body> +</html> +``` + +## 课后小测 +[课后小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6?loc=zh_cn) + +## 复习 & 自学 + +许多政府有关于无障碍要求的法律,阅读一下你的国家与无障碍相关的法律。它涉及了哪些方面,又有哪些方面没有涉及?[这个政府网站](https://accessibility.blog.gov.uk/)是一个例子。 + +## 作业 + +[分析一个非无障碍网站](assignment.zh-cn.md) + +参考:[Turtle Ipsum](https://github.com/Instrument/semantic-html-sample),作者:Instrument diff --git a/1-getting-started-lessons/3-accessibility/translations/README.zh-tw.md b/1-getting-started-lessons/3-accessibility/translations/README.zh-tw.md new file mode 100644 index 00000000..cbb85d2a --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/README.zh-tw.md @@ -0,0 +1,231 @@ +# 建立無障礙網頁 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/5?loc=zh_tw) + +> 網路的強大在於它的普遍性。無論用戶是否有殘疾,讓大家無差別地使用網路是必要的。 +> +> The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect. +> +> \- Tim Berners-Lee 爵士 ── 全球資訊網協會總監暨網際網路創立者 + +這段話完美地詮釋建立無障礙網頁的重要性。應用程式若無法服務所有人是建立在排他性設計。身為一位網頁開發員,我們需要時刻警惕著網頁親和力。從此時開始,你接下來創建的網頁要能服務給任何人。在這堂課中,你會學習開發無障礙網頁相關的工具與觀念。 + +## 相關工具 + +### 螢幕報讀器 (Screen readers) + +螢幕報讀器可說是最知名的無障礙工具之一。 + +[螢幕報讀器](https://zh.wikipedia.org/wiki/%E8%9E%A2%E5%B9%95%E9%96%B1%E8%AE%80%E5%99%A8)已被廣泛地幫助視覺障礙者。就像我們花了不少時間確保瀏覽器能呈現網頁內容,我們也要確保螢幕報讀器能完整地實現相同的工作。 + +基本上,螢幕報讀器會一行一行地報讀網頁的內容。若網頁都是以文字建構而成,那螢幕報讀器就能達到與瀏覽器相同的功效。當然,網頁不可能只有文字:裡面可能會有連結、圖像、顏色或是其他視覺物件。我們必須確保螢幕報讀器也能呈現出上述物件。 + +任何一位網頁開發者需要熟悉螢幕報讀器。它們是用戶的好幫手,就像你的瀏覽器一樣,你需要學習螢幕報讀器是如何運作的。幸運的是,它們都內建在大部分的作業系統當中。 + +有些瀏覽器內建相關工具與擴充插件,報讀出文字甚至是可互動物件:例如[這些以網頁親和力為目標的 Edge 瀏覽器工具](https://support.microsoft.com/zh-tw/microsoft-edge/microsoft-edge-%E7%9A%84%E5%8D%94%E5%8A%A9%E5%B7%A5%E5%85%B7%E5%8A%9F%E8%83%BD-4c696192-338e-9465-b2cd-bd9b698ad19a)。 它們是重要的輔助工具,或許與螢幕報讀器有所差異,但基本上能測試螢幕報讀器的基本功能。 + +✅ 嘗試使用螢幕報讀器或瀏覽器朗讀工具。 在 Windows 中,[Narrator](https://support.microsoft.com/zh-tw/windows/%E5%AE%8C%E6%95%B4%E7%9A%84%E6%9C%97%E8%AE%80%E7%A8%8B%E5%BC%8F%E6%8C%87%E5%8D%97-e4397a0d-ef4f-b386-d8ae-c172f109bdb1)內建在系統中,使用者也可以選擇[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/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design)是縮放頁面重要的一環。 + +其他放大功能會專注在小部分的區域上,這些額外軟體提供類似於實體放大器的功能。 Windows 內建[放大器](https://support.microsoft.com/zh-tw/windows/%E4%BD%BF%E7%94%A8%E6%94%BE%E5%A4%A7%E9%8F%A1%E4%BB%A5%E8%AE%93%E8%9E%A2%E5%B9%95%E4%B8%8A%E7%9A%84%E5%85%A7%E5%AE%B9%E6%9B%B4%E5%AE%B9%E6%98%93%E7%9C%8B%E5%88%B0-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's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=zh-tw)。 你學到了什麼? + +### Lighthouse + +在瀏覽器的開發者工具中,你能找到一款工具名為 Lighthouse。這項工具可以有效的確認網頁親和力。這邊不強制網頁都要經過 Lighthouse 審核,但 100% 的分數是網頁完美的基礎。 + +✅ 在你的瀏覽器開發工具中找尋 Lighthouse ,對任何網頁做分析。 你發現了什麼? + +## 提升網頁親和力 + +網頁親和力是項相對龐大的主體。要尋求幫助,網路上有許多資源可以參考。 + +- [Accessible U - 明尼蘇達大學](https://accessibility.umn.edu/your-role/web-developers) + +我們無法在此說明建立無障礙網頁的所有重點,但下列是開發時重要的核心觀念。從零開始就留意網頁親和力**一定會比**從完成的網頁來增進網頁親和力來的容易。 + +## 良好的呈現方式 + +### 安全的配色 + +每個人的觀點都有所不同,包含觀看顏色。如何選擇配色也是網頁親和力的課題之一。下列是一款實用的[安全配色生產工具](http://colorsafe.co/). + +✅ 舉出在配色上有問題的一個網頁,告訴大家為什麼? + +### 使用合理的 HTML 語法 + +在 CSS 與 JavaScript 的支援下,我們無法判斷網頁物件的控制目的。 好比 `<span>` 也可以建立 `<button>`, `<b>` 可以代表超連結。 在造型變化上或許較為容易,但可能會對螢幕報讀器產生混淆。我們必須確保對應的控制有相同的標籤,例如超連結只使用 `<a>`。這才能完整的表現 HTML 的語義化。 + +✅ 去任何一個網頁分析開發員與設計員是否使用正確的 HTML 語法。 你能找到語法將連結取代成按鈕嗎? 小提示:在瀏覽器中點擊「右鍵」 > 「檢視網頁原始碼」來確認程式碼。 + +### 建立分級的描述性標題的 + +螢幕報讀器使用者[非常仰賴文字標題](https://webaim.org/projects/screenreadersurvey8/#finding),確認並查詢網頁資訊。使用描述性標題並有層次的標籤分別得以創建出較易閱讀的網頁。 + +### 使用合理的視覺指引 + +CSS 提供完整的網頁造型控制,你可以讓文字框框線隱藏或是讓超連結去除底線。然而去除這些視覺指引會造成視覺障礙者閱讀上的困擾,難以辨別它們原本的功能性。 + +## 連結文字的重要性 + +超連結是網頁中重點物件。請確保螢幕報讀器能正確的辨識網頁中的超連結。 + +### 螢幕報讀器處理連結 + +可想而知,螢幕報讀器對於連結與文字的朗讀方式是相同的。因此,判斷下列文章例子,哪個對於網頁親和力上較為合理? + +> 小藍企鵝,又稱做仙企鵝,是世界上最小的企鵝。[點擊這裡](https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D)了解更多資訊。 + +> 小藍企鵝,又稱做仙企鵝,是世界上最小的企鵝。造訪 https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D 了解更多資訊。 + +> **注意** 讀完之後,請盡量**避免**上方的連結例子。 + +記得,螢幕報讀器處理物件的方式會與瀏覽器有所不同。 + +### 使用 URL 的問題 + +螢幕報讀器會朗讀文字。如果 URL 出現在文章中,它也會被裝置朗讀。綜觀來說,朗讀 URL 不含有任何意義,而且聽來不悅耳。你可能曾在手機上聽過含有網址的文章朗讀。 + +### 使用「點擊這裡」的問題 + +螢幕報讀器有能力去處理超連結文字,就像我們尋找網頁中的連結一樣。想像所有的超連結文字都表示成「點擊這裡」,用戶就會重複聽到「點擊這裡!點擊這裡!點擊這裡!點擊這裡......」,會造成別人的困擾。 + +### 合理的連結文字 + +合理的連結文字為連結與文字找到了平衡。像上方例子中的小藍企鵝,連結是導向維基百科的物種頁面。文字*小藍企鵝*就會是完美的連結文字,讓用戶了解點擊後會取得關於小藍企鵝的相關資訊。 + +> [小藍企鵝](https://zh.wikipedia.org/zh-tw/%E5%B0%8F%E8%97%8D%E4%BC%81%E9%B5%9D),又稱做仙企鵝,是世界上最小的企鵝。 + +✅ 花點時間逛逛網頁,觀察它們如何設定連結的導向。比較較合適的連結文字,你學到了什麼? + +#### 關於搜尋引擎 + +網頁中的搜尋引擎對網頁親和力有加分的效果,搜尋引擎也能從連結找到你的網頁,了解網頁的主題。所以連結文字對大家都有幫助! + +### ARIA + +想像下方的網頁: + +| 產品 | 描述 | 數量 | +| ------------ | ----------- | ----------- | +| 物品 | [描述]('#') | [數量]('#') | +| 超優物品 | [描述]('#') | [數量]('#') | + +在這項舉例中,瀏覽器用戶可以清楚地辨別重複性的「描述」與「數量」;但對於螢幕報讀器用戶而言,他們只能重複地聽取*「描述」與「數量」*這兩個單詞。 + +為了處理這種情況,HTML 提供一套屬性名為[Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)。它能為螢幕報讀器附加額外的朗讀資訊。 + +> **注意**: 就如 HTML 的各式物件,瀏覽器與螢幕報讀器能支援的項目也不盡相同。然而,客群主體基本上都支援 ARIA 屬性。 + +若網頁不支援部分格式語法,你可以使用 `aria-label` 來描述連結。就如下方物件被標註上 "Widget description" 的標籤。 + +``` html +<a href="#" aria-label="Widget description">description</a> +``` + +✅ 總體而言,使用語義化標籤得以取代 ARIA 功能,但是這些標籤無法全面性地覆蓋 HTML 的各式物件。樹(Tree)就是一種例子。沒有 HTML 物件能處理一棵樹,所以你可以在 `<div>` 元素中加上 aria 數值。[關於 ARIA 的 MDN 技術文件](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA)說明許多有用的資訊。 + +```html +<h2 id="tree-label">File Viewer</h2> +<div role="tree" aria-labelledby="tree-label"> + <div role="treeitem" aria-expanded="false" tabindex="0">Uploads</div> +</div> +``` + +## 圖片 + +螢幕報讀器用戶無法直接的了解圖片內容。為了確保圖片也能服務給視覺障礙者,這就是 `alt` 屬性存在的目的。所有重要的圖片都需要有 `alt` 描述圖片的內容。 +裝飾性圖片的 `alt` 欄位就需要留空字串:`alt=""`。 這樣能避免螢幕報讀器朗讀不必要的裝飾性圖片敘述。 + +✅ 你可能會猜到,搜尋引擎也有可能無法辨別圖片。它們也是使用 alt 敘述。因此,無障礙網頁有許多加分要素! + +## 鍵盤輸入 + +有些用戶無法使用滑鼠或觸控板,他們需要使用鍵盤中的 "tab" 鍵來切換網頁元素,讓網頁物件能順序性地排列與互動就很重要。如果網頁有語義化標籤並以CSS造型化視覺畫面,網頁基本上就能以鍵盤來切換,當然手動測試還是必要的。了解更多關於[鍵盤調查的策略](https://webaim.org/techniques/keyboard/)。 + +✅ 前往任何一個網頁,試著只以鍵盤瀏覽網頁。哪些能成功運作,你又遭遇了哪些困難? 你有辦法解釋嗎? + +## 結論 + +能連上網頁並不是網際網路的真諦。從現在起確保網頁能以無障礙的方式呈現。雖然還有很多未被提及的開發資訊,熟習你知道的無障礙開發知識一定會對網頁有所幫助。 + +--- + +## 🚀 挑戰 + +看看下列的 HTML 程式碼。利用你所學到的知識,試著增進它的網頁親和力。 + +```html +<!DOCTYPE html> +<html> + <head> + <title> + Example + </title> + <link href='../assets/style.css' rel='stylesheet' type='text/css'> + </head> + <body> + <div class="site-header"> + <p class="site-title">Turtle Ipsum</p> + <p class="site-subtitle">The World's Premier Turtle Fan Club</p> + </div> + <div class="main-nav"> + <p class="nav-header">Resources</p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"I like turtles"</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtle">Basic Turtle Info</a></p> + <p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtles_(chocolate)">Chocolate Turtles</a></p> + </div> + </div> + <div class="main-content"> + <div> + <p class="page-title">Welcome to Turtle Ipsum. + <a href="">Click here</a> to learn more. + </p> + <p class="article-text"> + Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + </p> + </div> + </div> + <div class="footer"> + <div class="footer-section"> + <span class="button">Sign up for turtle news</span> + </div><div class="footer-section"> + <p class="nav-header footer-title"> + Internal Pages + </p> + <div class="nav-list"> + <p class="nav-item nav-item-bull"><a href="../">Index</a></p> + <p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p> + </div> + </div> + <p class="footer-copyright">© 2016 Instrument</span> + </div> + </body> +</html> +``` + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/6?loc=zh_tw) + +## 複習與自學 + +許多政府機關立法要求無障礙需求。查詢你的國家是否有這些法規。它們涉及了那些,那些又沒包含在其中? 看看[英國政府機關網頁](https://accessibility.blog.gov.uk/)的例子。 + +## 作業 + +[分析一個非無障礙網頁](assignment.zh-tw.md) + +參考出處: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) diff --git a/1-getting-started-lessons/3-accessibility/translations/assignment.es.md b/1-getting-started-lessons/3-accessibility/translations/assignment.es.md index a13e9ba6..9ee2f5ac 100644 --- a/1-getting-started-lessons/3-accessibility/translations/assignment.es.md +++ b/1-getting-started-lessons/3-accessibility/translations/assignment.es.md @@ -2,11 +2,11 @@ ## Instrucciones -Identifique un sitio web que crea que NO es accesible y cree un plan de acción para mejorar su accesibilidad. Su primera tarea sería identificar este sitio, detallar las formas en que cree que es inaccesible sin usar herramientas analíticas y luego someterlo a un análisis Lighthouse. Tome los resultados de este análisis y describa un plan detallado con un mínimo de diez puntos que muestre cómo se podría mejorar el sitio. +Identifica un sitio web que creas que NO es accesible y crea un plan de acción para mejorar su accesibilidad. Tu primer tarea será identificar este sitio, detallar las formas en que crees que es inaccesible sin usar herramientas analíticas y luego someterlo a un análisis Lighthouse. Toma los resultados de este análisis y describe un plan detallado con un mínimo de diez puntos que muestre cómo se podría mejorar el sitio. ## Rúbrica -| Criterios | Ejemplar | Adecuada | Necesita mejorar | +| Criterios | Ejemplar | Adecuado | Necesita mejorar | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------- | | informe del estudiante | incluye párrafos sobre cómo el sitio es inadecuado, el informe Lighthouse capturado como un pdf, una lista de diez puntos para mejorar, con detalles sobre cómo mejorarlo | falta el 20% de lo requerido | falta el 50% de lo requerido | \ No newline at end of file diff --git a/1-getting-started-lessons/3-accessibility/translations/assignment.nl.md b/1-getting-started-lessons/3-accessibility/translations/assignment.nl.md new file mode 100644 index 00000000..6136278b --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Analyseer een niet-toegankelijke website + +## Instructies + +Identificeer een website waarvan u denkt dat deze NIET toegankelijk is, en maak een actieplan om de toegankelijkheid ervan te verbeteren. Uw eerste taak zou zijn om deze site te identificeren, de manieren te beschrijven waarop u denkt dat deze ontoegankelijk is zonder analytische tools te gebruiken, en deze vervolgens door een Lighthouse-analyse te laten gaan. Neem de resultaten van deze analyse en maak een gedetailleerd plan met minimaal tien punten waaruit blijkt hoe de site kan worden verbeterd. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------- | +| studentenrapport | bevat paragrafen over hoe de site ontoereikend is, het Lighthouse-rapport vastgelegd als pdf, een lijst met tien punten die verbeterd kunnen worden, met details over hoe deze te verbeteren | ontbreekt 20% van de vereiste | ontbreekt 50% van de vereiste | \ No newline at end of file diff --git a/1-getting-started-lessons/3-accessibility/translations/assignment.zh-cn.md b/1-getting-started-lessons/3-accessibility/translations/assignment.zh-cn.md new file mode 100644 index 00000000..c2a7f290 --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/assignment.zh-cn.md @@ -0,0 +1,11 @@ +# 分析一个非无障碍网站 + +## 说明 + +找到一个你认为无障碍性做得不好的网站,制定一个提升其无障碍性的计划表。你的第一个任务是找到这样一个网站,并在不借助分析工具的前提下详细指出你认为它无障碍做得不好的方面,然后再使用 Lighthouse 分析工具来分析它。借助分析的结果,制定一个包含至少十点的改进该网站的详细计划。 + +## 评价表 + +| 标准 | 优秀 | 良好 | 尚可进步 | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------- | +| 书面报告 | 解释了这个网站做得不好的地方,将 Lighthouse 报告打印为 PDF 文件,至少十点可改进之处,每点详细说明了改进策略 | 缺少上述 20% 内容 | 缺少上述 50% 内容 | diff --git a/1-getting-started-lessons/3-accessibility/translations/assignment.zh-tw.md b/1-getting-started-lessons/3-accessibility/translations/assignment.zh-tw.md new file mode 100644 index 00000000..ac89b664 --- /dev/null +++ b/1-getting-started-lessons/3-accessibility/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 分析一個非無障礙網頁 + +## 說明 + +辨別一個你認為對視覺障礙者不友善的網頁,列出網頁改進的策略。你需要先發掘各個網頁,不使用分析工具的情況下判斷網頁的親和力,再套用到 Lighthouse 審核工具。將網頁的審核結果轉化成至少十點的改進計畫。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ----------------------------------------------------------------------------------- | --------------- | --------------- | +| 書面報告 | 文章解釋為何網頁需要被改進,將 Lighthouse 結果轉成 pdf 檔,列出十點詳細的改進計畫。 | 缺少 20% 的內容 | 缺少 50% 的內容 | \ No newline at end of file diff --git a/1-getting-started-lessons/translations/README.fr.md b/1-getting-started-lessons/translations/README.fr.md new file mode 100644 index 00000000..712f40b6 --- /dev/null +++ b/1-getting-started-lessons/translations/README.fr.md @@ -0,0 +1,17 @@ +# Premiers pas avec le développement Web + +Dans cette section du programme, vous serez initié à des concepts non basés sur des projets importants pour devenir un développeur professionnel. + +### theme + +1. [Introduction aux langages de programmation et aux outils du métier](1-intro-to-programming-languages/README.md) +2. [Bases de GitHub](2-github-basics/README.md) +3. [Bases de l'accessibilité](3-accessibility/README.md) + +### Crédits + +Bases de l'accessibilité a été écrit avec ♥ ️ par [Christopher Harrison](https://twitter.com/geektrainer) + +L'introduction à GitHub a été écrite avec ♥ ️ par [Floor Drees](https://twitter.com/floordrees) + +L'introduction aux langages de programmation et aux outils du métier a été écrite avec ♥ ️ par [Jasmine Greenaway](https://twitter.com/paladique) diff --git a/1-getting-started-lessons/translations/README.nl.md b/1-getting-started-lessons/translations/README.nl.md new file mode 100644 index 00000000..811e2f97 --- /dev/null +++ b/1-getting-started-lessons/translations/README.nl.md @@ -0,0 +1,17 @@ +# Aan de slag met webontwikkeling + +In dit deel van het curriculum maakt u kennis met niet-projectgebaseerde concepten die belangrijk zijn om een professionele ontwikkelaar te worden. + +### Onderwerpen + +1. [Inleiding tot programmeertalen en tools van het vak](../1-intro-to-programming-languages/translations/README.nl.md) +2. [Basisprincipes van GitHub](../2-github-basics/translations/README.nl.md) +3. [Basisprincipes van toegankelijkheid](../3-accessibility/translations/README.nl.md) + +### Credits + +Basisprincipes van toegankelijkheid is geschreven met ♥ door [Christopher Harrison](https://twitter.com/geektrainer) + +Inleiding tot GitHub is geschreven met ♥ ️door [Floor Drees](https://twitter.com/floordrees) + +Inleiding tot programmeertalen en tools van het vak is geschreven met ♥ ️door [Jasmine Greenaway](https://twitter.com/paladique) diff --git a/1-getting-started-lessons/translations/README.zh-cn.md b/1-getting-started-lessons/translations/README.zh-cn.md new file mode 100644 index 00000000..8cd5cbe4 --- /dev/null +++ b/1-getting-started-lessons/translations/README.zh-cn.md @@ -0,0 +1,17 @@ +# 开始 Web 开发 + +在课程的这一部分,我们会通过不编写代码的方式介绍一些概念,这些概念对于成为一位专业的开发者非常重要。 + +### 主题 + +1. [编程语言概述与工具介绍](../1-intro-to-programming-languages/translations/README.zh-cn.md) +2. [GitHub 基础知识](../2-github-basics/translations/README.zh-cn.md) +3. [无障碍性基础知识](../3-accessibility/translations/README.zh-cn.md) + +### 参考 + +无障碍性基础知识由 [Christopher Harrison](https://twitter.com/geektrainer) 用 ♥️ 编写 + +GitHub 基础知识由 [Floor Drees](https://twitter.com/floordrees) 用 ♥️ 编写 + +编程语言概述与工具介绍由 [Jasmine Greenaway](https://twitter.com/paladique) 用 ♥️ 编写 diff --git a/1-getting-started-lessons/translations/README.zh-tw.md b/1-getting-started-lessons/translations/README.zh-tw.md new file mode 100644 index 00000000..f17c7e23 --- /dev/null +++ b/1-getting-started-lessons/translations/README.zh-tw.md @@ -0,0 +1,17 @@ +# 網頁開發入門 + +這段課程會說明重要的程式開發觀念,不會以程式碼為導向,讓你成為出色的開發人員。 + +### 主題 + +1. [程式語言概論與必備工具](../1-intro-to-programming-languages/translations/README.zh-tw.md) +2. [GitHub 簡介](../2-github-basics/translations/README.zh-tw.md) +3. [建立無障礙網頁](../3-accessibility/translations/README.zh-tw.md) + +### 參與人員 + +文章「無障礙網頁」是由 [Christopher Harrison](https://twitter.com/geektrainer) 用滿滿的 ♥️ 來編寫。 + +文章「GitHub 簡介」是由 [Floor Drees](https://twitter.com/floordrees) 用滿滿的 ♥️ 來編寫。 + +文章「建立無障礙網頁」是由 [Jasmine Greenaway](https://twitter.com/paladique) 用滿滿的 ♥️ 來編寫。 diff --git a/2-js-basics/1-data-types/README.md b/2-js-basics/1-data-types/README.md index ddee1284..c1ecefcb 100644 --- a/2-js-basics/1-data-types/README.md +++ b/2-js-basics/1-data-types/README.md @@ -1,6 +1,6 @@ # JavaScript Basics: Data Types - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -176,7 +176,7 @@ Booleans can be only two values: `true` or `false`. Booleans can help make decis - `let myTrueBool = true` - `let myFalseBool = false` -✅ A variable can be considered 'truthy' if it evaluates to a boolean `true`. Interestingly, in JavaScript, [all values are truthy unless defined as falsy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ A variable can be considered 'truthy' if it evaluates to a boolean `true`. Interestingly, in JavaScript, [all values are truthy unless defined as falsy](https://developer.mozilla.org/docs/Glossary/Truthy). --- diff --git a/2-js-basics/1-data-types/translations/README.de.md b/2-js-basics/1-data-types/translations/README.de.md index 0193b6d3..b4eb8b8d 100644 --- a/2-js-basics/1-data-types/translations/README.de.md +++ b/2-js-basics/1-data-types/translations/README.de.md @@ -178,7 +178,7 @@ Boolesche Werte können nur zwei Werte sein: `true` oder `false`. Boolesche Wert - `let myTrueBool = true` - `let myFalseBool = false` -✅ Eine Variable kann als "wahr" betrachtet werden, wenn sie als boolescher Wert "wahr" ausgewertet wird. Interessanterweise sind in JavaScript [alle Werte wahr, sofern sie nicht als falsch definiert sind](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ Eine Variable kann als "wahr" betrachtet werden, wenn sie als boolescher Wert "wahr" ausgewertet wird. Interessanterweise sind in JavaScript [alle Werte wahr, sofern sie nicht als falsch definiert sind](https://developer.mozilla.org/docs/Glossary/Truthy). --- ---. diff --git a/2-js-basics/1-data-types/translations/README.es.md b/2-js-basics/1-data-types/translations/README.es.md index 01e1c92f..c2f288d4 100644 --- a/2-js-basics/1-data-types/translations/README.es.md +++ b/2-js-basics/1-data-types/translations/README.es.md @@ -1,8 +1,11 @@ # Conceptos básicos de JavaScript: tipos de datos + +> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) + [](https://youtube.com/watch?v=rEHV3fFMfn0 "Tipos de datos en JavaScript") -## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7) +## [Pre-lectura prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7) Esta lección cubre los conceptos básicos de JavaScript, el lenguaje que proporciona interactividad en la web. @@ -21,7 +24,7 @@ Crear y **declarar** una variable tiene la siguiente sintaxis **[keyword] [name] ### Tarea - trabajar con variables -1. **Declare una variable**. Declaremos una variable usando la palabra clave `let`: +1. **Declara una variable**. Declaremos una variable usando la palabra clave `let`: ```javascript let myVariable; @@ -39,7 +42,7 @@ Crear y **declarar** una variable tiene la siguiente sintaxis **[keyword] [name] `myVariable` ahora se ha *inicializado* con el valor 123. -1. **Refactor**. Reemplace su código con la siguiente declaración. +1. **Refactorizar código**. Reemplace su código con la siguiente declaración. ```javascript let myVariable = 123; @@ -66,9 +69,9 @@ La declaración e inicialización de una constante sigue los mismos conceptos qu const MY_VARIABLE = 123; ``` -CLas constantes son similares a las variables, con dos excepciones: +Las constantes son similares a las variables, con dos excepciones: -- **Debe tener un valor**. Las constantes deben inicializarse o se producirá un error al ejecutar el código. +- **Deben tener un valor**. Las constantes deben inicializarse o se producirá un error al ejecutar el código. - **La referencia no se puede cambiar**. La referencia de una constante no se puede cambiar una vez inicializada, o se producirá un error al ejecutar el código. Veamos dos ejemplos: - **Valor simple**. NO se permite lo siguiente: @@ -78,11 +81,11 @@ CLas constantes son similares a las variables, con dos excepciones: PI = 4; // no permitido ``` - - **La referencia de objeto está protegida**. NO se permite lo siguiente. + - **La referencia del objeto está protegida**. NO se permite lo siguiente. ```javascript const obj = { a: 3 }; - obj = { b: 5 } // o permitido + obj = { b: 5 } // no permitido ``` - **El valor del objeto no está protegido**. Se permite lo siguiente: @@ -94,7 +97,7 @@ CLas constantes son similares a las variables, con dos excepciones: Arriba está cambiando el valor del objeto pero no la referencia en sí, lo que lo permite. - > Tenga en cuenta que una `const` significa que la referencia está protegida contra la reasignación. Sin embargo, el valor no es _immutable_ y puede cambiar, especialmente si es una construcción compleja como un objeto. + > Tenga en cuenta que `const` significa que la referencia está protegida contra la reasignación. Sin embargo, el valor no es _immutable_ y puede cambiar, especialmente si es una construcción compleja como un objeto. ## Tipos de datos @@ -120,52 +123,52 @@ Hay varios tipos de operadores que se pueden utilizar al realizar funciones arit | `-` | **Resta**: Calcula la diferencia de dos números | `1 - 2 //la respuesta esperada es -1` | | `*` | **Multiplicación**: Calcula el producto de dos números | `1 * 2 //la respuesta esperada es 2` | | `/` | **División**: Calcula el cociente de dos números | `1 / 2 //la respuesta esperada es 0.5` | -| `%` | **Resto**: Calcula el resto a partir de la división de dos números | `1 % 2 //la respuesta esperada es 1` | +| `%` | **Restante**: Calcula el resto a partir de la división de dos números | `1 % 2 //la respuesta esperada es 1` | ✅ ¡Pruébalo! Pruebe una operación aritmética en la consola de su navegador. ¿Te sorprenden los resultados? -### Cadenas +### String -Las cadenas son conjuntos de caracteres que residen entre comillas simples o dobles. +Las cadenas (Strings) son conjuntos de caracteres que residen entre comillas simples o dobles. -- `'Esto es una cadena'` -- `"Esto también es una cadena"` -- `let myString = 'Este es un valor de cadena almacenado en una variable';` +- `'Esto es un String'` +- `"Esto también es un String"` +- `let myString = 'Este es un valor del String almacenado en una variable';` -Recuerde utilizar comillas al escribir una cadena, de lo contrario JavaScript asumirá que es un nombre de variable. +Recuerde utilizar comillas al escribir un String, de lo contrario JavaScript asumirá que es un nombre de variable. -### Formateo de cadenas +### Formateo de Strings -Las cadenas son textuales y requerirán formato de vez en cuando. +Los Strings son textuales y requerirán formato de vez en cuando. -Para **concatenar** dos o más cadenas, o unirlas, use el operador `+`. +Para **concatenar** dos o más Strings, o unirlas, use el operador `+`. ```javascript -let myString1 = "Hello"; -let myString2 = "World"; +let myString1 = "Hola"; +let myString2 = "Mundo"; -myString1 + myString2 + "!"; //HelloWorld! -myString1 + " " + myString2 + "!"; //Hello World! -myString1 + ", " + myString2 + "!"; //Hello, World! +myString1 + myString2 + "!"; //¡Hola, mundo! +myString1 + " " + myString2 + "!"; //¡Hola, mundo! +myString1 + ", " + myString2 + "!"; //¡Hola, mundo! ``` ✅ ¿Por qué `1 + 1 = 2` en JavaScript, pero `'1' + '1' = 11?` Piense en ello. ¿Qué pasa con `'1' + 1`? -** Los literales de plantilla ** son otra forma de formatear cadenas, excepto que en lugar de comillas, se usa la comilla invertida. Todo lo que no sea texto sin formato debe colocarse dentro de los marcadores de posición `${ }`. Esto incluye cualquier variable que pueda ser cadenas. +**Los literales de plantilla** son otra forma de formatear Strings, excepto que en lugar de comillas, se usa la comilla invertida. Todo lo que no sea texto sin formato debe colocarse dentro de los marcadores de posición `${ }`. Esto incluye cualquier variable que pueda ser Strings. ```javascript -let myString1 = "Hello"; -let myString2 = "World"; +let myString1 = "Hola"; +let myString2 = "Mundo"; -`${myString1} ${myString2}!` //Hello World! -`${myString1}, ${myString2}!` //Hello, World! +`${myString1} ${myString2}!` //¡Hola, mundo! +`${myString1}, ${myString2}!` //¡Hola, mundo! ``` Puede lograr sus objetivos de formato con cualquier método, pero los literales de plantilla respetarán los espacios y saltos de línea. -✅ ¿Cuándo usaría una plantilla literal frente a una cadena simple? +✅ ¿Cuándo usaría una plantilla literal frente a un String simple? ### Booleanos @@ -174,11 +177,11 @@ Los booleanos pueden tener solo dos valores: `true` o `false`. Los valores boole - `let myTrueBool = true` - `let myFalseBool = false` -✅ Una variable se puede considerar 'verdadera' si se evalúa como un valor booleano 'verdadero'. Curiosamente, en JavaScript, [todos los valores son verdaderos a menos que se definan como falsos](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ Una variable se puede considerar 'verdadera' si se evalúa como un valor booleano 'verdadero'. Curiosamente, en JavaScript, [todos los valores son verdaderos a menos que se definan como falsos](https://developer.mozilla.org/docs/Glossary/Truthy). 🚀 Desafío: JavaScript es conocido por sus sorprendentes formas de manejar tipos de datos en ocasiones. Investiga un poco sobre estos "errores". Por ejemplo: ¡la sensibilidad a mayúsculas y minúsculas puede morder! Pruebe esto en su consola: `let age = 1; let Age = 2; age == Age` (resuelve `false` - ¿por qué?). ¿Qué otras trampas puedes encontrar? -## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8) +## [Post-lectura prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8) ## Revisión y autoestudio diff --git a/2-js-basics/1-data-types/translations/README.id.md b/2-js-basics/1-data-types/translations/README.id.md index b78c8a22..df199f6c 100644 --- a/2-js-basics/1-data-types/translations/README.id.md +++ b/2-js-basics/1-data-types/translations/README.id.md @@ -1,6 +1,6 @@ # Dasar-dasar JavaScript: Tipe Data - + > Catatan sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) @@ -178,7 +178,7 @@ Boolean hanya dapat berupa dua nilai: `true` atau `false`. Boolean dapat membant - `let myTrueBool = true` - `let myFalseBool = false` -✅ Variabel dapat dianggap 'benar (truthy)' jika dievaluasi ke boolean `true`. Menariknya, di JavaScript, [semua nilai adalah benar (truthy) kecuali jika didefinisikan sebagai salah](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ Variabel dapat dianggap 'benar (truthy)' jika dievaluasi ke boolean `true`. Menariknya, di JavaScript, [semua nilai adalah benar (truthy) kecuali jika didefinisikan sebagai salah](https://developer.mozilla.org/docs/Glossary/Truthy). --- diff --git a/2-js-basics/1-data-types/translations/README.it.md b/2-js-basics/1-data-types/translations/README.it.md index ec185a54..027c4771 100644 --- a/2-js-basics/1-data-types/translations/README.it.md +++ b/2-js-basics/1-data-types/translations/README.it.md @@ -1,6 +1,6 @@ # Nozioni di base su JavaScript: tipi di dato - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz pre-lezione @@ -175,7 +175,7 @@ I booleani possono avere solo due valori: vero (`true`) o falso (`false`). I bo - `let myTrueBool = true` - `let myFalseBool = false` -✅ Una variabile può essere considerata "veritiera" se restituisce un valore booleano `true`. È interessante notare che in JavaScript [tutti i valori sono veritieri a meno che non siano definiti falsi](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ Una variabile può essere considerata "veritiera" se restituisce un valore booleano `true`. È interessante notare che in JavaScript [tutti i valori sono veritieri a meno che non siano definiti falsi](https://developer.mozilla.org/docs/Glossary/Truthy). --- diff --git a/2-js-basics/1-data-types/translations/README.ja.md b/2-js-basics/1-data-types/translations/README.ja.md index 71594a0b..5d3b17a1 100644 --- a/2-js-basics/1-data-types/translations/README.ja.md +++ b/2-js-basics/1-data-types/translations/README.ja.md @@ -1,6 +1,6 @@ # JavaScript の基本: データ型 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/2-js-basics/1-data-types/translations/README.ko.md b/2-js-basics/1-data-types/translations/README.ko.md index 3a511455..1d104ce0 100644 --- a/2-js-basics/1-data-types/translations/README.ko.md +++ b/2-js-basics/1-data-types/translations/README.ko.md @@ -1,6 +1,6 @@ # JavaScript 기초: 데이터 타입 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -176,7 +176,7 @@ let myString2 = "World"; - `let myTrueBool = true` - `let myFalseBool = false` -✅ 변수가 논리 자료형이 `true`로 설정되면 '참'으로 간주될 수 있습니다. 흥미롭게도, JavaScript에서는 [거짓으로 정의되지 않는다면 모든 값은 참입니다](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ 변수가 논리 자료형이 `true`로 설정되면 '참'으로 간주될 수 있습니다. 흥미롭게도, JavaScript에서는 [거짓으로 정의되지 않는다면 모든 값은 참입니다](https://developer.mozilla.org/docs/Glossary/Truthy). --- diff --git a/2-js-basics/1-data-types/translations/README.ms.md b/2-js-basics/1-data-types/translations/README.ms.md index b79ea7d6..efae955e 100644 --- a/2-js-basics/1-data-types/translations/README.ms.md +++ b/2-js-basics/1-data-types/translations/README.ms.md @@ -1,6 +1,6 @@ # Asas JavaScript: Jenis Data - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -176,7 +176,7 @@ Booleans boleh hanya dua nilai: `benar` atau `salah`. Booleans dapat membantu me - `let myTrueBool = betul` - `let myFalseBool = salah` -✅ Pemboleh ubah boleh dianggap 'benar' jika dinilai menjadi `benar` boolean. Menariknya, dalam JavaScript, [semua nilai adalah benar kecuali ditakrifkan sebagai palsu](https://developer.mozilla.org/en-US/docs/Glossary/Truthy). +✅ Pemboleh ubah boleh dianggap 'benar' jika dinilai menjadi `benar` boolean. Menariknya, dalam JavaScript, [semua nilai adalah benar kecuali ditakrifkan sebagai palsu](https://developer.mozilla.org/docs/Glossary/Truthy). --- diff --git a/2-js-basics/1-data-types/translations/README.nl.md b/2-js-basics/1-data-types/translations/README.nl.md new file mode 100644 index 00000000..ab2a13aa --- /dev/null +++ b/2-js-basics/1-data-types/translations/README.nl.md @@ -0,0 +1,196 @@ +# JavaScript Basics: Gegevenstypen + + +> Sketchnote door [Tomomi Imura](https://twitter.com/girlie_mac) + +## Quiz voorafgaand aan de lezing +[Quiz voorafgaand aan de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7) + +Deze les behandelt de basisprincipes van JavaScript, de taal die voor interactiviteit op internet zorgt. + +[](https://youtube.com/watch?v=JNIXfGiDWM8 "Gegevenstypen in JavaScript") + + +Laten we beginnen met variabelen en de gegevenstypen waarmee ze worden gevuld! + +## Variabelen + +Variabelen slaan waarden op die in uw code kunnen worden gebruikt en gewijzigd. + +Het creëren en **declareren** van een variabele heeft de volgende syntaxis **[sleutelwoord] [naam]**. Het bestaat uit twee delen: + +- **Sleutelwoord**. Sleutelwoorden kunnen `let` of `var` zijn. + + > Let op, het sleutelwoord `let` is geïntroduceerd in ES6 en geeft uw variabele een zogenaamde _block scope_. Het wordt aanbevolen om `let` over `var` te gebruiken. In toekomstige delen gaan we dieper in op block scopes. +- **De variabelenaam**, dit is een naam die u zelf kiest. + +### Taak - werken met variabelen + +1. **Declareer een variabele**. Laten we een variabele declareren met het sleutelwoord `let`: + + ```javascript + let myVariable; + ``` + + `myVariable` is nu gedeclareerd met het `let` sleutelwoord. Het heeft momenteel geen waarde. + +1. **Wijs een waarde toe**. Sla een waarde op in een variabele met de operator `=`, gevolgd door de verwachte waarde. + + ```javascript + myVariable = 123; + ``` + + > Let op: het gebruik van `=` in deze les betekent dat we gebruik maken van een "toewijzingsoperator", die wordt gebruikt om een waarde aan een variabele te geven. Het duidt niet op gelijkheid. + + `myVariable` is nu *geïnitialiseerd* met de waarde 123. + +1. **Refactor**. Vervang uw code door de volgende verklaring. + + ```javascript + let myVariable = 123; + ``` + + Het bovenstaande wordt een _expliciete initialisatie_ genoemd wanneer een variabele wordt gedeclareerd en tegelijkertijd een waarde krijgt toegewezen. + +1. **Wijzig de variabele waarde**. Wijzig de waarde van de variabele op de volgende manier: + + ```javascript + myVariable = 321; + ``` + + Zodra een variabele is gedeclareerd, kunt u de waarde ervan op elk moment in uw code wijzigen met de operator `=` en de nieuwe waarde. + + ✅ Probeer het! U kunt JavaScript rechtstreeks in uw browser schrijven. Open een browservenster en ga naar Developer Tools. In de console vind u een prompt; typ `let myVariable = 123`, druk op Return en typ vervolgens `myVariable`. Wat gebeurt er? Let op, in de volgende lessen leert u meer over deze concepten. + +## Constanten + +Declaratie en initialisatie van een constante volgt dezelfde concepten als een variabele, met uitzondering van het sleutelwoord `const`. Constanten worden doorgaans gedeclareerd met alleen hoofdletters. + +```javascript +const MY_VARIABLE = 123; +``` + +Constanten zijn vergelijkbaar met variabelen, met twee uitzonderingen: + +- **Moet waarde hebben**. Constanten moeten worden geïnitialiseerd, anders treedt er een fout op bij het uitvoeren van code. +- **Referentie kan niet worden gewijzigd**. De referentie van een constante kan niet worden gewijzigd nadat deze is geïnitialiseerd, anders treedt er een fout op bij het uitvoeren van code. Laten we naar twee voorbeelden kijken: + - **Eenvoudige waarde**. Het volgende is NIET toegestaan: + + ```javascript + const PI = 3; + PI = 4; // niet toegestaan + ``` + + - **Objectreferentie is beveiligd**. Het volgende is NIET toegestaan. + + ```javascript + const obj = { a: 3 }; + obj = { b: 5 } // niet toegestaan + ``` + + - **Objectwaarde is niet beschermd**. Het volgende is toegestaan: + + ```javascript + const obj = { a: 3 }; + obj.a = 5; // toegestaan + ``` + + Hierboven verandert u de waarde van het object maar niet de referentie zelf, waardoor het toegestaan is. + + > Let op: een 'const' betekent dat de referentie is beschermd tegen opnieuw toewijzen. De waarde is echter niet _onveranderlijk_ en kan veranderen, vooral als het een complexe constructie is, zoals een object. + +## Gegevenstypen + +Variabelen kunnen veel verschillende soorten waarden opslaan, zoals getallen en tekst. Deze verschillende soorten waarden staan bekend als het **gegevenstype**. Gegevenstypen zijn een belangrijk onderdeel van softwareontwikkeling omdat het ontwikkelaars helpt beslissingen te nemen over hoe de code moet worden geschreven en hoe de software moet worden uitgevoerd. Bovendien hebben sommige gegevenstypen unieke kenmerken die helpen bij het transformeren of extraheren van aanvullende informatie in een waarde. + +✅ Gegevenstypen worden ook wel JavaScript-gegevensprimitieven genoemd, omdat dit de gegevenstypen op het laagste niveau zijn die door de taal worden geleverd. Er zijn 6 primitieve gegevenstypen: string, number, bigint, boolean, undefined, en symbol. Neem even de tijd om te visualiseren wat elk van deze primitieven zou kunnen vertegenwoordigen. Wat is een `zebra`? Hoe zit het met `0`? `true`? + +### Getallen + +In de vorige sectie was de waarde van `myVariable` een gegevenstype met een getal. + +`let myVariable = 123;` + +Variabelen kunnen alle soorten getallen opslaan, inclusief decimalen of negatieve getallen. Getallen kunnen ook worden gebruikt met rekenkundige operatoren, behandeld in de [volgende sectie](#operators). + +### Rekenkundige operatoren + +Er zijn verschillende soorten operatoren die kunnen worden gebruikt bij het uitvoeren van rekenkundige functies, en sommige worden hier vermeld: + +| Symbool | beschrijving | Voorbeeld | +| ------- | ------------------------------------------------------------- | ---------------------------------- | +| `+` | **Toevoeging**: Berekent de som van twee getallen | `1 + 2 //verwacht antwoord is 3` | +| `-` | **Aftrekken**: Berekent het verschil tussen twee getallen | `1 - 2 //verwacht antwoord is -1` | +| `*` | **Vermenigvuldiging**: Berekent het product van twee getallen | `1 * 2 //verwacht antwoord is 2` | +| `/` | **Divisie**: Berekent het quotiënt van twee getallen | `1 / 2 //verwacht antwoord is 0.5` | +| `%` | **Rest**: Berekent de rest uit de deling van twee getallen | `1 % 2 //verwacht antwoord is 1` | + +✅ Probeer het! Probeer een rekenkundige bewerking in de console van uw browser. Verrassen de resultaten u? + +### Strings + +Strings zijn sets van tekens die tussen enkele of dubbele aanhalingstekens staan. + +- `'Dit is een string'` +- `"Dit is ook een string"` +- `let myString = 'Dit is een tekenreekswaarde die is opgeslagen in een variabele';` + +Denk eraan om aanhalingstekens te gebruiken bij het schrijven van een string, anders neemt JavaScript aan dat het een variabelenaam is. + +### Strings formatteren + +Strings zijn tekstueel en moeten van tijd tot tijd worden opgemaakt. + +Gebruik de operator `+` om twee of meer strings **samen te voegen**. + +```javascript +let myString1 = "Hello"; +let myString2 = "World"; + +myString1 + myString2 + "!"; //HelloWorld! +myString1 + " " + myString2 + "!"; //Hello World! +myString1 + ", " + myString2 + "!"; //Hello, World! + +``` + +✅ Waarom is `1 + 1 = 2` in JavaScript, maar `'1' + '1' = 11?` Denk er eens over na. Hoe zit het met `'1' + 1`? + +**Template literals** zijn een andere manier om strings op te maken, behalve dat in plaats van aanhalingstekens de backtick wordt gebruikt. Alles wat geen platte tekst is, moet tussen tijdelijke aanduidingen `${}` worden geplaatst. Dit omvat alle variabelen die strings kunnen zijn. + +```javascript +let myString1 = "Hello"; +let myString2 = "World"; + +`${myString1} ${myString2}!` //Hello World! +`${myString1}, ${myString2}!` //Hello, World! +``` + +U kunt uw opmaakdoelen met beide methoden bereiken, maar template literals respecteren alle spaties en regeleinden. + +✅ Wanneer zou u een template literal versus een gewone string gebruiken? + +### Booleans + +Booleans kunnen slechts twee waarden zijn: `true` of `false`. Booleans kunnen helpen bij het nemen van beslissingen over welke regels code moeten worden uitgevoerd wanneer aan bepaalde voorwaarden is voldaan. In veel gevallen helpen [operatoren](# operators) bij het instellen van de waarde van een Boolean waarde en u zult vaak merken en variabelen schrijven die geïnitialiseerd worden of dat hun waarden worden bijgewerkt met een operator. + +- `let myTrueBool = true` +- `let myFalseBool = false` + +✅ Een variabele kan als 'waar' worden beschouwd als deze resulteert in een boolean waarde `true`. Interessant is dat in JavaScript [alle waarden waarheidsgetrouw zijn, tenzij ze als onjuist zijn gedefinieerd](https://developer.mozilla.org/nl/docs/Glossary/Truthy). + +--- + +## 🚀 Uitdaging + +JavaScript is berucht om zijn verrassende manieren om af en toe met gegevenstypen om te gaan. Doe een beetje onderzoek naar deze 'valstrikken'. Bijvoorbeeld: hoofdlettergevoeligheid kan bijten! Probeer dit in uw console: `let age = 1; let Age = 2; age == Age` (lost `false` op - waarom?). Welke andere valstrikken kunt u vinden? + +## Quiz na de lezing +[Quiz na de lezing](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8) + +## Beoordeling en zelfstudie + +Bekijk [deze lijst met JavaScript-oefeningen](https://css-tricks.com/snippets/javascript/) en probeer er een. Wat heeft u geleerd? + +## Toewijzing + +[Gegevenstypen Oefening](assignment.nl.md) diff --git a/2-js-basics/1-data-types/translations/README.zh-tw.md b/2-js-basics/1-data-types/translations/README.zh-tw.md new file mode 100644 index 00000000..e7d2008e --- /dev/null +++ b/2-js-basics/1-data-types/translations/README.zh-tw.md @@ -0,0 +1,197 @@ +# JavaScript 入門 - 資料型態 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7?loc=zh_tw) + +這堂課會講述 Javascript 的基礎 ── 一款建立互動性網頁的程式語言。 + +[](https://youtube.com/watch?v=JNIXfGiDWM8 "JavaScript 的資料型態") + +讓我們從程式語言的基礎 ── 「變數」與「資料型態」開始吧! + +## 變數 (Variable) + +變數會依照程式碼調整並儲存數值。 + +建立並**宣告**變數的語法有一定的格式: **[關鍵字(keyword)] [變數名稱(name)]**。下列開始分別敘述: + +- **關鍵字 (Keyword)** 關鍵字可以是 `let` 或者是 `var`。 + + > 注意,關鍵字 `let` 在 ES6 被導入進去,為變數限制 _區塊範疇(block scope)_。 建議上使用 `let` 勝過於 `var`。我們在往後的章節會講述什麼是區塊範疇。 + +- **變數名稱 (Variable Name)** 你可以自己定義變數名稱。 + +### 課題:變數的操作 + +1. **宣告變數** 利用關鍵字 `let` 來宣告新的變數: + + ```javascript + let myVariable; + ``` + + `myVariable` 已經被關鍵字 `let` 宣告出來了。它現在並沒有被賦予數值。 + +1. **賦予數值** 以運算子 `=` 來為變數新增數值,後面加上預期的數字。 + + ```javascript + myVariable = 123; + ``` + + > 注意:本堂課程中的運算子 `=` 只作為「指派運算子」,處理賦予數值的功用。它與「等於」並沒有關係。 + + 變數 `myVariable` 現在已經被*初始化*為數值 123。 + +1. **代碼重構 (Refactor)** 改寫你的程式碼為: + + ```javascript + let myVariable = 123; + ``` + + 合併「宣告變數」與「賦予數值」為一條程式碼的步驟稱為 _顯式初始化 (explicit initialization)_。 + +1. **更改變數數值** 透過下列的方式更改參數數值: + + ```javascript + myVariable = 321; + ``` + + 一旦變數被宣告後,你在任何往後的程式碼利用運算子 `=` 賦予新的數值。 + + ✅ 動手試試看! 在瀏覽器中撰寫 JavaScript:開啟瀏覽器並前往開發者工具,你會在 Console 頁面找到命令提示字元。輸入 `let myVariable = 123` 並按下 Enter。輸入 `myVariable`。它出現了什麼? 往後,你會學到更多這些觀念的課程。 + +## 常數 (Constants) + +宣告與初始化常數的行為與變數相似,只差在關鍵字 `const`。通常常數會以全大寫的方式命名。 + +```javascript +const MY_VARIABLE = 123; +``` + +常數與變數非常類似,主要的兩大差別為: + +- **一定要附帶數值** 常數一定要被初始化過,否則在執行程式時會產生錯誤。 +- **參考(Reference)不能被改變** 變數與常數都能根據其他變數或常數作為定義,但是常數的參考在初始化後,就不能再被更改,否則在執行程式時會產生錯誤。我們來看下列兩種例子: + - **簡單數值** 下列程式碼是不被允許的: + + ```javascript + const PI = 3; + PI = 4; // 錯誤 + ``` + + - **有限存取的參考物件** 下列程式碼是不被允許的: + + ```javascript + const obj = { a: 3 }; + obj = { b: 5 } // 錯誤 + ``` + + - **參考物件** 下列程式碼是「允許」的: + + ```javascript + const obj = { a: 3 }; + obj.a = 5; // OK + ``` + + 上述只改變物件的數值而非物件本身,這是可以被允許的。 + + > 注意,`const` 代表參考物件在重新賦值上有存取的限制。數值並不是永遠 _不可變的_,如果數值是規劃在其他物件上的話。 + +## 資料型態 (Data types) + +變數可以儲存不一樣的數值型態,好比是數字或是文字。這些多樣的數值型態被稱為**資料型態**。資料型態是軟體開發上重要的環節,它能幫助開發者釐清程式該如何被填寫以及運作。除此之外,有些獨特的資料型態能改變或賦加而外的數值資訊。 + +✅ 資料型態也存在於 JavaScript 的原始結構中,它們是程式語言中最低階的描述方式。六種資料型態:string、number、bigint、boolean、undefined 和 symbol。 花點時間了解它們的含義。資料 `zebra` 屬於哪一類? 那 `0` 呢? `true` 呢? + +### 數字 (Numbers) + +在前一個段落中,`myVariable`的數值屬於數字型。 + +`let myVariable = 123;` + +變數能儲存所有類型的數字,包含小數點與負數。數字也可以被套用在四則運算上,這被放在[下一個段落](#operators)中。 + +### 算術運算子 (Arithmetic Operators) + +這些是做四則運算時會使用到的算術運算子,下列舉出了幾項例子: + +| 符號 | 描述 | 舉例 | +| ------ | ------------------------------| --------------------- | +| `+` | **加法**: 對兩數做相加 | `1 + 2 // 答案為 3` | +| `-` | **減法**: 對兩數做相減 | `1 - 2 // 答案為 -1` | +| `*` | **乘法**: 對兩數做相乘 | `1 * 2 // 答案為 2` | +| `/` | **除法**: 對兩數做相除 | `1 / 2 // 答案為 0.5` | +| `%` | **餘數**: 取得兩數相除的餘數 | `1 % 2 // 答案為 1` | + +✅ 試試看!在瀏覽器命令欄中使用算數運算子。你得到了什麼結果? + +### 字串 (Strings) + +字串由多組字元組成,會以單引號或雙引號匡列起來。 + +- `'這是一組字串'` +- `"這也是一組字串"` +- `let myString = '這是被存在變數中的字串';` + +記得使用引號來編寫字串,否則 JavaScript 會把字串內容當作是變數名稱。 + +### 字串格式化 + + +字串由文字組成,自然需要隨時間而做修正。 + +要**串接**兩個以上的字串,可以使用運算子 `+`。 + +```javascript +let myString1 = "Hello"; +let myString2 = "World"; + +myString1 + myString2 + "!"; //HelloWorld! +myString1 + " " + myString2 + "!"; //Hello World! +myString1 + ", " + myString2 + "!"; //Hello, World! + +``` + +✅ 在 JavaScript 中,為什麼 `1 + 1 = 2`,但是 `'1' + '1' = 11` 呢? 想想看。那 `'1' + 1` 呢? + +**樣板字面值(Template literals)**是另一種格式化字串的方式,它不使用引號,而是使用反引號。任何非純文字字串必須放在 `${ }` 中。這會包入字串型態的任何變數。 + +```javascript +let myString1 = "Hello"; +let myString2 = "World"; + +`${myString1} ${myString2}!` //Hello World! +`${myString1}, ${myString2}!` //Hello, World! +``` + +這樣就可以達到字串格式化的目的,但要注意樣板字面會遵守變數中的空格與分行符號。 + +✅ 什麼情況下該使用樣板字面,或者是純文字字串呢? + +### 布林 (Booleans) + +布林有兩種數值:`true` 或 `false`,使用在程式碼做條件決定的時候。在多數情況下,[運算子](#operators)可以套用在布林上,你會在初始化或更新數值時使用。 + +- `let myTrueBool = true` +- `let myFalseBool = false` + +✅ 布林值 `true` 亦有廣義的 'truthy' 數值。有趣的是,在 JavaScript 中,[除非被定義為 falsy,其餘的數值都會被當作是 truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)。 + +--- + +## 🚀 挑戰 + +JavaScript 在處理資料結構時有許多種方法,有些場合為人詬病。在這方面做一些調查,例如:大小寫敏感性的問題!在命令欄中輸入看看: `let age = 1; let Age = 2; age == Age`,輸出結果是 `false`,為什麼? 你能找到其他問題嗎? + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8?loc=zh_tw) + +## 複習與自學 + +試試看[這些 JavaScript 練習題](https://css-tricks.com/snippets/javascript/)。 你學到了什麼? + +## 作業 + +[練習資料型態](assignment.zh-tw.md) diff --git a/2-js-basics/1-data-types/translations/assignment.nl.md b/2-js-basics/1-data-types/translations/assignment.nl.md new file mode 100644 index 00000000..841db475 --- /dev/null +++ b/2-js-basics/1-data-types/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Gegevenstypen Oefening + +## Instructies + +Stelt u voor dat u een winkelwagentje aan het bouwen bent. Schrijf wat documentatie over de gegevenstypen die u nodig zou hebben om uw winkelervaring te voltooien. Hoe bent u tot uw keuzes gekomen? + +## Rubriek + +Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd +--- | --- | --- | -- | +||De zes gegevenstypen worden opgesomd en in detail onderzocht, waarbij het gebruik ervan wordt gedocumenteerd|Vier gegevenstypen worden onderzocht|Twee gegevenstypen worden onderzocht| \ No newline at end of file diff --git a/2-js-basics/1-data-types/translations/assignment.zh-tw.md b/2-js-basics/1-data-types/translations/assignment.zh-tw.md new file mode 100644 index 00000000..0fd84cce --- /dev/null +++ b/2-js-basics/1-data-types/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 練習資料型態 + +## 簡介 + +想像你要建立一條購物清單,寫下你需要使用的資料型態。你是怎麼做出這些選擇的? + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------------------------- | ---------------------------------- | ---------------------------------- | +| | 使用六種資料型態並解釋用途以及用法 | 使用四種資料型態並解釋用途以及用法 | 使用兩種資料型態並解釋用途以及用法 | diff --git a/2-js-basics/2-functions-methods/README.md b/2-js-basics/2-functions-methods/README.md index 50efd195..7c6828f3 100644 --- a/2-js-basics/2-functions-methods/README.md +++ b/2-js-basics/2-functions-methods/README.md @@ -1,6 +1,6 @@ # JavaScript Basics: Methods and Functions - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -104,7 +104,7 @@ displayGreeting('Christopher', 'Hi'); ## Return values -Up until now the function we built will always output to the [console](https://developer.mozilla.org/en-US/docs/Web/API/console). Sometimes this can be exactly what we're looking for, especially when we create functions which will be calling other services. But what if I want to create a helper function to perform a calculation and provide the value back so I can use it elsewhere? +Up until now the function we built will always output to the [console](https://developer.mozilla.org/docs/Web/API/console). Sometimes this can be exactly what we're looking for, especially when we create functions which will be calling other services. But what if I want to create a helper function to perform a calculation and provide the value back so I can use it elsewhere? We can do this by using a **return value**. A return value is returned by the function, and can be stored in a variable just the same as we could store a literal value such as a string or number. @@ -133,7 +133,7 @@ const greetingMessage = createGreetingMessage('Christopher'); As you progress in your programming career, you will come across functions which accept functions as parameters. This neat trick is commonly used when we don't know when something is going to occur or complete, but we know we need to perform an operation in response. -As an example, consider [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), which begins a timer and will execute code when it completes. We need to tell it what code we want to execute. Sounds like a perfect job for a function! +As an example, consider [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), which begins a timer and will execute code when it completes. We need to tell it what code we want to execute. Sounds like a perfect job for a function! If you run the code below, after 3 seconds you'll see the message **3 seconds has elapsed**. @@ -188,7 +188,7 @@ Can you articulate in one sentence the difference between functions and methods? ## Review & Self Study -It's worth [reading up a little more on arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), as they are increasingly used in code bases. Practice writing a function, and then rewriting it with this syntax. +It's worth [reading up a little more on arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), as they are increasingly used in code bases. Practice writing a function, and then rewriting it with this syntax. ## Assignment diff --git a/2-js-basics/2-functions-methods/translations/README.de.md b/2-js-basics/2-functions-methods/translations/README.de.md index fbcdff8a..d57ec8a0 100644 --- a/2-js-basics/2-functions-methods/translations/README.de.md +++ b/2-js-basics/2-functions-methods/translations/README.de.md @@ -101,7 +101,7 @@ displayGreeting('Christopher', 'Hi'); ## Rückgabewerte -Bisher wurde die von uns erstellte Funktion immer an die [Konsole](https://developer.mozilla.org/en-US/docs/Web/API/console) ausgegeben. Manchmal kann dies genau das sein, wonach wir suchen, insbesondere wenn wir Funktionen erstellen, die andere Dienste aufrufen. Was aber, wenn ich eine Hilfsfunktion erstellen möchte, um eine Berechnung durchzuführen und den Wert zurückzugeben, damit ich ihn an anderer Stelle verwenden kann? +Bisher wurde die von uns erstellte Funktion immer an die [Konsole](https://developer.mozilla.org/docs/Web/API/console) ausgegeben. Manchmal kann dies genau das sein, wonach wir suchen, insbesondere wenn wir Funktionen erstellen, die andere Dienste aufrufen. Was aber, wenn ich eine Hilfsfunktion erstellen möchte, um eine Berechnung durchzuführen und den Wert zurückzugeben, damit ich ihn an anderer Stelle verwenden kann? Wir können dies tun, indem wir einen **Rückgabewert** verwenden. Ein Rückgabewert wird von der Funktion zurückgegeben und kann in einer Variablen genauso gespeichert werden, wie wir einen Literalwert wie eine Zeichenfolge oder eine Zahl speichern könnten. @@ -131,7 +131,7 @@ const greetingMessage = createGreetingMessage('Christopher'); Im Laufe Ihrer Programmierkarriere werden Sie auf Funktionen stoßen, die Funktionen als Parameter akzeptieren. Dieser nette Trick wird häufig verwendet, wenn wir nicht wissen, wann etwas eintreten oder abgeschlossen sein wird, aber wir wissen, dass wir als Reaktion darauf eine Operation ausführen müssen. -Betrachten Sie als Beispiel [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), das einen Timer startet und nach dessen Ausführung Code ausführt. Wir müssen ihm sagen, welchen Code wir ausführen wollen. Klingt nach einem perfekten Job für eine Veranstaltung! +Betrachten Sie als Beispiel [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), das einen Timer startet und nach dessen Ausführung Code ausführt. Wir müssen ihm sagen, welchen Code wir ausführen wollen. Klingt nach einem perfekten Job für eine Veranstaltung! Wenn Sie den folgenden Code ausführen, wird nach 3 Sekunden die Meldung **3 Sekunden sind verstrichen** angezeigt. @@ -188,7 +188,7 @@ Können Sie den Unterschied zwischen Funktionen und Methoden in einem Satz artik ## Review & Selbststudium -Es lohnt sich, [etwas mehr über Pfeilfunktionen zu lesen](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), da diese zunehmend in Codebasen verwendet werden. Üben Sie, eine Funktion zu schreiben und sie dann mit dieser Syntax neu zu schreiben. +Es lohnt sich, [etwas mehr über Pfeilfunktionen zu lesen](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), da diese zunehmend in Codebasen verwendet werden. Üben Sie, eine Funktion zu schreiben und sie dann mit dieser Syntax neu zu schreiben. ## Zuordnung diff --git a/2-js-basics/2-functions-methods/translations/README.es.md b/2-js-basics/2-functions-methods/translations/README.es.md index c147fed3..16b54ecb 100644 --- a/2-js-basics/2-functions-methods/translations/README.es.md +++ b/2-js-basics/2-functions-methods/translations/README.es.md @@ -1,10 +1,14 @@ -# Conceptos básicos de JavaScript: métodos y funciones -[](https://youtube.com/watch?v=XgKsD6Zwvlc "Métodos y funciones") + +> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) -## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/9) +# Conceptos básicos de JavaScript: funcións y funciones -Cuando necesite su código para realizar una tarea, utilizará un método o una función. Analicemos las diferencias. +[](https://youtube.com/watch?v=XgKsD6Zwvlc "funcións y funciones") + +## [Pre-lectura prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/9) + +Cuando necesite su código para realizar una tarea, utilizará un función o una función. Analicemos las diferencias. ## Funciones @@ -16,10 +20,94 @@ function name(param, param2, param3) { // definición de función } ``` -## Métodos +## Funciónes (Functions) + +En esencia, una función es un bloque de código que podemos ejecutar bajo demanda. Esto es perfecto para escenarios en los que necesitamos realizar la misma tarea varias veces; en lugar de duplicar la lógica en varias ubicaciones (lo que dificultaría la actualización cuando llegue el momento), podemos centralizarla en una ubicación y llamarla cuando necesitemos que se realice la operación; ¡incluso puede llamar a funciones desde otras funciones! + +Igual de importante es la capacidad de nombrar una función. Si bien esto puede parecer trivial, el nombre proporciona una forma rápida de documentar una sección de código. Podría pensar en esto como una etiqueta en un botón. Si hago clic en un botón que dice "Cancelar temporizador", sé que dejará de correr el reloj. + +## Creating and calling a function + +La sintaxis de una función se parece a la siguiente: + +```javascript +function nameOfFunction() { // function definition + // function definition/body +} +``` + +Si quisiera crear una función para mostrar un saludo, podría verse así: + +```javascript +function displayGreeting() { + console.log('¡Hola, mundo!'); +} +``` + +Siempre que queremos llamar (o invocar) nuestra función, usamos el nombre de la función seguido de `()`. Vale la pena señalar el hecho de que nuestra función se puede definir antes o después de que decidamos llamarla; el compilador de JavaScript lo encontrará por usted. + +```javascript +// calling our function +displayGreeting(); +``` + +> **NOTA:** Existe un tipo especial de función conocida como **método**, que ya ha estado utilizando. De hecho, vimos esto en nuestra demostración anterior cuando usamos `console.log`. Lo que hace que un método sea diferente de una función es que un método está adjunto a un objeto (`consola` en nuestro ejemplo), mientras que una función es flotante libre. Escuchará que muchos desarrolladores usan estos términos indistintamente. -TODO +### Mejores prácticas de función + +Hay algunas prácticas recomendadas que se deben tener en cuenta al crear funciones: + +- Como siempre, use nombres descriptivos para que sepa lo que hará la función +- Usa **camelCasing** para combinar palabras +- Mantenga sus funciones enfocadas en una tarea específica + +## Pasar información a una función + +Para que una función sea más reutilizable, a menudo querrá pasarle información. Si consideramos nuestro ejemplo de `displayGreeting` anterior, solo mostrará **¡Hola, mundo!**. No es la función más útil que uno podría crear. Si queremos hacerlo un poco más flexible, como permitir que alguien especifique el nombre de la persona a saludar, podemos agregar un **parámetro**. Un parámetro (también llamado a veces **argumento**), es información adicional enviada a una función. + +Los parámetros se enumeran en la parte de definición entre paréntesis y están separados por comas así: +```javascript +function name(param, param2, param3) { + +} +``` + +Podemos actualizar nuestro `displayGreeting` para aceptar un nombre y mostrarlo. + +```javascript +function displayGreeting(name) { + const message = `¡Hola, ${name}!`; + console.log(message); +} +``` + +Cuando queremos llamar a nuestra función y pasar el parámetro, lo especificamos entre paréntesis. + +```javascript +displayGreeting('Paco'); +// dice "¡Hola, Paco!" cuando ejecutas el comando +``` + +## Valores predeterminados + +Podemos hacer que nuestra función sea aún más flexible agregando más parámetros. Pero, ¿y si no queremos que se especifiquen todos los valores? Siguiendo con nuestro ejemplo de saludo, podríamos dejar el nombre según sea necesario (necesitamos saber a quién saludamos), pero queremos permitir que el saludo en sí se personalice como desee. Si alguien no quiere personalizarlo, proporcionamos un valor predeterminado en su lugar. Para proporcionar un valor predeterminado a un parámetro, lo configuramos de la misma manera que configuramos un valor para una variable: `parameterName = 'defaultValue'`. Para ver un ejemplo completo: + +```javascript +function displayGreeting(name, salutation='Hola') { + console.log(`${salutation}, ${name}`); +} +``` + +Cuando llamamos a la función, podemos decidir si queremos establecer un valor para el "saludo". + +```javascript +displayGreeting('Paco'); +// dice "Hola, Paco" + +displayGreeting('Paco', 'Hola'); +// dice "Hola, Paco" +``` ### Parámetro Los parámetros se enumeran en la parte de definición entre paréntesis y están separados por comas así: @@ -30,7 +118,9 @@ Los parámetros se enumeran en la parte de definición entre paréntesis y está ### Parámetro -Cuerpo de función +Hasta ahora, la función que construimos siempre saldrá a la [consola](https://developer.mozilla.org/en-US/docs/Web/API/console). A veces, esto puede ser exactamente lo que estamos buscando, especialmente cuando creamos funciones que llamarán a otros servicios. Pero, ¿qué pasa si quiero crear una función auxiliar para realizar un cálculo y devolver el valor para poder usarlo en otro lugar? + +Podemos hacer esto usando un **valor de retorno**. La función devuelve un valor de retorno y se puede almacenar en una variable de la misma manera que podríamos almacenar un valor literal como una cadena o un número. Aquí define qué tarea debe realizar la función. Una función puede devolver algo o no. Si una función devuelve algo, entonces se usa la palabra clave `return`. La palabra clave `return` espera un valor o referencia de lo que se devuelve así: @@ -52,7 +142,7 @@ En el código anterior, se devuelve la variable `sum`. ### Invocación -Cuando _invocas_ una función, la llamas con 0...N conjuntos de argumentos. Los valores de los argumentos se vinculan a los parámetros correspondientes a su posición. El método `add()` introducido se puede invocar de la siguiente manera: +Cuando _invocas_ una función, la llamas con 0...N conjuntos de argumentos. Los valores de los argumentos se vinculan a los parámetros correspondientes a su posición. El función `add()` introducido se puede invocar de la siguiente manera: ```javascript @@ -64,7 +154,7 @@ Los argumentos `1` y `3` están vinculados a los parámetros `firstValue` y `sec JavaScript es bastante flexible cuando se trata de invocaciones. No está obligado a proporcionar argumentos para todos los parámetros, el código se ejecutará de todos modos. Sin embargo, dependiendo de lo que le pase, es posible que el código no se comporte como se esperaba. -> Desafío, intente llamar al método `add()` así `add(1)` y vea qué sucede +> Desafío, intente llamar al función `add()` así `add(1)` y vea qué sucede ### Valores predeterminados @@ -93,7 +183,7 @@ Cualquier parámetro con valores predeterminados debe estar al final de la lista ## Revisión y autoestudio -TODO +Vale la pena [leer un poco más sobre las funciones de flecha](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), ya que se utilizan cada vez más en bases de código. Practique escribir una función y luego reescribirla con esta sintaxis. **Tarea**: [Práctica de tipos de datos](assignment.es.md) diff --git a/2-js-basics/2-functions-methods/translations/README.id.md b/2-js-basics/2-functions-methods/translations/README.id.md index ebb02be6..93c651c3 100644 --- a/2-js-basics/2-functions-methods/translations/README.id.md +++ b/2-js-basics/2-functions-methods/translations/README.id.md @@ -1,6 +1,6 @@ # Dasar-dasar JavaScript: Metode dan Fungsi - + > Catatan sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) @@ -102,7 +102,7 @@ tampilkanSapaan("Christopher", "Hi"); ## Nilai Kembali (Return values) -Hingga saat ini fungsi yang kita buat akan selalu menghasilkan [konsol](https://developer.mozilla.org/en-US/docs/Web/API/console). Terkadang ini persis seperti yang kita cari, terutama saat kita membuat fungsi yang akan memanggil layanan lain. Tetapi bagaimana jika saya ingin membuat fungsi pembantu untuk melakukan kalkulasi dan memberikan nilai kembali sehingga saya dapat menggunakannya di tempat lain? +Hingga saat ini fungsi yang kita buat akan selalu menghasilkan [konsol](https://developer.mozilla.org/docs/Web/API/console). Terkadang ini persis seperti yang kita cari, terutama saat kita membuat fungsi yang akan memanggil layanan lain. Tetapi bagaimana jika saya ingin membuat fungsi pembantu untuk melakukan kalkulasi dan memberikan nilai kembali sehingga saya dapat menggunakannya di tempat lain? Kita bisa melakukan ini dengan menggunakan **nilai kembali (return value)**. Nilai kembali dikembalikan oleh fungsi, dan dapat disimpan dalam variabel sama seperti kita dapat menyimpan nilai literal seperti string atau angka. @@ -131,7 +131,7 @@ const pesanSapaan = buatPesanSapaan("Christopher"); Saat Anda maju dalam karir pemrograman Anda, Anda akan menemukan fungsi yang menerima fungsi sebagai parameter. Trik rapi ini biasanya digunakan ketika kita tidak tahu kapan sesuatu akan terjadi atau selesai, tetapi kita tahu kita perlu melakukan operasi sebagai tanggapan. -Sebagai contoh, pertimbangkan [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), yang memulai timer dan akan mengeksekusi kode setelah selesai. Kita perlu memberi tahu kode apa yang ingin kita jalankan. Kedengarannya seperti pekerjaan yang sempurna untuk suatu fungsi! +Sebagai contoh, pertimbangkan [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), yang memulai timer dan akan mengeksekusi kode setelah selesai. Kita perlu memberi tahu kode apa yang ingin kita jalankan. Kedengarannya seperti pekerjaan yang sempurna untuk suatu fungsi! Jika Anda menjalankan kode di bawah ini, setelah 3 detik Anda akan melihat pesan **3 detik telah berlalu**. @@ -187,7 +187,7 @@ Bisakah Anda mengartikulasikan dalam satu kalimat perbedaan antara fungsi dan me ## Review & Belajar Mandiri -Layak [membaca lebih banyak tentang fungsi panah](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), karena semakin sering digunakan dalam basis kode. Berlatihlah menulis fungsi, lalu menulis ulang dengan sintaks ini. +Layak [membaca lebih banyak tentang fungsi panah](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), karena semakin sering digunakan dalam basis kode. Berlatihlah menulis fungsi, lalu menulis ulang dengan sintaks ini. ## Tugas diff --git a/2-js-basics/2-functions-methods/translations/README.it.md b/2-js-basics/2-functions-methods/translations/README.it.md index 2718bb8d..3428fcf6 100644 --- a/2-js-basics/2-functions-methods/translations/README.it.md +++ b/2-js-basics/2-functions-methods/translations/README.it.md @@ -1,6 +1,6 @@ # Nozioni di base su JavaScript: Metodi e Funzioni - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz pre-lezione @@ -131,7 +131,7 @@ const greetingMessage = createGreetingMessage('Christopher'); Man mano che si progredisce nella propria carriera di programmatore, ci si imbatterà in funzioni che accettano funzioni come parametri. Questo trucco è comunemente usato quando non si sa quando qualcosa accadrà o sarà completata, ma si sa che si deve eseguire un'operazione in risposta. -Come esempio si consideri [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), che fa partire un timer ed eseguirà del codice il tempo viene esaurito. Occorre dirgli quale codice si vuole eseguire. Sembra un lavoro perfetto per una funzione! +Come esempio si consideri [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), che fa partire un timer ed eseguirà del codice il tempo viene esaurito. Occorre dirgli quale codice si vuole eseguire. Sembra un lavoro perfetto per una funzione! Se si esegue il codice qui sopra, dopo 3 secondi si vedrà il messaggio **3 seconds has elapsed** (sono trascorsi 3 secondi). @@ -188,7 +188,7 @@ Si riesce ad articolare in una frase la differenza tra funzioni e metodi? Fare u ## Revisione e auto apprendimento -Vale la pena [leggere un poco di più sulle funzioni arrow](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), poiché sono sempre più utilizzate nelle basi di codice. Esercitarsi a scrivere una funzione, quindi riscriverla con questa sintassi. +Vale la pena [leggere un poco di più sulle funzioni arrow](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), poiché sono sempre più utilizzate nelle basi di codice. Esercitarsi a scrivere una funzione, quindi riscriverla con questa sintassi. ## Compito diff --git a/2-js-basics/2-functions-methods/translations/README.ja.md b/2-js-basics/2-functions-methods/translations/README.ja.md index 94681031..ef8ec065 100644 --- a/2-js-basics/2-functions-methods/translations/README.ja.md +++ b/2-js-basics/2-functions-methods/translations/README.ja.md @@ -1,6 +1,6 @@ # JavaScript の基本: メソッドと関数 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/2-js-basics/2-functions-methods/translations/README.ko.md b/2-js-basics/2-functions-methods/translations/README.ko.md index fa1d587d..7c5a5a73 100644 --- a/2-js-basics/2-functions-methods/translations/README.ko.md +++ b/2-js-basics/2-functions-methods/translations/README.ko.md @@ -1,6 +1,6 @@ # JavaScript 기초: 메소드와 함수 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -101,7 +101,7 @@ displayGreeting('Christopher', 'Hi'); ## 반환 값 -지금까지 만든 함수는 항상 [console](https://developer.mozilla.org/en-US/docs/Web/API/console)에 출력됩니다. 특히 다른 서비스를 호출할 함수를 만들 때도 이것이 찾고 있을 수 있습니다. 하지만 계산을 하고 값을 다른 곳에 다시 제공하고자 헬퍼 함수를 만들고 싶으면 어떻게 해야합니까? +지금까지 만든 함수는 항상 [console](https://developer.mozilla.org/docs/Web/API/console)에 출력됩니다. 특히 다른 서비스를 호출할 함수를 만들 때도 이것이 찾고 있을 수 있습니다. 하지만 계산을 하고 값을 다른 곳에 다시 제공하고자 헬퍼 함수를 만들고 싶으면 어떻게 해야합니까? **반환 값**을 사용하면 할 수 있습니다. 반환 값은 함수에 의해 반환되며, 문자열이나 숫자와 같은 리터럴 값을 저장할 수 있고 똑같은 변수에 저장할 수 있습니다. @@ -130,7 +130,7 @@ const greetingMessage = createGreetingMessage('Christopher'); 프로그래밍 경력을 쌓으면서, 함수를 매개 변수로 받는 함수를 보게 될 것 입니다. 이 깔끔한 트릭은 일반적으로 어떤 일이 발생되거나 완료되는 때를 알지 못하지만, 이에 반응하여 작업해야 한다는 것을 알고있을 때 사용됩니다. -예시로, 타이머를 시작하고 완료되면 코드를 실행하는 [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)을 고려해보세요. 실행하려는 코드를 먼저 알려줘야 합니다. 함수에 대한 완벽한 직업인 것 같습니다! +예시로, 타이머를 시작하고 완료되면 코드를 실행하는 [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)을 고려해보세요. 실행하려는 코드를 먼저 알려줘야 합니다. 함수에 대한 완벽한 직업인 것 같습니다! 아래 코드를 실행하면, 3초 후에 **3 seconds has elapsed**는 메시지가 표시됩니다. @@ -185,7 +185,7 @@ setTimeout(3000, () => { ## 리뷰 & 자기주도 학습 -화살표 함수는 코드 베이스에서 점점 많이 사용되고 있으므로, [읽어 볼 가치](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)가 있습니다. 함수 작성을 연습한 다음에 syntax로 다시 작성하십시오. +화살표 함수는 코드 베이스에서 점점 많이 사용되고 있으므로, [읽어 볼 가치](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)가 있습니다. 함수 작성을 연습한 다음에 syntax로 다시 작성하십시오. ## 과제 diff --git a/2-js-basics/2-functions-methods/translations/README.ms.md b/2-js-basics/2-functions-methods/translations/README.ms.md index 6d6d0360..a437bdb3 100644 --- a/2-js-basics/2-functions-methods/translations/README.ms.md +++ b/2-js-basics/2-functions-methods/translations/README.ms.md @@ -1,6 +1,6 @@ # Asas JavaScript: Kaedah dan Fungsi - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -104,7 +104,7 @@ displayGreeting('Christopher', 'Hi'); ## Nilai Pulangan -Sehingga kini fungsi yang kami bina akan selalu dikeluarkan ke [console](https://developer.mozilla.org/en-US/docs/Web/API/console). Kadang kala inilah yang sebenarnya kita cari, terutamanya ketika kita membuat fungsi yang akan memanggil perkhidmatan lain. Tetapi bagaimana jika saya ingin membuat fungsi pembantu untuk melakukan pengiraan dan memberikan nilai kembali supaya saya dapat menggunakannya di tempat lain? +Sehingga kini fungsi yang kami bina akan selalu dikeluarkan ke [console](https://developer.mozilla.org/docs/Web/API/console). Kadang kala inilah yang sebenarnya kita cari, terutamanya ketika kita membuat fungsi yang akan memanggil perkhidmatan lain. Tetapi bagaimana jika saya ingin membuat fungsi pembantu untuk melakukan pengiraan dan memberikan nilai kembali supaya saya dapat menggunakannya di tempat lain? Kita boleh melakukan ini dengan menggunakan **nilai kembali**. Nilai kembali akan dikembalikan oleh fungsi, dan dapat disimpan dalam pemboleh ubah sama seperti kita dapat menyimpan nilai literal seperti rentetan atau angka. @@ -133,7 +133,7 @@ const greetingMessage = createGreetingMessage('Christopher'); Semasa anda maju dalam kerjaya pengaturcaraan anda, anda akan menemui fungsi yang menerima fungsi sebagai parameter. Trik rapi ini biasanya digunakan ketika kita tidak tahu kapan sesuatu akan terjadi atau selesai, tetapi kita tahu kita perlu melakukan operasi sebagai tindak balas. -Sebagai contoh, pertimbangkan [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), yang memulakan pemasa dan akan melaksanakan kod apabila selesai. Kita perlu memberitahu apa kod yang ingin kita laksanakan. Kedengarannya pekerjaan yang sempurna untuk fungsi! +Sebagai contoh, pertimbangkan [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), yang memulakan pemasa dan akan melaksanakan kod apabila selesai. Kita perlu memberitahu apa kod yang ingin kita laksanakan. Kedengarannya pekerjaan yang sempurna untuk fungsi! Sekiranya anda menjalankan kod di bawah ini, setelah 3 saat anda akan melihat mesej **3 saat telah berlalu**. @@ -188,7 +188,7 @@ Bolehkah anda menyatakan dalam satu ayat perbezaan antara fungsi dan kaedah? Men ## Mengkaji & Belajar Sendiri -Perlu [membaca sedikit lebih banyak mengenai fungsi anak panah](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), kerana ia semakin banyak digunakan dalam pangkalan kod. Berlatih menulis fungsi, dan kemudian menulis semula dengan sintaks ini. +Perlu [membaca sedikit lebih banyak mengenai fungsi anak panah](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), kerana ia semakin banyak digunakan dalam pangkalan kod. Berlatih menulis fungsi, dan kemudian menulis semula dengan sintaks ini. ## Tugasan diff --git a/2-js-basics/2-functions-methods/translations/README.zh-tw.md b/2-js-basics/2-functions-methods/translations/README.zh-tw.md new file mode 100644 index 00000000..9c6d0404 --- /dev/null +++ b/2-js-basics/2-functions-methods/translations/README.zh-tw.md @@ -0,0 +1,195 @@ +# JavaScript 入門 - 函式與方法 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/9?loc=zh_tw) + +撰寫程式碼時,我們必須確保程式碼的閱讀性。聽來不太直覺,理解程式碼的時間遠比撰寫時間來的久。裡面最需要被管理的程式項目就是**函式**。 + +[](https://youtube.com/watch?v=XgKsD6Zwvlc "函式與方法") + +> 點擊上方圖片觀看關於函式的影片。 + + +## 函式 (Function) + +函式是程式碼區塊,會在程式執行時被呼叫運行。有些時候我們需要重複性的執行同一項作業,比起複製整個邏輯到其他區塊,函式是較完美的處理方式。不只方便維護,也可以在任何地方、任何時間被其他函式呼叫執行。 + +另一項重點是函式的名稱,聽來不太重要,但它能直接地解釋程式碼的內容。你可以想像它是按鈕上的文字,若按鈕上寫著「停止計時」,你會預期按壓按鈕後會終止計時器的運作。 + +## 建立並呼叫函式 + +函式的語法格式如下: + +```javascript +function nameOfFunction() { // 函式的定義 + // 函式的說明與內容 +} +``` + +如果你想建立一個打招呼的函式,它可能會以下列的格式呈現: + +```javascript +function displayGreeting() { + console.log('Hello, world!'); +} +``` + +如果你想呼叫這個函式,我們使用函式的名稱加上 `()`。我們不需要考慮函式是在被呼叫地方的前面或後面才被定義出來,JavaScript 的編譯器會幫你尋找它的定義為置。 + +```javascript +// 呼叫函式 +displayGreeting(); +``` + +> **注意** 另一個你正使用的函式類型稱做 **方法(method)**。事實上,我們能在執行 `console.log` 的 demo 時能找到它。它與函式的差異在於它需要接續在物件後面,在這個例子中就是 `console`,而函式並沒有強制要求的。你會發現許多開發者在兩者之間做切換。 + +### 函式的重點觀念 + +在建立函式時,你需要注意一些重點: + +- 我們反覆提到的,函式的名字要能了解函式的主要功能。 +- 使用**駝峰式大小寫(camelCasing)**來連接單字。 +- 單一函式只專一在單一功能。 + +## 向含式傳遞資料 + +為了讓函式能被重複利用,你會需要餵給函式不同的資料。以上述 `displayGreeting` 的例子中,它只能輸出文字 **Hello, world!**。這並不是個實用的函式。要增加函式的彈性,例如打招呼的對象,我們可以增加新的**參數(parameter/argument)**。它提供額外的資料給函式使用。 + +參數會寫在定義函式的地方,以括號與逗號標記與分隔: + +```javascript +function name(param, param2, param3) { + +} +``` + +現在我們更新函式 `displayGreeting`,讓它支援打招呼的對象: + +```javascript +function displayGreeting(name) { + const message = `Hello, ${name}!`; + console.log(message); +} +``` + +當我們要呼叫函式時,輸入需要的參數在括號中: + +```javascript +displayGreeting('Christopher'); +// 呼叫完,印出字串 "Hello, Christopher!" +``` + +## 預設值(Default values) + +我們利用參數增加了函式的彈性。但如果我們不想每次都要指定參數給函式使用呢? 繼續之前的例子,保留對象的名稱外,我們增加招呼語的種類。我們可以定義招呼語的預設值,若使用者沒有指定哪一種招呼語時,就使用預設值。它的方法就與賦予變數數值一樣 ── `parameterName = 'defaultValue'`。例如: + +```javascript +function displayGreeting(name, salutation='Hello') { + console.log(`${salutation}, ${name}`); +} +``` + +當我們呼叫函式時,我們可以選擇是否要指定招呼語到 `salutation` 中。 + +```javascript +displayGreeting('Christopher'); +// 輸出字串 "Hello, Christopher" + +displayGreeting('Christopher', 'Hi'); +// 輸出字串 "Hi, Christopher" +``` + +## 回傳值(Return values) + +目前為止,我們的函式只能輸出字串到[console](https://developer.mozilla.org/en-US/docs/Web/API/console)上。這或許是我們希望的結果,尤其是需要呼叫其他服務的時候。萬一今天我想建立一個額外的函式負責做資料處理與運算呢? + +此時,我們可以利用**回傳值**。回傳值由函式輸出,就像變數一樣儲存像是字串或是數字的結果。 + +如果函式有定義回傳值,那就需要使用關鍵字 `return` 。關鍵字 `return` 需要附帶回傳的數值或是參考物件在後方,如: + +```javascript +return myVariable; +``` + +我們建立一個函式專門建立招呼訊息並回傳給呼叫者: + +```javascript +function createGreetingMessage(name) { + const message = `Hello, ${name}`; + return message; +} +``` + +當函式被呼叫時,變數會儲存函式回傳的數值。這就像我們給變數定值一樣: `const name = 'Christopher'`。 + +```javascript +const greetingMessage = createGreetingMessage('Christopher'); +``` + +## 將函式作為函式參數使用 + +在你的程式旅程中,你會見到有函式將其他函式當作參數使用。這個俐落的手法常被用在一種情況:我們不知道 A 事件什麼時候發生與完成,但我們要在 A 事件後執行 B 事件。 + +舉例來說,考慮函式[setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout),它會啟動計時機制,並在倒數完後執行下一個程式。我們需要告訴函式哪一個函式要在時間到後執行,一個完美的例子! + +執行下方的程式,三秒鐘之後你會看到訊息**已經過三秒鐘**。 + +```javascript +function displayDone() { + console.log('已經過三秒鐘'); +} +// 計時單位為毫秒。 +setTimeout(displayDone, 3000); +``` + +### 不記名函式(Anonymous functions) + +回顧我們所建的函式,這些函式都只被執行了一次。當程式越來越複雜,我們可能建了許多的函式,但他們可能都只被呼叫了一次。這並不是理想的方式,那不如,不要給它函式名稱! + +我們可以傳遞函式作為參數使用,也可以直接在參數裡建立新的函式。同樣使用關鍵字 `function`,但我們寫在參數欄當中。 + +試著以不記名函式的方式改寫程式碼: + +```javascript +setTimeout(function() { + console.log('3 seconds has elapsed'); +}, 3000); +``` + +執行上述程式後可以得到相同的結果。我們建立了一個函式,一個沒有名字的函式! + +### 箭頭函式(Fat arrow functions) + +許多程式語言,包含 JavaScript,都有一個常見的快捷語法稱作**箭頭(arrow/fat arrow)**函式。 它使用 `=>` 表示法,就像是箭頭一樣,如同它的名稱!使用 `=>` 可以省略關鍵字 `function`。 + +再一次改寫程式碼,這次我們使用箭頭函式: + +```javascript +setTimeout(() => { + console.log('3 seconds has elapsed'); +}, 3000); +``` + +### 使用不同策略的時機 + +現在你已經學會了三種將函式作為參數的方法了。你可能會好奇使用它們的時機點為何。如果你知道你會重複使用一個函式,請使用正常的方法;如果你知道函式只用在特定的函式內一次,這就是用無記名函式的時機;箭頭函式與傳統 `function` 語法則是取決與你自己,但多數的開發者比較偏好使用 `=>`。 + +--- + +## 🚀 挑戰 + +你能用一句話清楚地說明這些函式與方法的差別嗎? 試試看吧! + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/10?loc=zh_tw) + +## 複習與自學 + +這很值得去閱讀[關於箭頭函式的資料](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions),它們越來越常被用在程式碼上。試著寫個函式,再改寫成箭頭語法。 + +## 作業 + +[把玩函式](assignment.zh-tw.md) \ No newline at end of file diff --git a/2-js-basics/2-functions-methods/translations/assignment.nl.md b/2-js-basics/2-functions-methods/translations/assignment.nl.md new file mode 100644 index 00000000..7199c167 --- /dev/null +++ b/2-js-basics/2-functions-methods/translations/assignment.nl.md @@ -0,0 +1,13 @@ +# Plezier met functies + +## Instructies + +Maak verschillende functies, zowel functies die iets retourneren als functies die niets retourneren. + +Kijk of u een functie kunt maken met een combinatie van parameters en parameters met standaardwaarden. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ----------------- | +| | Oplossing wordt geboden met twee of meer goed presterende functies met diverse parameters | Werkoplossing wordt aangeboden met één functie en enkele parameters | Oplossing heeft bugs | \ No newline at end of file diff --git a/2-js-basics/2-functions-methods/translations/assignment.zh-tw.md b/2-js-basics/2-functions-methods/translations/assignment.zh-tw.md new file mode 100644 index 00000000..bff30afa --- /dev/null +++ b/2-js-basics/2-functions-methods/translations/assignment.zh-tw.md @@ -0,0 +1,13 @@ +# 把玩函式 + +## 簡介 + +建立不同的函式,有的回傳數值,有的不回傳數值。 + +看看你是否能讓函式有多樣的參數輸入與參數預設值。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ------------------------------------------ | -------------------------- | -------------- | +| | 建立兩個以上多樣參數輸入且功能豐富的函式。 | 建立一個有參數輸入的函式。 | 函式出現問題。 | diff --git a/2-js-basics/3-making-decisions/README.md b/2-js-basics/3-making-decisions/README.md index b1fcd0cd..89df8ae1 100644 --- a/2-js-basics/3-making-decisions/README.md +++ b/2-js-basics/3-making-decisions/README.md @@ -1,6 +1,6 @@ # JavaScript Basics: Making Decisions - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -166,7 +166,7 @@ Create a program that is written first with logical operators, and then rewrite ## Review & Self Study -Read more about the many operators available to the user [on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators). +Read more about the many operators available to the user [on MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). Go through Josh Comeau's wonderful [operator lookup](https://joshwcomeau.com/operator-lookup/)! diff --git a/2-js-basics/3-making-decisions/images/webdev101-js-decisions.png b/2-js-basics/3-making-decisions/images/webdev101-js-decisions.png deleted file mode 100644 index 50b2a8e9..00000000 Binary files a/2-js-basics/3-making-decisions/images/webdev101-js-decisions.png and /dev/null differ diff --git a/2-js-basics/3-making-decisions/translations/README.de.md b/2-js-basics/3-making-decisions/translations/README.de.md index 9eea615f..509d34d9 100644 --- a/2-js-basics/3-making-decisions/translations/README.de.md +++ b/2-js-basics/3-making-decisions/translations/README.de.md @@ -162,7 +162,7 @@ Erstellen Sie ein Programm, das zuerst mit logischen Operatoren geschrieben wird ## Review & Selbststudium -Lesen Sie mehr über die vielen Operatoren, die dem Benutzer [auf MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) zur Verfügung stehen. +Lesen Sie mehr über die vielen Operatoren, die dem Benutzer [auf MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) zur Verfügung stehen. ## Zuordnung diff --git a/2-js-basics/3-making-decisions/translations/README.es.md b/2-js-basics/3-making-decisions/translations/README.es.md index 7ef4c2bc..e7b25fac 100644 --- a/2-js-basics/3-making-decisions/translations/README.es.md +++ b/2-js-basics/3-making-decisions/translations/README.es.md @@ -1,5 +1,9 @@ # Conceptos básicos de JavaScript: tomar decisiones + + +> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) + ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/11) Tomar decisiones y controlar el orden en que se ejecuta su código hace que su código sea reutilizable y robusto. Esta sección cubre la sintaxis para controlar el flujo de datos en JavaScript y su importancia cuando se usa con tipos de datos booleanos. @@ -156,7 +160,7 @@ if (firstNumber > secondNumber) { ## Revisión y autoestudio -Más información sobre los muchos operadores disponibles para el usuario [en MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators). +Más información sobre los muchos operadores disponibles para el usuario [en MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). **Asignación**: [Operadores](assignment.es.md) diff --git a/2-js-basics/3-making-decisions/translations/README.id.md b/2-js-basics/3-making-decisions/translations/README.id.md index 07dba472..43910d4f 100644 --- a/2-js-basics/3-making-decisions/translations/README.id.md +++ b/2-js-basics/3-making-decisions/translations/README.id.md @@ -1,6 +1,6 @@ # Dasar-dasar JavaScript: Membuat Keputusan - + > Sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) @@ -166,7 +166,7 @@ Buat program yang ditulis pertama kali dengan operator logika, lalu tulis ulang ## Review & Belajar Mandiri -Baca lebih lanjut tentang banyak operator yang tersedia untuk pengguna [di MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators). +Baca lebih lanjut tentang banyak operator yang tersedia untuk pengguna [di MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). Lihat [pencarian operator](https://joshwcomeau.com/operator-lookup/) oleh Josh Comeau yang luar biasa! diff --git a/2-js-basics/3-making-decisions/translations/README.it.md b/2-js-basics/3-making-decisions/translations/README.it.md index 3170511a..580e9e04 100644 --- a/2-js-basics/3-making-decisions/translations/README.it.md +++ b/2-js-basics/3-making-decisions/translations/README.it.md @@ -1,6 +1,6 @@ # Nozioni di base su JavaScript: Prendere Decisioni - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione diff --git a/2-js-basics/3-making-decisions/translations/README.ja.md b/2-js-basics/3-making-decisions/translations/README.ja.md index 93e0e701..9368c398 100644 --- a/2-js-basics/3-making-decisions/translations/README.ja.md +++ b/2-js-basics/3-making-decisions/translations/README.ja.md @@ -1,6 +1,6 @@ # JavaScript の基本: 意思決定 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/2-js-basics/3-making-decisions/translations/README.ko.md b/2-js-basics/3-making-decisions/translations/README.ko.md index 32774b54..37db58a0 100644 --- a/2-js-basics/3-making-decisions/translations/README.ko.md +++ b/2-js-basics/3-making-decisions/translations/README.ko.md @@ -1,6 +1,6 @@ # JavaScript 기초: 결정하기 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -164,7 +164,7 @@ if (firstNumber > secondNumber) { ## 리뷰 & 자기주도 학습 -[MDN에서](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) 사용할 수 있는 많은 연산자에 대해 자세히 알아보십시오. +[MDN에서](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) 사용할 수 있는 많은 연산자에 대해 자세히 알아보십시오. Josh Comeau'의 wonderful [operator lookup](https://joshwcomeau.com/operator-lookup/)을 통할 수 있습니다! diff --git a/2-js-basics/3-making-decisions/translations/README.ms.md b/2-js-basics/3-making-decisions/translations/README.ms.md index a4b46845..0bc347a0 100644 --- a/2-js-basics/3-making-decisions/translations/README.ms.md +++ b/2-js-basics/3-making-decisions/translations/README.ms.md @@ -1,6 +1,6 @@ # Asas JavaScript: Membuat Keputusan - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -166,7 +166,7 @@ Buat program yang ditulis terlebih dahulu dengan operator logik, dan kemudian tu ## Mengkaji & Belajar Sendiri -Baca lebih lanjut mengenai banyak pengendali yang ada pada pengguna[pada laman MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators). +Baca lebih lanjut mengenai banyak pengendali yang ada pada pengguna[pada laman MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). Lalui laman Josh Comeau tentang [pengendali](https://joshwcomeau.com/operator-lookup/)! diff --git a/2-js-basics/3-making-decisions/translations/README.zh-tw.md b/2-js-basics/3-making-decisions/translations/README.zh-tw.md new file mode 100644 index 00000000..be63a694 --- /dev/null +++ b/2-js-basics/3-making-decisions/translations/README.zh-tw.md @@ -0,0 +1,176 @@ +# JavaScript 入門 - 做出決定 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/11?loc=zh_tw) + +為程式碼做決定與控制順序以提高其重複利用性與豐富性。這堂課程提供 JavaScript 的資料流控制語法與布林資料型的重點。 + +[](https://youtube.com/watch?v=SxTp8j-fMMY "做出決定") + +> 點擊上方圖片以觀賞關於程式做決定的影片。 + +## 回顧布林資料型 + +布林只能有兩種數值: `true` 或 `false`。 布林幫助程式碼間在特定的條件下做出決定。 + +設定布林值的方式如下: + +`let myTrueBool = true` +`let myFalseBool = false` + +✅ 布林的命名來源為一位英格蘭數學家、哲學家暨邏輯學家喬治·布爾 George Boole (1815–1864)。 + +## 關係運算子與布林 + +運算子會被使用在執行比較上,並回傳布林值。以下是常用的運算子列表。 + +| 符號 | 描述 | 舉例 | +| ----- | -------------------------------------------------------------------------- | ------------------ | +| `<` | **小於**: 比較兩數,當左數小於右數時,回傳 `true`。 | `5 < 6 // true` | +| `<=` | **小於等於**: 比較兩數,當左數小於右數或左數等於右數時,回傳 `true`。 | `5 <= 6 // true` | +| `>` | **大於**: 比較兩數,當左數大於右數時,回傳 `true`。 | `5 > 6 // false` | +| `>=` | **大於等於**: 比較兩數,當左數大於右數或左數等於右數時,回傳 `true`。 | `5 >= 6 // false` | +| `===` | **嚴格相等**: 比較兩數,當左數等於右數且有相同的資料型態時,回傳 `true`。 | `5 === 6 // false` | +| `!==` | **嚴格不等於**: 比較兩數,回傳值與嚴格相等恰恰相反。 | `5 !== 6 // true` | + +✅ 藉由在瀏覽器命令欄中撰寫關係運算子來驗證你學到的知識。你有什麼意外發現嗎? + +## If 條件式 + +當條件成立時,If 條件式會執行區塊內的程式碼。 + +```javascript +if (condition){ + //Condition was true. Code in this block will run. +} +``` + +邏輯運算子常被用在建立條件上。 + +```javascript +let currentMoney; +let laptopPrice; + +if (currentMoney >= laptopPrice){ + //Condition was true. Code in this block will run. + console.log("Getting a new laptop!"); +} +``` + +## IF..Else 條件式 + +當條件不成立時,`else` 條件式會執行區塊內的程式碼。它可以和 `if` 條件式選擇性地使用。 + +```javascript +let currentMoney; +let laptopPrice; + +if (currentMoney >= laptopPrice){ + // if 條件成立時,這段程式碼會被執行。 + console.log("Getting a new laptop!"); +} +else{ + // else 條件成立時,這段程式碼會被執行。 + console.log("Can't afford a new laptop, yet!"); +} +``` + +✅ 在瀏覽器命令欄中測試你是否了解上述程式碼的意義。改變變數 currentMoney 和 laptopPrice 的數值來取得不同的回傳值 `console.log()`。 + +## 邏輯運算子與布林 + +有時候條件內容包含兩個以上的比較,邏輯運算子可以協助串接比較式來回傳布林值。 + +| 符號 | 描述 | 舉例 | +| ------ | -------------------------------------------------------------------------- | --------------------------------------------------------- | +| `&&` | **邏輯和**: 比較兩個布林條件式,當兩者**皆**回傳 `true` 時,回傳 `true`。 | `(5 > 6) && (5 < 6 ) //左為false、右為true,回傳 false。` | +| `\|\|` | **邏輯或**: 比較兩個布林條件式,當其中一個回傳 `true` 時,回傳 `true`。 | `(5 > 6) \|\| (5 < 6) //左為false、右為true,回傳 true。` | +| `!` | **邏輯非**: 回傳布林條件式的相反回傳值。 | `!(5 > 6) // 5 不大於 6,但 "!" 讓回傳值為 true。` | + +## 邏輯運算子下的決定與條件 + +邏輯運算子可以用在建立 if..else 條件式中的條件。 + +```javascript +let currentMoney; +let laptopPrice; +let laptopDiscountPrice = laptopPrice - (laptopPrice * .20) //Laptop price at 20 percent off + +if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice){ + // if 條件成立時,這段程式碼會被執行。 + console.log("Getting a new laptop!"); +} +else { + // else 條件成立時,這段程式碼會被執行。 + console.log("Can't afford a new laptop, yet!"); +} +``` + +### 否定運算子 + +你已經了解如何在 `if...else` 條件式中建立條件。任何 `if` 條件需要決定它的是與否。利用運算子 `!` 來 _否定_ 結果。它以下列方式呈現: + +```javascript +if (!condition) { + // condition 為 false 時,執行。 +} else { + // condition 為 true 時,執行。 +} +``` + +### 條件運算子 + +`if...else` 並不是唯一表達條件式的方式。你也可以使用名為條件運算子的符號。語法如下: + +```javascript +let variable = condition ? <條件成立時回傳 A> : <條件否定時回傳 B> +``` + +下列是較明確的例子: + +```javascript +let firstNumber = 20; +let secondNumber = 10 +let biggestNumber = firstNumber > secondNumber ? firstNumber: secondNumber; +``` + +✅ 花點時間閱讀這段程式碼。你能了解這些運算子的運作方式嗎? + +上述的狀態為: +- 若 `firstNumber` 大於 `secondNumber` 時 +- 則賦予 `firstNumber` 數值 `biggestNumber` +- 否則賦予為數值 `secondNumber`。 + +條件運算子的另一種表達方式為: + +```javascript +let biggestNumber; +if (firstNumber > secondNumber) { + biggestNumber = firstNumber; +} else { + biggestNumber = secondNumber; +} +``` + +--- + +## 🚀 挑戰 + +建立一個程式,使用邏輯運算式來做判斷,再將程式碼改寫成條件運算子。你喜歡用哪一種語法? + +--- +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/12?loc=zh_tw) + +## 複習與自學 + +閱讀更多可被使用的運算子:[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators)。 + +瀏覽 Josh Comeau 所編制的[運算子查詢表](https://joshwcomeau.com/operator-lookup/)! + +## 作業 + +[運算子](assignment.zh-tw.md) diff --git a/2-js-basics/3-making-decisions/translations/assignment.nl.md b/2-js-basics/3-making-decisions/translations/assignment.nl.md new file mode 100644 index 00000000..5e4993d7 --- /dev/null +++ b/2-js-basics/3-making-decisions/translations/assignment.nl.md @@ -0,0 +1,40 @@ +# Operatoren + +## Instructies + +Speel met operatoren. Hier is een suggestie voor een programma dat u kunt implementeren: + +U hebt een groep studenten uit twee verschillende beoordelingssystemen. + +### Eerste beoordelingssysteem + +Een beoordelingssysteem wordt gedefinieerd met cijfers van 1-5, waarbij 3 en hoger betekent dat u slaagt voor de cursus. + +### Tweede beoordelingssysteem + +Het andere cijfer systeem heeft de volgende cijfers `A, A-, B, B-, C, C-` waarbij `A` het hoogste cijfer is en `C` het laagste voldoende is. + +### De taak + +Gegeven de volgende array `allStudents` die alle studenten en hun cijfers vertegenwoordigt, construeert u een nieuwe array `studentsWhoPass` met daarin alle studenten die slagen. + +> TIP, gebruik een for-loop, if...else en vergelijkingsoperatoren: + +```javascript +let allStudents = [ + 'A', + 'B-', + 1, + 4, + 5, + 2 +] + +let studentsWhoPass = []; +``` + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------------ | ----------------------------- | ------------------------------- | +| | De complete oplossing wordt gepresenteerd | Gedeeltelijke oplossing wordt gepresenteerd | Oplossing met bugs wordt gepresenteerd | diff --git a/2-js-basics/3-making-decisions/translations/assignment.zh-tw.md b/2-js-basics/3-making-decisions/translations/assignment.zh-tw.md new file mode 100644 index 00000000..0746abe3 --- /dev/null +++ b/2-js-basics/3-making-decisions/translations/assignment.zh-tw.md @@ -0,0 +1,41 @@ +# 運算子 + +## 簡介 + +把玩並熟悉運算子。以下是建議的練習程式模板: + +你有兩套提供給同一組學生的成績系統。 + +### 第一套成績系統 + +定義分數為 1 到 5。當分數 3 以上時通過測驗。 + +### 第二套成績系統 + +定義分數為 `A, A-, B, B-, C, C-`, `A` 為最高分而 `C` 為最低分,皆為通過測驗。 + +### 課題 + +使用下列矩陣 `allStudents` 表示所有學生的成績,試著建立新的矩陣 `studentsWhoPass` 包含所有通過學生的編號。 + +> 提示,使用 for-loop 迴圈、 if...else 條件式與比較運算子: + +```javascript +let allStudents = [ + 'A', + 'B-', + 1, + 4, + 5, + 2 +] + +let studentsWhoPass = []; +``` + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------------- | ------------------------ | ---------- | +| | 提供完整的解答與解釋。 | 只提供部分的解答與解釋。 | 解答有誤。 | + diff --git a/2-js-basics/4-arrays-loops/README.md b/2-js-basics/4-arrays-loops/README.md index 9c0b5b7e..9fc66df1 100644 --- a/2-js-basics/4-arrays-loops/README.md +++ b/2-js-basics/4-arrays-loops/README.md @@ -1,6 +1,6 @@ # JavaScript Basics: Arrays and Loops - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -110,7 +110,7 @@ for (let i = 0; i < iceCreamFlavors.length; i++) { ## 🚀 Challenge -There are other ways of looping over arrays other than for and while loops. There are [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of), and [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Rewrite your array loop using one of these techniques. +There are other ways of looping over arrays other than for and while loops. There are [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), and [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Rewrite your array loop using one of these techniques. ## Post-Lecture Quiz [Post-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14) @@ -118,7 +118,7 @@ There are other ways of looping over arrays other than for and while loops. Ther ## Review & Self Study -Arrays in JavaScript have many methods attached to them, extremely useful for data manipulation. [Read up on these methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) and try some of them out (like push, pop, slice and splice) on an array of your creation. +Arrays in JavaScript have many methods attached to them, extremely useful for data manipulation. [Read up on these methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) and try some of them out (like push, pop, slice and splice) on an array of your creation. ## Assignment diff --git a/2-js-basics/4-arrays-loops/translations/README.de.md b/2-js-basics/4-arrays-loops/translations/README.de.md index bfab7c69..16f00a3b 100644 --- a/2-js-basics/4-arrays-loops/translations/README.de.md +++ b/2-js-basics/4-arrays-loops/translations/README.de.md @@ -109,13 +109,13 @@ for (let i = 0; i < iceCreamFlavors.length; i++) { ## 🚀 Herausforderung -Es gibt andere Möglichkeiten, Arrays als for- und while-Schleifen zu durchlaufen. Es gibt [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) und [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Schreiben Sie Ihre Array-Schleife mit einer dieser Techniken neu. +Es gibt andere Möglichkeiten, Arrays als for- und while-Schleifen zu durchlaufen. Es gibt [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) und [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Schreiben Sie Ihre Array-Schleife mit einer dieser Techniken neu. ## [Quiz nach der Vorlesung](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14) ## Review & Selbststudium -An Arrays in JavaScript sind viele Methoden angehängt, die für die Datenmanipulation äußerst nützlich sind. [Informieren Sie sich über diese Methoden](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) und probieren Sie einige davon aus (wie Push, Pop, Slice und Splice). auf einem Array Ihrer Kreation. +An Arrays in JavaScript sind viele Methoden angehängt, die für die Datenmanipulation äußerst nützlich sind. [Informieren Sie sich über diese Methoden](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) und probieren Sie einige davon aus (wie Push, Pop, Slice und Splice). auf einem Array Ihrer Kreation. ## Zuordnung diff --git a/2-js-basics/4-arrays-loops/translations/README.es.md b/2-js-basics/4-arrays-loops/translations/README.es.md index 237b9778..584e6fbf 100644 --- a/2-js-basics/4-arrays-loops/translations/README.es.md +++ b/2-js-basics/4-arrays-loops/translations/README.es.md @@ -1,5 +1,8 @@ # Conceptos básicos de JavaScript: matrices y bucles + +> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) + [](https://youtube.com/watch?v=Q_CRM2lXXBg "Matrices y bucles") @@ -87,7 +90,7 @@ while (i < 10) { } ``` -✅ ¿Por qué elegiría un bucle for frente a un bucle while? 17K espectadores tenían la misma pregunta sobre StackOverflow, y algunas de las opiniones [podrían ser interesantes para usted](https://stackoverflow.com/questions/39969145/ while-loops-vs-for-loops-in-javascript). +✅ ¿Por qué elegiría un bucle for frente a un bucle while? 17K espectadores tenían la misma pregunta sobre StackOverflow, y algunas de las opiniones [podrían ser interesantes para usted](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript). ## Bucles y matrices @@ -103,12 +106,12 @@ for (let i = 0; i < iceCreamFlavors.length; i++) { ✅ Experimente recorriendo una serie de su propia creación en la consola de su navegador. -🚀 Desafío: Hay otras formas de realizar un bucle sobre arreglos además de los bucles for y while. Existen [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of), y [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Vuelva a escribir su bucle de matriz utilizando una de estas técnicas. +🚀 Desafío: Hay otras formas de realizar un bucle sobre arreglos además de los bucles for y while. Existen [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), y [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Vuelva a escribir su bucle de matriz utilizando una de estas técnicas. ## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14) ## Revisión y autoestudio -Las matrices en JavaScript tienen muchos métodos adjuntos, extremadamente útiles para la manipulación de datos. [Lea sobre estos métodos](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) y pruebe algunos de ellos (como push, pop, slice y splice) en una matriz de su creación. +Las matrices en JavaScript tienen muchos métodos adjuntos, extremadamente útiles para la manipulación de datos. [Lea sobre estos métodos](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) y pruebe algunos de ellos (como push, pop, slice y splice) en una matriz de su creación. **Asignación**: [Bucle de una matriz](assignment.es.md) diff --git a/2-js-basics/4-arrays-loops/translations/README.id.md b/2-js-basics/4-arrays-loops/translations/README.id.md index f2e02c32..8fe286ef 100644 --- a/2-js-basics/4-arrays-loops/translations/README.id.md +++ b/2-js-basics/4-arrays-loops/translations/README.id.md @@ -1,6 +1,6 @@ # Dasar-dasar JavaScript: Array dan Loop - + > Sketsa oleh [Tomomi Imura](https://twitter.com/girlie_mac) @@ -126,7 +126,7 @@ for (let i = 0; i < rasaRasaEsKrim.length; i++) { ## 🚀 Tantangan -Ada cara lain untuk melakukan perulangan pada array selain perulangan for dan while. Ada [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of), dan [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Tulis ulang loop array Anda menggunakan salah satu dari teknik ini. +Ada cara lain untuk melakukan perulangan pada array selain perulangan for dan while. Ada [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), dan [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Tulis ulang loop array Anda menggunakan salah satu dari teknik ini. ## Kuis Pasca-Kuliah @@ -134,7 +134,7 @@ Ada cara lain untuk melakukan perulangan pada array selain perulangan for dan wh ## Review & Belajar Mandiri -Array dalam JavaScript memiliki banyak metode yang menyertainya, sangat berguna untuk manipulasi data. [Bacalah tentang metode ini](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) dan coba beberapa di antaranya (seperti push, pop, slice dan splice) pada array kreasi Anda. +Array dalam JavaScript memiliki banyak metode yang menyertainya, sangat berguna untuk manipulasi data. [Bacalah tentang metode ini](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) dan coba beberapa di antaranya (seperti push, pop, slice dan splice) pada array kreasi Anda. ## Tugas diff --git a/2-js-basics/4-arrays-loops/translations/README.it.md b/2-js-basics/4-arrays-loops/translations/README.it.md index 1a02a71e..8b59cca5 100644 --- a/2-js-basics/4-arrays-loops/translations/README.it.md +++ b/2-js-basics/4-arrays-loops/translations/README.it.md @@ -1,6 +1,6 @@ # Nozioni di base di JavaScript: Array e Cicli - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione diff --git a/2-js-basics/4-arrays-loops/translations/README.ja.md b/2-js-basics/4-arrays-loops/translations/README.ja.md index fd1eb9a3..593ee840 100644 --- a/2-js-basics/4-arrays-loops/translations/README.ja.md +++ b/2-js-basics/4-arrays-loops/translations/README.ja.md @@ -1,6 +1,6 @@ # JavaScript の基本: 配列とループ - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/2-js-basics/4-arrays-loops/translations/README.ko.md b/2-js-basics/4-arrays-loops/translations/README.ko.md index e48f9b7b..dbf5f2b0 100644 --- a/2-js-basics/4-arrays-loops/translations/README.ko.md +++ b/2-js-basics/4-arrays-loops/translations/README.ko.md @@ -1,6 +1,6 @@ # JavaScript 기초: 배열과 반복 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -109,7 +109,7 @@ for (let i = 0; i < iceCreamFlavors.length; i++) { ## 🚀 도전 -for문과 while문 외에 배열을 반복하는 다른 방법이 있습니다. [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) 그리고 [map](https://developer.mozilla.org/en-US/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)도 있습니다. 해당 기술 중 하나를 사용하여 배열 반복을 다시 작성하십시오. ## 강의 후 퀴즈 [Post-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14?loc=ko) @@ -117,7 +117,7 @@ for문과 while문 외에 배열을 반복하는 다른 방법이 있습니다. ## 리뷰 & 자기주도 학습 -JavaScript의 배열에는 많은 메서드를 가져서 데이터 조작에 매우 유용합니다. [이 방법에 대해 읽어보고](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) 만든 배열에서 몇 가지(push, pop, slice 그리고 splice와 같은) 방식을 시도해보십시오. +JavaScript의 배열에는 많은 메서드를 가져서 데이터 조작에 매우 유용합니다. [이 방법에 대해 읽어보고](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) 만든 배열에서 몇 가지(push, pop, slice 그리고 splice와 같은) 방식을 시도해보십시오. ## 과제 diff --git a/2-js-basics/4-arrays-loops/translations/README.ms.md b/2-js-basics/4-arrays-loops/translations/README.ms.md index 9ca89079..f46fa7d2 100644 --- a/2-js-basics/4-arrays-loops/translations/README.ms.md +++ b/2-js-basics/4-arrays-loops/translations/README.ms.md @@ -1,6 +1,6 @@ # Asas JavaScript: Array dan Loop - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -110,14 +110,14 @@ for (let i = 0; i < iceCreamFlavors.length; i++) { ## 🚀 Cabaran -Terdapat cara lain untuk mengulangi tatasusunan selain untuk dan semasa gelung. Terdapat [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of), dan [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Tulis semula array loop anda menggunakan salah satu teknik ini. +Terdapat cara lain untuk mengulangi tatasusunan selain untuk dan semasa gelung. Terdapat [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), dan [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Tulis semula array loop anda menggunakan salah satu teknik ini. ## Kuiz Pasca Kuliah [Kuiz Pasca Kuliah](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14) ## Mengkaji and Belajar Sendiri -Array dalam JavaScript mempunyai banyak kaedah yang melekat padanya, sangat berguna untuk manipulasi data. [Baca kaedah ini](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) dan cuba beberapa di antaranya (seperti push, pop, slice dan splice) pada pelbagai ciptaan anda. +Array dalam JavaScript mempunyai banyak kaedah yang melekat padanya, sangat berguna untuk manipulasi data. [Baca kaedah ini](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) dan cuba beberapa di antaranya (seperti push, pop, slice dan splice) pada pelbagai ciptaan anda. ## Tugasan diff --git a/2-js-basics/4-arrays-loops/translations/README.zh-tw.md b/2-js-basics/4-arrays-loops/translations/README.zh-tw.md new file mode 100644 index 00000000..d0e80d46 --- /dev/null +++ b/2-js-basics/4-arrays-loops/translations/README.zh-tw.md @@ -0,0 +1,126 @@ +# JavaScript 入門 - 矩陣與迴圈 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/13?loc=zh_tw) + +這堂課會包含程式語言 JavaScript,建立互動式網頁的基礎。課程中,你會學到用來操作資料的矩陣與迴圈。 + +[](https://youtube.com/watch?v=Q_CRM2lXXBg "矩陣與迴圈") + +> 點擊以上的圖片來觀賞關於矩陣與迴圈的影片。 + +## 矩陣(Arrays) + +處理資料是任何程式語言中最常見的任務,如果能將程式碼有條理地編排成如矩陣的形式,處理任務來會更加輕鬆。矩陣的資料儲存格式就像串列,其中一項好處是矩陣可以儲存不同的資料型態資料。 + +✅ 矩陣其實圍繞在我們身邊!你能想到現實中那些應用是矩陣的形式,例如太陽能板矩陣嗎? + +矩陣的語法需要用到中括號。 + +`let myArray = [];` + +上述為一個空矩陣,矩陣也能在宣告時設定內容資料,資料會以逗號來做區隔。 + +`let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];` + +矩陣數值位置會以**索引(index)**來決定,標記從矩陣的開頭相隔多少元素。在上述例子中,字串 "Chocolate" 的索引為 0,"Rocky Road" 為 4。以中括號帶入索引來接收、修改或加入特定元素數值。 + +✅ 索引從 0 開始有超出你的預料之外嗎?在部分程式語言中,索引會從 1 開始。這有一段有趣的歷史,你可以[閱讀維基百科](https://zh.wikipedia.org/wiki/%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B%E7%9A%84%E7%B7%A8%E8%99%9F)來了解它。 + +```javascript +let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +iceCreamFlavors[2]; //"Vanilla" +``` + +你可以指定索引改變其中的數值,如: + +```javascript +iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan" +``` + +或者是指定索引加入新數值,如: + +```javascript +iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough" +``` + +✅ 另一個常用加入矩陣元素的方式為使用矩陣運算子如 array.push()。 + +要得知矩陣內有多少元素,可以使用矩陣屬性 `length`。 + +```javascript +let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +iceCreamFlavors.length; //5 +``` + +✅ 自己動手試試看!使用瀏覽器命令欄,自由地建立並操控矩陣。 + +## 迴圈(Loops) + +迴圈幫助你處理重複性與**迭代(iterative)**任務,這可以省下許多程式碼行數與時間。每一次迭代可以有不同的變數、數值或條件。在 JavaScript 中有許多種迴圈的樣式,彼此都有些微的差異,但主要功能都一樣:對資料做迴圈。 + +### For 迴圈(For Loop) + +`for` 迴圈有三個條件: + - `計數器(counter)` 一個初始化變數決定目前迭代的次數。 + - `條件式(condition)` 一個以比較運算子表示的陳述式,當結果為 `true` 時終止迴圈。 + - `迭代陳述式(iteration-expression)` 在每一次迭代完後,改變計數器的數值。 + +```javascript + // 從 0 加到 10 + for (let i = 0; i < 10; i++) { + console.log(i); + } +``` + +✅ 在瀏覽器命令欄中運行這段迴圈。在改變計數器、條件式與迭代陳述式後有什麼改變?你能讓它變成從 10 減到 0 嗎? + +### While 迴圈(While Loop) + +不同於 `for` 迴圈語法,`while` 迴圈只要求一個條件式,當條件式回傳 `true` 時即終止迴圈。迴圈中的條件是通常需要依賴像計數器的變數,這些變數必須被合理的處理。計數器的起始化需要在迴圈外面,之後的條件陳述式與計數器的變化則需要在迴圈當中。 + +```javascript +// 從 0 加到 10 +let i = 0; +while (i < 10) { + console.log(i); + i++; +} +``` + +✅ 你會選擇 for 迴圈還是 while 迴圈呢? 一萬七千個 StackOverflow 用戶問過相同的問題,有些回應[可能會勾起你的興趣](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript)。 + +## 矩陣與迴圈 + +矩陣通常會與迴圈一起出現,大多數的條件式需要矩陣的長度來決定迴圈次數,矩陣的索引值也與計數器的數值相同。 + +```javascript +let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; + +for (let i = 0; i < iceCreamFlavors.length; i++) { + console.log(iceCreamFlavors[i]); +} // 當所有冰淇淋口味表示完時,結束迴圈。 +``` + +✅ 做個實驗,在瀏覽器命令欄中製作一個使用矩陣的迴圈。 + +--- + +## 🚀 挑戰 + +除了 for 迴圈與 while 迴圈外,仍有許多使用矩陣與迴圈的方法:[forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)、[for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)與[map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)。 用上列其中一種語法改寫你的迴圈。 + +## 課後測驗 +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14?loc=zh_tw) + +## 複習與自學 + +在 JavaScript 中,矩陣有許多控制的方法,它們在處理資料上有很大的幫助。 +[學習這些方法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array),如 push、pop、slice 和 splice,試著套用在你所創造的矩陣上。 + +## 作業 + +[給矩陣的迴圈](assignment.zh-tw.md) diff --git a/2-js-basics/4-arrays-loops/translations/assignment.nl.md b/2-js-basics/4-arrays-loops/translations/assignment.nl.md new file mode 100644 index 00000000..b45cd53d --- /dev/null +++ b/2-js-basics/4-arrays-loops/translations/assignment.nl.md @@ -0,0 +1,13 @@ +# Loop een Array + +## Instructies + +Maak een programma dat elk 3de nummer tussen 1 en 20 opsomt en het afdrukt naar de console. + +> TIP: gebruik een for-loop en pas de iteratie-uitdrukking aan + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | --------------------------------------- | ------------------------ | ------------------------------ | +| | Programma loopt correct en wordt becommentarieerd | Programma wordt niet becommentarieerd | Programma is onvolledig of bevat fouten | \ No newline at end of file diff --git a/2-js-basics/4-arrays-loops/translations/assignment.zh-tw.md b/2-js-basics/4-arrays-loops/translations/assignment.zh-tw.md new file mode 100644 index 00000000..c28ebd03 --- /dev/null +++ b/2-js-basics/4-arrays-loops/translations/assignment.zh-tw.md @@ -0,0 +1,13 @@ +# 給矩陣的迴圈 + +## 簡介 + +建立一個程式,列出數字每第三個從 1 到 20 的值(3,6,9......),並輸出在 console 上。 + +> 提示:使用 for-loop 迴圈並改寫它的迭代陳述式。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------------------- | ---------------------- | -------------- | +| | 程式完成簡介裡的課題並解釋程式碼意義。 | 程式完成簡介裡的課題。 | 程式出現問題。 | diff --git a/2-js-basics/translations/README.nl.md b/2-js-basics/translations/README.nl.md new file mode 100644 index 00000000..a657542c --- /dev/null +++ b/2-js-basics/translations/README.nl.md @@ -0,0 +1,14 @@ +# Inleiding tot JavaScript + +JavaScript is de taal van het web. In deze vier lessen leert u de basisprincipes. + +### Onderwerpen + +1. [Variabelen en Gegevenstypen](../1-data-types/translations/README.nl.md) +2. [Functies en Methoden](../2-functions-methods/translations/README.nl.md) +3. [Beslissingen nemen met JavaScript](../3-making-decisions/translations/README.nl.md) +4. [Arrays en Lussen](../4-arrays-loops/translations/README.nl.md) + +### Credits + +Deze lessen zijn geschreven met ♥ door [Jasmine Greenaway](https://twitter.com/paladique), [Christopher Harrison](https://twitter.com/geektrainer) en [Chris Noring](https://twitter.com/chris_noring) \ No newline at end of file diff --git a/2-js-basics/translations/README.zh-tw.md b/2-js-basics/translations/README.zh-tw.md new file mode 100644 index 00000000..d6917e7b --- /dev/null +++ b/2-js-basics/translations/README.zh-tw.md @@ -0,0 +1,14 @@ +# JavaScript 入門 + +JavaScript 編輯網頁的一種程式語言。在這四堂課中,你會學到它最基本的知識。 + +### 主題 + +1. [變數與資料型態](../1-data-types/translations/README.zh-tw.md) +2. [函式與方法](../2-functions-methods/translations/README.zh-tw.md) +3. [在 JavaScript 做出決定](../3-making-decisions/translations/README.zh-tw.md) +4. [矩陣與迴圈](../4-arrays-loops/translations/README.zh-tw.md) + +### 參與人員 + +這些文章是由 [Jasmine Greenaway](https://twitter.com/paladique)、[Christopher Harrison](https://twitter.com/geektrainer)和[Chris Noring](https://twitter.com/chris_noring) 用滿滿的 ♥️ 來編寫。 \ No newline at end of file diff --git a/3-terrarium/1-intro-to-html/README.md b/3-terrarium/1-intro-to-html/README.md index fabf656e..167ff4a2 100644 --- a/3-terrarium/1-intro-to-html/README.md +++ b/3-terrarium/1-intro-to-html/README.md @@ -1,6 +1,6 @@ # Terrarium Project Part 1: Introduction to HTML - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -48,13 +48,13 @@ Add these lines at the top of your `index.html` file: <html></html> ``` -✅ There are a few different modes that can be determined by setting the DocType with a query string: [Quirks Mode and Standards Mode](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). These modes used to support really old browsers that aren't normally used nowadays (Netscape Navigator 4 and Internet Explorer 5). You can stick to the standard doctype declaration. +✅ There are a few different modes that can be determined by setting the DocType with a query string: [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). These modes used to support really old browsers that aren't normally used nowadays (Netscape Navigator 4 and Internet Explorer 5). You can stick to the standard doctype declaration. --- ## The document's 'head' -The 'head' area of the HTML document includes crucial information about your web page, also known as [metadata](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). In our case, we tell the web server to which this page will be sent to be rendered, these four things: +The 'head' area of the HTML document includes crucial information about your web page, also known as [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta). In our case, we tell the web server to which this page will be sent to be rendered, these four things: - the page's title - page metadata including: @@ -75,7 +75,7 @@ Add a 'head' block to your document in between the opening and closing `<html>` </head> ``` -✅ What would happen if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? Read more about the [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag). +✅ What would happen if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? Read more about the [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag). --- @@ -213,7 +213,7 @@ Add this markup above the last `</div>` tag: ## 🚀Challenge -There are some wild 'older' tags in HTML that are still fun to play with, though you shouldn't use deprecated tags such as [these tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) in your markup. Still, can you use the old `<marquee>` tag to make the h1 title scroll horizontally? (if you do, don't forget to remove it afterwards) +There are some wild 'older' tags in HTML that are still fun to play with, though you shouldn't use deprecated tags such as [these tags](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) in your markup. Still, can you use the old `<marquee>` tag to make the h1 title scroll horizontally? (if you do, don't forget to remove it afterwards) ## Post-Lecture Quiz diff --git a/3-terrarium/1-intro-to-html/translations/README.es.md b/3-terrarium/1-intro-to-html/translations/README.es.md index c4eb78ff..1cdbd918 100644 --- a/3-terrarium/1-intro-to-html/translations/README.es.md +++ b/3-terrarium/1-intro-to-html/translations/README.es.md @@ -1,6 +1,6 @@ # Terrarium Project Parte 1: Introducción a HTML - + > Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/15) @@ -39,13 +39,13 @@ Agrega estas líneas en la parte superior de tu archivo `index.html`: <html></html> ``` -✅ Hay algunos modos diferentes que se pueden determinar configurando DocType con una cadena de consulta: [Modo Quirks y Modo estándar](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Estos modos solían admitir navegadores realmente antiguos que no se utilizan normalmente en la actualidad (Netscape Navigator 4 e Internet Explorer 5). Puede ceñirse a la declaración de tipo de documento estándar. +✅ Hay algunos modos diferentes que se pueden determinar configurando DocType con una cadena de consulta: [Modo Quirks y Modo estándar](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Estos modos solían admitir navegadores realmente antiguos que no se utilizan normalmente en la actualidad (Netscape Navigator 4 e Internet Explorer 5). Puede ceñirse a la declaración de tipo de documento estándar. --- ## 2. El 'encabezado' del documento -El área 'encabezado' del documento HTML incluye información crucial sobre su página web, también conocida como [metadatos](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). En nuestro caso, le decimos al servidor web al que se enviará esta página para que sea renderizada cuatro cosas: +El área 'encabezado' del documento HTML incluye información crucial sobre su página web, también conocida como [metadatos](https://developer.mozilla.org/docs/Web/HTML/Element/meta). En nuestro caso, le decimos al servidor web al que se enviará esta página para que sea renderizada cuatro cosas: - el título de la página - metadatos de la página que incluyen: @@ -66,7 +66,7 @@ Agregue un bloque de 'encabezado' a su documento entre las etiquetas de apertura </head> ``` -✅ ¿Qué pasaría si configuras una metaetiqueta de ventana gráfica como esta: `<meta name =" viewport "content =" width = 600 ">`? Obtenga más información sobre [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag). +✅ ¿Qué pasaría si configuras una metaetiqueta de ventana gráfica como esta: `<meta name =" viewport "content =" width = 600 ">`? Obtenga más información sobre [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag). --- @@ -203,7 +203,7 @@ Agregue este marcado encima de la última etiqueta `</div>`: --- -🚀 Desafío: hay algunas etiquetas "antiguas" salvajes en HTML con las que todavía es divertido jugar, aunque no debes usar etiquetas obsoletas como [estas etiquetas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) en su marcado. Aún así, ¿puede usar la antigua etiqueta `<marquee>` para hacer que el título h1 se desplace horizontalmente? (si lo hace, no olvide quitarlo después) +🚀 Desafío: hay algunas etiquetas "antiguas" salvajes en HTML con las que todavía es divertido jugar, aunque no debes usar etiquetas obsoletas como [estas etiquetas](https://developer.mozilla.org/docs/Web/HTML/Element) en su marcado. Aún así, ¿puede usar la antigua etiqueta `<marquee>` para hacer que el título h1 se desplace horizontalmente? (si lo hace, no olvide quitarlo después) ## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16) diff --git a/3-terrarium/1-intro-to-html/translations/README.it.md b/3-terrarium/1-intro-to-html/translations/README.it.md index 7bcd7a07..579a730e 100644 --- a/3-terrarium/1-intro-to-html/translations/README.it.md +++ b/3-terrarium/1-intro-to-html/translations/README.it.md @@ -1,6 +1,6 @@ # Progetto Terrario Parte 1: Introduzione all'HTML - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione @@ -49,13 +49,13 @@ Aggiungere queste righe all'inizio del file `index.html` : <html></html> ``` -✅ Ci sono alcune modalità differenti che possono essere determinate impostando DocType con una stringa di query: [Quirks Mode e Standards Mode](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Queste modalità supportano browser molto vecchi che non vengono normalmente utilizzati al giorno d'oggi (Netscape Navigator 4 e Internet Explorer 5). Ci si può attenere alla dichiarazione doctype standard. +✅ Ci sono alcune modalità differenti che possono essere determinate impostando DocType con una stringa di query: [Quirks Mode e Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Queste modalità supportano browser molto vecchi che non vengono normalmente utilizzati al giorno d'oggi (Netscape Navigator 4 e Internet Explorer 5). Ci si può attenere alla dichiarazione doctype standard. --- ## La "testa" del documento (tag head) -L'area "head" del documento HTML include informazioni cruciali sulla propria pagina web, note anche come [metadati](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). In questo caso, si dice al server web a cui verrà inviata questa pagina per essere renderizzata, queste quattro cose: +L'area "head" del documento HTML include informazioni cruciali sulla propria pagina web, note anche come [metadati](https://developer.mozilla.org/docs/Web/HTML/Element/meta). In questo caso, si dice al server web a cui verrà inviata questa pagina per essere renderizzata, queste quattro cose: - il titolo della pagina - metadati della pagina tra cui: @@ -76,7 +76,7 @@ Aggiungere un blocco "head" al proprio documento tra i tag di apertura e di chiu </head> ``` -✅ Cosa accadrebbe se il meta tag viewport viene impostato come questo: `<meta name="viewport" content="width=600">`? Ulteriori informazioni sul [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag). +✅ Cosa accadrebbe se il meta tag viewport viene impostato come questo: `<meta name="viewport" content="width=600">`? Ulteriori informazioni sul [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag). --- @@ -214,7 +214,7 @@ Aggiungere questo markup sopra l'ultimo tag `</div>`: ## 🚀 Sfida -Ci sono alcuni "vecchi" selvaggi tag in HTML con cui è ancora divertente giocare, anche se non si dovrebero usare tag deprecati come [questi tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) nel proprio markup. Tuttavia, si può usare il vecchio tag `<marquee>` per far scorrere orizzontalmente il titolo h1? (se viene fatto, non dimenticarsi di rimuoverlo dopo) +Ci sono alcuni "vecchi" selvaggi tag in HTML con cui è ancora divertente giocare, anche se non si dovrebero usare tag deprecati come [questi tag](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) nel proprio markup. Tuttavia, si può usare il vecchio tag `<marquee>` per far scorrere orizzontalmente il titolo h1? (se viene fatto, non dimenticarsi di rimuoverlo dopo) ## Quiz Post-Lezione diff --git a/3-terrarium/1-intro-to-html/translations/README.ja.md b/3-terrarium/1-intro-to-html/translations/README.ja.md index c80ac593..07906c59 100644 --- a/3-terrarium/1-intro-to-html/translations/README.ja.md +++ b/3-terrarium/1-intro-to-html/translations/README.ja.md @@ -1,6 +1,6 @@ # テラリウムプロジェクト その1: HTML 入門 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト @@ -75,7 +75,7 @@ HTML ドキュメントの 'head' 領域には、Web ページに関する重要 </head> ``` -✅ このように viewport の meta タグを設定するとどうなるでしょうか: `<meta name="viewport" content="width=600">`? [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag) についてはこちらをご覧ください。 +✅ このように viewport の meta タグを設定するとどうなるでしょうか: `<meta name="viewport" content="width=600">`? [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag) についてはこちらをご覧ください。 --- diff --git a/3-terrarium/1-intro-to-html/translations/README.ko.md b/3-terrarium/1-intro-to-html/translations/README.ko.md index 8a8d4f18..ea02cdc2 100644 --- a/3-terrarium/1-intro-to-html/translations/README.ko.md +++ b/3-terrarium/1-intro-to-html/translations/README.ko.md @@ -1,6 +1,6 @@ # Terrarium 프로젝트 파트 1: HTML 소개 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -48,13 +48,13 @@ HTML 파일의 첫 번째 줄은 doctype입니다. 파일 최상단에 줄이 <html></html> ``` -✅ 쿼리 문자열로 DocType을 설정하여 결정할 수 있는 몇 가지 모드가 있습니다: [Quirks Mode and Standards Mode](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). 이 모드는 요즘 잘 사용하지 않는 오래된 브라우저를 지원하는 데 사용되었습니다 (Netscape Navigator 4 및 Internet Explorer 5). 표준 doctype 선언을 할 수도 있습니다. +✅ 쿼리 문자열로 DocType을 설정하여 결정할 수 있는 몇 가지 모드가 있습니다: [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). 이 모드는 요즘 잘 사용하지 않는 오래된 브라우저를 지원하는 데 사용되었습니다 (Netscape Navigator 4 및 Internet Explorer 5). 표준 doctype 선언을 할 수도 있습니다. --- ## 문서의 'head' -HTML 문서의 'head' 영역에는 [metadata](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)라고 하는 웹 페이지의 중요한 정보가 포함되어 있습니다. 우리의 경우에는, 이 페이지가 렌더링될 웹 서버에 다음 4가지를 알립니다. +HTML 문서의 'head' 영역에는 [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta)라고 하는 웹 페이지의 중요한 정보가 포함되어 있습니다. 우리의 경우에는, 이 페이지가 렌더링될 웹 서버에 다음 4가지를 알립니다. - 페이지의 제목 - 페이지 메타데이터 포함: @@ -75,7 +75,7 @@ HTML 문서의 'head' 영역에는 [metadata](https://developer.mozilla.org/en-U </head> ``` -✅ `<meta name="viewport" content="width=600">`과 같이 viewport 메타 태그를 설정하면 어떻게 되나요? [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag)에 대해 자세히 알아보세요. +✅ `<meta name="viewport" content="width=600">`과 같이 viewport 메타 태그를 설정하면 어떻게 되나요? [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag)에 대해 자세히 알아보세요. --- @@ -213,7 +213,7 @@ HTML에서는, .html 파일에 태그를 추가하여 웹 페이지의 요소를 ## 🚀 도전 -HTML에는 여전히 재미있고 '오래된' 태그가 있지만, 마크업에서는 [이러한 태그](https://developer.mozilla.org/en-US/docs/Web/HTML/Element)처럼 더 이상 사용되지 않는 태그를 쓰면 안됩니다. 그래도, 예전 `<marquee>` 태그를 사용하여 h1 제목을 가로로 스크롤할 수 있습니까? (한다면, 나중에 제거하는 것을 잊지 마십시오) +HTML에는 여전히 재미있고 '오래된' 태그가 있지만, 마크업에서는 [이러한 태그](https://developer.mozilla.org/docs/Web/HTML/Element)처럼 더 이상 사용되지 않는 태그를 쓰면 안됩니다. 그래도, 예전 `<marquee>` 태그를 사용하여 h1 제목을 가로로 스크롤할 수 있습니까? (한다면, 나중에 제거하는 것을 잊지 마십시오) ## 강의 후 퀴즈 diff --git a/3-terrarium/1-intro-to-html/translations/README.ms.md b/3-terrarium/1-intro-to-html/translations/README.ms.md index 864bfc98..f0210601 100644 --- a/3-terrarium/1-intro-to-html/translations/README.ms.md +++ b/3-terrarium/1-intro-to-html/translations/README.ms.md @@ -1,6 +1,6 @@ # Projek Terrarium Bahagian 1: Pengenalan Kepada HTML - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -48,13 +48,13 @@ Tambahkan baris ini di bahagian atas fail `index.html` anda: <html></html> ``` -✅ Terdapat beberapa mod berbeza yang dapat ditentukan dengan menetapkan Jenis Dokumen dengan rentetan pertanyaan: [Mod Quirks dan Mod Piawai](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode) . Mod ini digunakan untuk menyokong penyemak imbas lama yang tidak biasa digunakan pada masa ini (Netscape Navigator 4 dan Internet Explorer 5). Anda boleh berpegang pada pernyataan standard documentype. +✅ Terdapat beberapa mod berbeza yang dapat ditentukan dengan menetapkan Jenis Dokumen dengan rentetan pertanyaan: [Mod Quirks dan Mod Piawai](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode) . Mod ini digunakan untuk menyokong penyemak imbas lama yang tidak biasa digunakan pada masa ini (Netscape Navigator 4 dan Internet Explorer 5). Anda boleh berpegang pada pernyataan standard documentype. --- ## Dokumen 'head' -Kawasan 'head' dokumen HTML merangkumi maklumat penting mengenai laman web anda, juga dikenali sebagai [metadata](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). Dalam kes kami, kami memberitahu pelayan web tempat halaman ini akan dihantar untuk diberikan, empat perkara berikut: +Kawasan 'head' dokumen HTML merangkumi maklumat penting mengenai laman web anda, juga dikenali sebagai [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta). Dalam kes kami, kami memberitahu pelayan web tempat halaman ini akan dihantar untuk diberikan, empat perkara berikut: - tajuk halaman - metadata halaman termasuk: @@ -75,7 +75,7 @@ Tambahkan blok 'head' ke dokumen anda di antara tag pembuka dan penutup `<html>` </head> ``` -✅ Apa yang akan berlaku jika anda menetapkan tag meta viewport seperti ini: `<meta name =" viewport "content =" width = 600 ">`? Baca lebih lanjut mengenai [viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag). +✅ Apa yang akan berlaku jika anda menetapkan tag meta viewport seperti ini: `<meta name =" viewport "content =" width = 600 ">`? Baca lebih lanjut mengenai [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag). --- @@ -213,7 +213,7 @@ Tambahkan markup ini di atas tag `</div>` terakhir: ## 🚀Cabaran -Terdapat beberapa tag 'lawas' liar dalam HTML yang masih menyeronokkan untuk dimainkan, walaupun anda tidak boleh menggunakan tag yang tidak digunakan seperti [tag ini](https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) dalam markup anda. Masih bolehkah anda menggunakan tag `<marquee>` lama untuk menjadikan tajuk h1 menatal secara mendatar? (jika anda melakukannya, jangan lupa membuangnya selepas itu) +Terdapat beberapa tag 'lawas' liar dalam HTML yang masih menyeronokkan untuk dimainkan, walaupun anda tidak boleh menggunakan tag yang tidak digunakan seperti [tag ini](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) dalam markup anda. Masih bolehkah anda menggunakan tag `<marquee>` lama untuk menjadikan tajuk h1 menatal secara mendatar? (jika anda melakukannya, jangan lupa membuangnya selepas itu) ## Kuiz Pasca Kuliah diff --git a/3-terrarium/1-intro-to-html/translations/README.zh-tw.md b/3-terrarium/1-intro-to-html/translations/README.zh-tw.md new file mode 100644 index 00000000..ff840d1a --- /dev/null +++ b/3-terrarium/1-intro-to-html/translations/README.zh-tw.md @@ -0,0 +1,231 @@ +# 盆栽盒專案 Part 1: HTML 簡介 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/15?loc=zh_tw) + +### 大綱 + +HTML (HyperText Markup Language) 可說是網頁的骨架。若說 CSS 打扮你的 HTML 而 JavaScript 讓它活起來,HTML 則是網頁應用的身體。HTML 的語法甚至佐證前行說明,它包含了 "head"、 "body" 和 "footer" 的標籤。 + +在這堂課中,我們會使用 HTML 去構建我們盆栽盒的虛擬介面。包含一個標題、三個欄位:左右各一的可拖曳植物欄位與中間的玻璃盆栽罐。這堂課程後,你會看到欄位中有許多盆栽,但介面可能會有點奇怪。不用擔心,往後的課程會講述 CSS 語法來造型化你的介面。 + +### 課題 + +在你的電腦上,建立專案資料夾 'terrarium' 並在其中建立檔案 'index.html'。你可以在 Visual Studio Code 中新增 VS Code 視窗建立你的資料夾,點擊「開啟資料夾」來檢視其中。在探索面板中點擊小小的「檔案」按鈕來建立新的檔案: + + + +或者是 + +在 git bash 中使用下列指令: +* `mkdir terrarium` +* `cd terrarium` +* `touch index.html` +* `code index.html` 或 `nano index.html` + +> index.html 檔案預設會連接到你的瀏覽器上,以網頁的方式呈現。網址像 `https://anysite.com/test` 會以資料夾結構的方式包含資料夾 `test` 與資料夾內的 `index.html`。`index.html` 不需要出現在網址當中。 + +--- + +## 文件型別宣告(DocType) 與 html 標籤 + +HTML 檔案的第一行是文件型別宣告。你會訝異這一行必須存在在檔案首行存在的意義,但這行能告訴舊款瀏覽器這份檔案開啟的模式以及它的定義方式。 + +> 提示:在 VS Code 中, 你可以把游標放在標籤上,從MDN文件庫中取得標籤的相關資訊。 + +檔案第二行會是 `<html>` 起始標籤,之後接續著 `</html>` 結束標籤。這項標籤使整個介面的根本。 + +### 課題 + +新增這些行到你的 `index.html` 檔案開頭: + +```HTML +<!DOCTYPE html> +<html></html> +``` + +✅ 有許多不一樣的文件型別模式,你可以用 query string 做設定:[怪異模式與標準模式](https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)。這些模式用來支援非常古老的瀏覽器,現在可能都不會見到的瀏覽器(Netscape Navigator 4 與 Internet Explorer 5)。 你可以觀看他們的文件型別模式宣告定義。 + +--- + +## 文件的 'head' + +HTML 文件中 'head' 的區域包含很多網頁的重要資訊,也被稱作[元資訊(metadata)](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)。我們告訴網頁伺服器我們需要哪些檔案與資訊,主要有四個: + +- 網頁標題 +- 網頁元資訊,包含: + - 字元集(Character Set),解釋網頁字元的編碼方式。 + - 瀏覽器資訊,包含 `x-ua-compatible` 讓 Internet Explorer Edge 瀏覽器支援的資訊。 + - 關於裝置的視窗資訊(Viewport)與後續視窗行為的依據。 設定視窗資訊的初始比例為 1 並控制讀取時的縮放大小。 + +### 課題 + +在網頁檔中,新增 'head' 區塊在 `<html>` 的標籤之間。 + +```html +<head> + <title>Welcome to my Virtual Terrarium</title> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> +</head> +``` + +✅ 你認為設定下列視窗元資訊 `<meta name="viewport" content="width=600">` 會發生什麼事? 請閱讀更多有關於[Viewport](https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag)的資訊。 + +--- + +## 文件的 `body` + +### HTML 標籤 + +在 HTML 中,新增標籤到你的 .html 檔案中。每個標籤都要有起始標籤與結束標籤,像是: `<p>hello</p>` 來增加文章。 在 `<html>` 標籤中利用一組 `<body>` 標籤建立新的介面內容,現在你的程式呈現如下: + +### 課題 + +```html +<!DOCTYPE html> +<html> + <head> + <title>Welcome to my Virtual Terrarium</title> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + </head> + <body></body> +</html> +``` + +現在,你可以開始豐富你的網頁內容。通常,你會使用 `<div>` 標籤來建立網頁中不同的元素。我們在一連串的 `<div>` 元素當中新增圖片。 + +### 圖片 + +其中一個不需要結束標籤的 html 標籤為 `<img>` 標籤,因為它含有 `src` 元素來提供所有網頁需要取得的資訊。 + +在專案資料夾中新增一個名叫 `images` 的資料夾,複製[我們提供的圖片](../../solution/images)到資料夾裡面,一共有十四張圖片。 + +### 課題 + +新增這些植物圖片到 `<body></body>` 標籤之間: + +```html +<div id="page"> + <div id="left-container" class="container"> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant1" src="./images/plant1.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant2" src="./images/plant2.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant3" src="./images/plant3.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant4" src="./images/plant4.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant5" src="./images/plant5.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant6" src="./images/plant6.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant7" src="./images/plant7.png" /> + </div> + </div> + <div id="right-container" class="container"> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant8" src="./images/plant8.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant9" src="./images/plant9.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant10" src="./images/plant10.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant11" src="./images/plant11.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant12" src="./images/plant12.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant13" src="./images/plant13.png" /> + </div> + <div class="plant-holder"> + <img class="plant" alt="plant" id="plant14" src="./images/plant14.png" /> + </div> + </div> +</div> +``` + +> 筆記: Spans 和 Divs。 Divs 是種「塊」元素,而 Spans 是種「內聯」元素。替換它們會發生什麼事情? + +更新這些程式碼後,現在植物出現在畫面上了。他看起來很糟,因為我們還沒用 CSS 來美化它,我們會在下堂課中處理。 + +每張圖片都有 alt 文字,即使是隱藏起來或沒取得的圖片。它是圖片提供網頁親和力很重要的屬性。你可以在之後學習更多關於網頁親和力的課程。現在,只需要記得 alt 屬性提供而外的圖片資訊,處理用戶無法觀看圖片時的資訊(連線太慢、src 屬性有誤、使用者使用螢幕報讀器......)。 + +✅ 你有發現每張圖片都有相同的 alt 標籤嗎?這樣合理嗎?為什麼?你能改善它嗎? + +--- + +## 語義化標籤 + +綜觀來說,最好使用普遍意義的標籤名稱。這是什麼意思?這代表你的 HTML 標籤必須表現它的資料型態或是它的功能性。舉例來說,網頁上的標題文字就應該使用 `<h1>` 標籤。 + +新增下列程式碼到你的 `<body>` 標籤中: + +```html +<h1>My Terrarium</h1> +``` + +使用語義化標籤如:標題 `<h1>` 和未排序串列 `<ul>` ,能幫助螢幕報讀器理解網頁的內容。普遍來說,按鈕為 `<button>` 而串列為 `<li>`。我們當然 _可以_ 用自訂義包含按鈕事件的 `<span>` 元素來替代按鈕,但這對障礙者而言,無法直接地理解語法功用會是一種負擔。基於這項原因,盡量只使用語義化標籤。 + +✅ 看看螢幕報讀器是[如何去處理一個網頁](https://www.youtube.com/watch?v=OUDV1gqs9GA)。 你可以看出非語義化標籤會怎麼阻礙用戶的嗎? + +## 盆栽盒 + +最後一項介面的要素,就是建立一個盆栽盒的雛型。 + +### 課題: + +加入這段程式碼在 `</div>` 之前: + +```html +<div id="terrarium"> + <div class="jar-top"></div> + <div class="jar-walls"> + <div class="jar-glossy-long"></div> + <div class="jar-glossy-short"></div> + </div> + <div class="dirt"></div> + <div class="jar-bottom"></div> +</div> +``` + +✅ 即使你在檔案中新增了程式碼,你卻沒看到任何東西。為什麼? + +--- + +## 🚀 挑戰 + +這邊有一些「古老」的 HTML 標籤。雖然[這些標籤](https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Obsolete_and_deprecated_elements)被歸為不推薦使用的標籤,但仍值得去嘗試的。你可以用 `<marquee>` 標籤來讓 h1 標題文字變成縱向呈現嗎?實驗完後,記得要移除這些標籤喔。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/16?loc=zh_tw) + +## 複習與自學 + +HTML 是一種「行之有效」的構築系統,建立了現今的各種網頁。從標籤來學習關於 HTML 的歷史,你能了解為什麼有的標籤被排除,而有的被新增上去嗎?有什麼標籤會在未來被建立上去呢? + +學習更多關於建立網頁的資訊:[Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-13441-cxa)。 + + +## 作業 + +[練習 HTML:建立部落格雛形](assignment.zh-tw.md) diff --git a/3-terrarium/1-intro-to-html/translations/assignment.nl.md b/3-terrarium/1-intro-to-html/translations/assignment.nl.md new file mode 100644 index 00000000..8ba1810d --- /dev/null +++ b/3-terrarium/1-intro-to-html/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Oefen uw HTML: maak een blogmodel + +## Instructies + +Stel u voor dat u uw persoonlijke website ontwerpt of herontwerpt. Maak een grafische mockup van uw site en schrijf vervolgens de HTML-opmaak op die u zou gebruiken om de verschillende elementen van de site uit te bouwen. U kunt dit op papier doen en het scannen, of u kunt software van uw keuze gebruiken. Zorg ervoor dat u de HTML-opmaak met de hand codeert. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| | Een blog lay-out wordt visueel weergegeven met ten minste 10 weergegeven markeringselementen | Een blog lay-out wordt visueel weergegeven met ongeveer 5 weergegeven markeringselementen | Een blog lay-out wordt visueel weergegeven met maximaal 3 weergegeven markeringselementen | \ No newline at end of file diff --git a/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md b/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md new file mode 100644 index 00000000..45d2397d --- /dev/null +++ b/3-terrarium/1-intro-to-html/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 練習 HTML:建立部落格雛形 + +## 簡介 + +想像你正在設計,或重新設計你自己的專屬網頁。建立網頁的圖像設計雛形,並用 HTML 語法建立這些網頁元素。你可以建在紙上並掃描它,或者是建在軟體中,只要確保有 HTML 語法在裡面。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ------------------------------------ | ------------------------------- | --------------------------------- | +| | 可以見到部落格編排包含10種以上的元素 | 見到部落格編排大約有 5 種的元素 | 見到部落格編排最多只有 3 種的元素 | \ No newline at end of file diff --git a/3-terrarium/2-intro-to-css/README.md b/3-terrarium/2-intro-to-css/README.md index 2bc08666..c10541f6 100644 --- a/3-terrarium/2-intro-to-css/README.md +++ b/3-terrarium/2-intro-to-css/README.md @@ -1,6 +1,6 @@ # Terrarium Project Part 2: Introduction to CSS - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -250,7 +250,7 @@ Add a 'bubble' shine to the left bottom area of the jar to make it look more gla  -To complete the post-lecture quiz, go through this Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) +To complete the post-lecture quiz, go through this Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) ## Post-Lecture Quiz diff --git a/3-terrarium/2-intro-to-css/translations/README.es.md b/3-terrarium/2-intro-to-css/translations/README.es.md index e961ebf9..22b39702 100644 --- a/3-terrarium/2-intro-to-css/translations/README.es.md +++ b/3-terrarium/2-intro-to-css/translations/README.es.md @@ -1,6 +1,6 @@ # Terrarium Project Parte 2: Introducción a CSS - + > Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17) @@ -252,4 +252,4 @@ CSS parece engañosamente sencillo, pero existen muchos desafíos cuando se trat **Asignación**: [Refactorización CSS](assignment.es.md) -[Diseñe su aplicación HTML con CSS](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) +[Diseñe su aplicación HTML con CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) diff --git a/3-terrarium/2-intro-to-css/translations/README.it.md b/3-terrarium/2-intro-to-css/translations/README.it.md index cbb9e55e..fb8be60f 100644 --- a/3-terrarium/2-intro-to-css/translations/README.it.md +++ b/3-terrarium/2-intro-to-css/translations/README.it.md @@ -1,6 +1,6 @@ # Progetto Terrario Parte 2: Introduzione a CSS - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione diff --git a/3-terrarium/2-intro-to-css/translations/README.ja.md b/3-terrarium/2-intro-to-css/translations/README.ja.md index 329afbff..0ee764ef 100644 --- a/3-terrarium/2-intro-to-css/translations/README.ja.md +++ b/3-terrarium/2-intro-to-css/translations/README.ja.md @@ -1,6 +1,6 @@ # テラリウムプロジェクト その2: CSS 入門 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/3-terrarium/2-intro-to-css/translations/README.ko.md b/3-terrarium/2-intro-to-css/translations/README.ko.md index 7f2ec695..56f51742 100644 --- a/3-terrarium/2-intro-to-css/translations/README.ko.md +++ b/3-terrarium/2-intro-to-css/translations/README.ko.md @@ -1,6 +1,6 @@ # Terrarium 프로젝트 파트 2: CSS 소개 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -248,7 +248,7 @@ jar 좌측 하단 부분에 'bubble' 광택을 추가하여 유리처럼 보이  -강의 후 퀴즈를 완료하려면, 다음 학습 모듈을 진행하십시오: [Style your HTML app with CSS](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) +강의 후 퀴즈를 완료하려면, 다음 학습 모듈을 진행하십시오: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) ## 강의 후 퀴즈 diff --git a/3-terrarium/2-intro-to-css/translations/README.ms.md b/3-terrarium/2-intro-to-css/translations/README.ms.md index d83e4e6c..2f678a5e 100644 --- a/3-terrarium/2-intro-to-css/translations/README.ms.md +++ b/3-terrarium/2-intro-to-css/translations/README.ms.md @@ -1,6 +1,6 @@ # Projek Terrarium Bahagian 2: Pengenalan Kepada CSS - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -248,7 +248,7 @@ Tambahkan kilauan 'bubble' ke bahagian bawah kiri balang agar kelihatan lebih me  -Untuk menyelesaikan kuiz pasca kuliah, baca modul Belajar ini: [Gaya aplikasi HTML anda dengan CSS](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics) +Untuk menyelesaikan kuiz pasca kuliah, baca modul Belajar ini: [Gaya aplikasi HTML anda dengan CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics) ## Kuiz Pasca Kuliah diff --git a/3-terrarium/2-intro-to-css/translations/README.zh-tw.md b/3-terrarium/2-intro-to-css/translations/README.zh-tw.md new file mode 100644 index 00000000..3513fd9d --- /dev/null +++ b/3-terrarium/2-intro-to-css/translations/README.zh-tw.md @@ -0,0 +1,263 @@ +# 盆栽盒專案 Part 2: CSS 簡介 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/17?loc=zh_tw) + +### 大綱 + +階層式樣式表,CSS (Cascading Style Sheets)解決了網頁開發重要的問題:如何讓網頁變得漂亮。為你的應用造型化可以讓網頁更好用、更好看。你也可以使用 CSS 建立回應式網頁設計(Responsive Web Design - RWD),依據你的視窗大小改變網頁的呈現方式。 CSS 不只讓網頁變美麗,它允許加入動畫以呈現更生動的互動體驗。CSS 工作組持續維護 CSS 的規格書,你可以在[全球資訊網協會官網](https://www.w3.org/Style/CSS/members)追蹤他們的作業。 + +> 筆記,CSS 是一種程式語言,但就像任何在網路上的東西一樣,並不是所有瀏覽器都支援最新的規格。請時常利用[CanIUse.com](https://caniuse.com)檢查你的設計是否支援相關瀏覽器。 + +這堂課中,我們會為我們的線上盆栽盒增加造型,學習更多 CSS 的概念:串接(Cascade)、繼承(Inheritance)、選擇器(Selectors)、定位(Positioning)與建立布局(Layout)。我們會規劃盆栽盒的布局,建立實際的盆栽盒。 + +### 開始之前 + +你需要確保你有盆栽盒的 HTML 程式碼,準備被造型化。 + +### 課題 + +在盆栽盒專案中,我們新增檔案 `style.css`。 在 HTML 檔案中匯入該檔案在 `<head>` 區塊中: + +```html +<link rel="stylesheet" href="./style.css" /> +``` + +--- + +## 串接(Cascade) + +串接造型表單體現了造型依照表單上的優先度「串接」在網頁應用上。網頁作者利用程式碼設定造型優先度,行內樣式(inline styles)的優先度會比外部造型表單來的高。 + +### 課題 + +新增行內造型 "color: red" 到 `<h1>` 標籤中: + +```HTML +<h1 style="color: red">My Terrarium</h1> +``` + +之後,也新增下列程式碼在 `style.css` 檔案中: + +```CSS +h1 { + color: blue; +} +``` + +✅ 你的網頁顯示了哪一種顏色?為什麼?你能找到方法覆蓋這個造型嗎?何時會讓你想用這套做法呢?又為什麼不呢? + +--- + +## 繼承(Inheritance) + +從父關係標籤到子關係標籤上繼承造型,如被嵌套的物件會繼承容器物件的造型。 + +### 課題 + +我們設定 body 的字體為特定字型,確認嵌套物件的字型: + +```CSS +body { + font-family: helvetica, arial, sans-serif; +} +``` + +開啟你的瀏覽器命令欄到 'Elements' 標籤中,觀察 H1 的字型。它繼承了 body 的字型,表現在瀏覽器上: + + + +✅ 你能讓被嵌套元素繼承其他格式嗎? + +--- + +## CSS 選擇器(Selectors) + +### 標籤 + +到目前為止,你的 `style.css` 檔案只有一部份標籤被造型化,這讓程式看起來很怪: + +```CSS +body { + font-family: helvetica, arial, sans-serif; +} + +h1 { + color: #3a241d; + text-align: center; +} +``` + +這種造型方法只能控制被指定的元素,但如果你需要套用在每一種盆栽盒內的植物。你需要利用 CSS 選擇器。 + +### Ids + +新增左容器與右容器造型布局。因為網頁內只有一個左容器與右容器,我們就這樣命名 id 標記。要造型化它們,使用 `#`: + +```CSS +#left-container { + background-color: #eee; + width: 15%; + left: 0px; + top: 0px; + position: absolute; + height: 100%; + padding: 10px; +} + +#right-container { + background-color: #eee; + width: 15%; + right: 0px; + top: 0px; + position: absolute; + height: 100%; + padding: 10px; +} +``` + +這裡,你已經將容器擺在絕對位置上了,一個位在左側,一個位在右側。容器寬度使用百分比以確保它們在小螢幕裝置上也能運作正常。 + +✅ 這兩段樣式已經重複了,請不要照抄。你能找到更好的方式來造型化這些 ids 嗎? 或許你可以從 id 或 class 來下手。讓 CSS 套用在容器上,我們需要改寫 HTML 程式碼: + +```html +<div id="left-container" class="container"></div> +``` + +### Classes + +在上述例子中,你成功地為兩樣物件新增造型。如果你想一次套用在多樣物件上,你就需要 CSS classes。利用這個方法來布局兩個容器。 + +注意每個植物的標記都有 ids 與 classes。JavaScript 使用 Id 標記來控制植物的擺放; class 則是被 CSS 套用特定的造型。 + +```html +<div class="plant-holder"> + <img class="plant" alt="plant" id="plant1" src="./images/plant1.png" /> +</div> +``` + +新增下列程式碼到 `style.css` 檔案中: + +```CSS +.plant-holder { + position: relative; + height: 13%; + left: -10px; +} + +.plant { + position: absolute; + max-width: 150%; + max-height: 150%; + z-index: 2; +} +``` + +片段開頭是 CSS 的定位屬性,分為相對與絕對定位,我們會在下一個段落進行解述。我們來看看百分比高度的方式: + +你設定了植物架高度為 13%,確保所有植物都能在不需要滾動容器的情況下,在每一個垂直的容器中顯示出來。 + +你設定了植物架向左移 10 像素,讓植物能在容器的正中間。圖片上亦有大區域的透明區域需要被拖曳過來,往左位移更適合呈現在畫面上。 + +之後,植物設定寬度為 150%。 當瀏覽器調整比例時,也能同時將植物圖片作大小的調整。試著改變瀏覽器檢視比例,植物依舊會保持在容器中。 + +我們換看 z-index,控制物件的相對高度,讓植物坐落在容器上方且在盆栽盒內部。 + +✅ 為什麼需要分為植物架與植物 CSS 選擇器? + +## 定位(Positioning) + +多樣的定位屬性,包含靜態(static)、相對(relative)、固定(fixed)、絕對(absolute)和黏貼(sticky),有時候讓人難以駕馭,但成功設定完後,可以讓你完整地掌握元素坐落的位置。 + +絕對定位元素會依照他的父關係物件來決定定位位置,若沒有關係物件,整個文件的 body 就會成為定位依據。 + +相對定位元素則依照 CSS 指定的方向來調整他的起始位置。 + +在我們的樣本中,`plant-holder` 是相對定位元素,坐落在絕對定位的容器當中。因此,容器被定義在左側與右側,而被嵌入的植物架會調整它在容器的位置,保持植物之間的間隔。 + +> `plant` 本身也擁有絕對定位,為了讓圖片被拖曳,你能在下段課程中發現更多資訊。 + +✅ 試著改變容器與植物架的定位模式。發生了什麼事? + +## 布局(Layouts) + +現在,你已經善用你所學的,只用 CSS 建出盆栽盒! + +首先,對 `.terrarium` 的 div 子關係物件加上圓邊矩形: + +```CSS +.jar-walls { + height: 80%; + width: 60%; + background: #d1e1df; + border-radius: 10%; + position: absolute; + bottom: 0.5%; + left: 20%; + opacity: 0.5; + z-index: 1; +} + +.jar-top { + width: 50%; + height: 5%; + background: #d1e1df; + position: absolute; + bottom: 80.5%; + left: 25%; + opacity: 0.7; + z-index: 1; +} + +.jar-bottom { + width: 50%; + height: 1%; + background: #d1e1df; + position: absolute; + bottom: 0%; + left: 25%; + opacity: 0.7; +} + +.dirt { + width: 58%; + height: 5%; + background: #3a241d; + position: absolute; + border-radius: 0 0 4rem 4rem; + bottom: 1%; + left: 21%; + opacity: 0.7; + z-index: -1; +} +``` + +注意這邊百分比的用法,即使是 `border-radius` 也請留意。 當瀏覽器調整檢視比例時,你會發現玻璃罐也會受到調整。 其他值得注意的地方為:玻璃罐的寬度與高度百分比,每個元素絕對定位在中心與視窗的下方。 + +✅ 試著改變罐子的顏色與透明度,觀察泥土與罐子的關係。發生了什麼事?為什麼? + +--- + +## 🚀 挑戰 + +新增「氣泡反光」在罐子左下方的位置,讓玻璃材質更擬真一些。你需要編輯 `.jar-glossy-long` 與 `.jar-glossy-short` 造型集來模擬罐子反光。下面是成果圖: + + + +在做課後測驗前,請先前往下列的學習頁面:[用 CSS 造型化你的網頁應用](https://docs.microsoft.com/en-us/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa) + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/18?loc=zh_tw) + +## 複習與自學 + +CSS 看似很好上手,但要在所有瀏覽器與螢幕大小上運作正常,也會面臨到許多挑戰。CSS-Grid 與 Flexbox 這兩種工具讓上述作業變得比較好規劃與調整。藉由遊玩[Flexbox Froggy](https://flexboxfroggy.com/)與[Grid Garden](https://codepip.com/games/grid-garden/)來學習它們。 + +## 作業 + +[重構 CSS](assignment.zh-tw.md) diff --git a/3-terrarium/2-intro-to-css/translations/assignment.nl.md b/3-terrarium/2-intro-to-css/translations/assignment.nl.md new file mode 100644 index 00000000..02ff0bc8 --- /dev/null +++ b/3-terrarium/2-intro-to-css/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# CSS-Refactoring + +## Instructies + +Restyle het terrarium met Flexbox of CSS Grid en maak screenshots om te laten zien dat u het in verschillende browsers hebt getest. Mogelijk moet u de opmaak wijzigen, dus maak een nieuwe versie van de app met de kunst voor uw refactor. Maakt u geen zorgen over het versleepbaar maken van de elementen; alleen de HTML en CSS refactoren voor nu. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ----------------------------------------------------------------- | ----------------------------- | ------------------------------------ | +| | Presenteer een volledig gerestyled terrarium met Flexbox of CSS Grid | Restyle een paar van de elementen | Het terrarium helemaal niet restylen | diff --git a/3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md b/3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md new file mode 100644 index 00000000..614f93cc --- /dev/null +++ b/3-terrarium/2-intro-to-css/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 重構 CSS + +## 簡介 + +使用 Flexbox 或 CSS Grid 重新規劃盆栽盒,拍幾張在不同瀏覽器上運作的畫面。重新規劃時,你可能需要改變程式碼中版本的標記。不需要去考慮植物拖曳的問題,我們只重構 HTML 與 CSS 的部分。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | --------------------------------------- | ---------------- | -------------------- | +| | 使用 Flexbox 或 CSS Grid 呈現新的盆栽盒 | 重新取代部分元素 | 無法更新原有的盆栽盒 | diff --git a/3-terrarium/3-intro-to-DOM-and-closures/README.md b/3-terrarium/3-intro-to-DOM-and-closures/README.md index 577d4139..ca0080f6 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/README.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/README.md @@ -1,6 +1,6 @@ # Terrarium Project Part 3: DOM Manipulation and a Closure - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## Pre-Lecture Quiz @@ -9,11 +9,11 @@ ### Introduction -Manipulating the DOM, or the "Document Object Model", is a key aspect of web development. According to [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." The challenges around DOM manipulation on the web have often been the impetus behind using JavaScript frameworks instead of vanilla JavaScript to manage the DOM, but we will manage on our own! +Manipulating the DOM, or the "Document Object Model", is a key aspect of web development. According to [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." The challenges around DOM manipulation on the web have often been the impetus behind using JavaScript frameworks instead of vanilla JavaScript to manage the DOM, but we will manage on our own! -In addition, this lesson will introduce the idea of a [JavaScript closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), which you can think of as a function enclosed by another function so that the inner function has access to the outer function's scope. +In addition, this lesson will introduce the idea of a [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures), which you can think of as a function enclosed by another function so that the inner function has access to the outer function's scope. -> JavaScript closures are a vast and complex topic. This lesson touches on the most basic idea that in this terrarium's code, you will find a closure: an inner function and an outer function constructed in a way to allow the inner function access to the outer function's scope. For much more information on how this works, please visit the [extensive documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). +> JavaScript closures are a vast and complex topic. This lesson touches on the most basic idea that in this terrarium's code, you will find a closure: an inner function and an outer function constructed in a way to allow the inner function access to the outer function's scope. For much more information on how this works, please visit the [extensive documentation](https://developer.mozilla.org/docs/Web/JavaScript/Closures). We will use a closure to manipulate the DOM. @@ -108,9 +108,9 @@ function dragElement(terrariumElement) { `dragElement` get its `terrariumElement` object from the declarations at the top of the script. Then, you set some local positions at `0` for the object passed into the function. These are the local variables that will be manipulated for each element as you add drag and drop functionality within the closure to each element. The terrarium will be populated by these dragged elements, so the application needs to keep track of where they are placed. -In addition, the terrariumElement that is passed to this function is assigned a `pointerdown` event, which is part of the [web APIs](https://developer.mozilla.org/en-US/docs/Web/API) designed to help with DOM management. `onpointerdown` fires when a button is pushed, or in our case, a draggable element is touched. This event handler works on both [web and mobile browsers](https://caniuse.com/?search=onpointerdown), with a few exceptions. +In addition, the terrariumElement that is passed to this function is assigned a `pointerdown` event, which is part of the [web APIs](https://developer.mozilla.org/docs/Web/API) designed to help with DOM management. `onpointerdown` fires when a button is pushed, or in our case, a draggable element is touched. This event handler works on both [web and mobile browsers](https://caniuse.com/?search=onpointerdown), with a few exceptions. -✅ The [event handler `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) has much more support cross-browser; why wouldn't you use it here? Think about the exact type of screen interaction you're trying to create here. +✅ The [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) has much more support cross-browser; why wouldn't you use it here? Think about the exact type of screen interaction you're trying to create here. --- @@ -205,9 +205,9 @@ Add new event handler to your closure to do something more to the plants; for ex ## Review & Self Study -While dragging elements around the screen seems trivial, there are many ways to do this and many pitfalls, depending on the effect you seek. In fact, there is an entire [drag and drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) that you can try. We didn't use it in this module because the effect we wanted was somewhat different, but try this API on your own project and see what you can achieve. +While dragging elements around the screen seems trivial, there are many ways to do this and many pitfalls, depending on the effect you seek. In fact, there is an entire [drag and drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) that you can try. We didn't use it in this module because the effect we wanted was somewhat different, but try this API on your own project and see what you can achieve. -Find more information on pointer events on the [W3C docs](https://www.w3.org/TR/pointerevents1/) and on [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events). +Find more information on pointer events on the [W3C docs](https://www.w3.org/TR/pointerevents1/) and on [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events). Always check browser capabilities using [CanIUse.com](https://caniuse.com/). diff --git a/3-terrarium/3-intro-to-DOM-and-closures/assignment.md b/3-terrarium/3-intro-to-DOM-and-closures/assignment.md index 6b1c9f61..4bf324c3 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/assignment.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/assignment.md @@ -2,7 +2,7 @@ ## Instructions -Research the DOM a little more by 'adopting' a DOM element. Visit the MSN's [list of DOM interfaces](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) and pick one. Find it being used on a web site in the web, and write an explanation of how it is used. +Research the DOM a little more by 'adopting' a DOM element. Visit the MSN's [list of DOM interfaces](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) and pick one. Find it being used on a web site in the web, and write an explanation of how it is used. ## Rubric diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.es.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.es.md index 29a36fe5..7b06d5bd 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.es.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.es.md @@ -1,15 +1,15 @@ # Terrarium Project Part 3: DOM Manipulación y cierre -! [DOM y un cierre](../images/webdev101-js.png) +! [DOM y un cierre](/sketchnotes/webdev101-js.png) > Boceto de [Tomomi Imura](https://twitter.com/girlie_mac) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19) ### Introducción: -Manipular el DOM, o el "Modelo de objetos de documento", es un aspecto clave del desarrollo web. Según [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), "El modelo de objetos de documento (DOM) es la representación de datos de los objetos que componen la estructura y contenido de un documento en la web ". Los desafíos en torno a la manipulación de DOM en la web a menudo han sido el ímpetu detrás del uso de marcos de JavaScript en lugar de JavaScript vanilla para administrar el DOM, ¡pero lo administraremos por nuestra cuenta! +Manipular el DOM, o el "Modelo de objetos de documento", es un aspecto clave del desarrollo web. Según [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "El modelo de objetos de documento (DOM) es la representación de datos de los objetos que componen la estructura y contenido de un documento en la web ". Los desafíos en torno a la manipulación de DOM en la web a menudo han sido el ímpetu detrás del uso de marcos de JavaScript en lugar de JavaScript vanilla para administrar el DOM, ¡pero lo administraremos por nuestra cuenta! -Además, esta lección presentará la idea de un [cierre de JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), que puede considerar como una función encerrada por otra función para que la función interna tenga acceso al alcance de la función externa. +Además, esta lección presentará la idea de un [cierre de JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), que puede considerar como una función encerrada por otra función para que la función interna tenga acceso al alcance de la función externa. Usaremos un cierre para manipular el DOM. @@ -108,9 +108,9 @@ function dragElement(terrariumElement) { `dragElement` obtiene su objeto` terrariumElement` de las declaraciones en la parte superior del script. Luego, establece algunas posiciones locales en "0" para el objeto pasado a la función. Estas son las variables locales que se manipularán para cada elemento a medida que agrega la funcionalidad de arrastrar y soltar dentro del cierre de cada elemento. El terrario estará poblado por estos elementos arrastrados, por lo que la aplicación debe realizar un seguimiento de dónde se colocan. -Además, al terrariumElement que se pasa a esta función se le asigna un evento `pointerdown`, que forma parte de las [API web](https://developer.mozilla.org/en-US/docs/Web/API) diseñadas para ayudar con la gestión del DOM. `Onpointerdown` se dispara cuando se presiona un botón, o en nuestro caso, se toca un elemento que se puede arrastrar. Este controlador de eventos funciona tanto en [navegadores web como móviles](https://caniuse.com/?search=onpointerdown), con algunas excepciones. +Además, al terrariumElement que se pasa a esta función se le asigna un evento `pointerdown`, que forma parte de las [API web](https://developer.mozilla.org/docs/Web/API) diseñadas para ayudar con la gestión del DOM. `Onpointerdown` se dispara cuando se presiona un botón, o en nuestro caso, se toca un elemento que se puede arrastrar. Este controlador de eventos funciona tanto en [navegadores web como móviles](https://caniuse.com/?search=onpointerdown), con algunas excepciones. -✅ El [controlador de eventos `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) tiene mucho más soporte entre navegadores; ¿Por qué no lo usarías aquí? Piense en el tipo exacto de interacción de pantalla que está intentando crear aquí. +✅ El [controlador de eventos `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) tiene mucho más soporte entre navegadores; ¿Por qué no lo usarías aquí? Piense en el tipo exacto de interacción de pantalla que está intentando crear aquí. --- @@ -201,7 +201,7 @@ Esta pequeña función restablece los eventos `onpointerup` y `onpointermove` pa ## Revisión y autoestudio -Si bien arrastrar elementos por la pantalla parece trivial, hay muchas formas de hacerlo y muchas trampas, según el efecto que busque. De hecho, hay una [API de arrastrar y soltar](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) completa que puedes probar. No lo usamos en este módulo porque el efecto que queríamos era algo diferente, pero pruebe esta API en su propio proyecto y vea lo que puede lograr. +Si bien arrastrar elementos por la pantalla parece trivial, hay muchas formas de hacerlo y muchas trampas, según el efecto que busque. De hecho, hay una [API de arrastrar y soltar](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) completa que puedes probar. No lo usamos en este módulo porque el efecto que queríamos era algo diferente, pero pruebe esta API en su propio proyecto y vea lo que puede lograr. ** Tarea: [Trabajar un poco más con el DOM](assignment.es.md) diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.it.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.it.md index 25d90cc2..d83b3be8 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.it.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.it.md @@ -1,6 +1,6 @@ # Progetto Terrario Parte 3: Manipolazione del DOM e Closure - + > Sketchnote di [Tomomi Imura](https://twitter.com/girlie_mac) ## Quiz Pre-Lezione @@ -9,11 +9,11 @@ ### Introduzione -La manipolazione del DOM, acronimo per "Document Object Model", è un aspetto chiave dello sviluppo web. Secondo [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), "Il Document Object Model (DOM) è la rappresentazione dei dati degli oggetti che compongono la struttura e il contenuto di un documento sul web". Le sfide intorno alla manipolazione del DOM sul Web sono state spesso l'impulso dietro l'utilizzo di infrastrutture (framework) JavaScript invece di JavaScript puro (vanilla) per gestire il DOM, ma ce la faremo da soli! +La manipolazione del DOM, acronimo per "Document Object Model", è un aspetto chiave dello sviluppo web. Secondo [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Il Document Object Model (DOM) è la rappresentazione dei dati degli oggetti che compongono la struttura e il contenuto di un documento sul web". Le sfide intorno alla manipolazione del DOM sul Web sono state spesso l'impulso dietro l'utilizzo di infrastrutture (framework) JavaScript invece di JavaScript puro (vanilla) per gestire il DOM, ma ce la faremo da soli! -Inoltre, questa lezione introdurrà l'idea di una [closure JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), che si può intendere come una funzione racchiusa da un'altra funzione in modo che la funzione più interna abbia accesso all'ambito della funzione più esterna. +Inoltre, questa lezione introdurrà l'idea di una [closure JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), che si può intendere come una funzione racchiusa da un'altra funzione in modo che la funzione più interna abbia accesso all'ambito della funzione più esterna. -> Le closure JavaScript sono un argomento vasto e complesso. Questa lezione tocca l'idea più basilare che nel codice di questo terrario si troverà una closure: una funzione interna e una funzione esterna costruite in modo da consentire alla funzione interna di accedere all'ambito della funzione esterna. Per molte più informazioni su come funziona, visitare l'[ampia documentazione](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). +> Le closure JavaScript sono un argomento vasto e complesso. Questa lezione tocca l'idea più basilare che nel codice di questo terrario si troverà una closure: una funzione interna e una funzione esterna costruite in modo da consentire alla funzione interna di accedere all'ambito della funzione esterna. Per molte più informazioni su come funziona, visitare l'[ampia documentazione](https://developer.mozilla.org/docs/Web/JavaScript/Closures). Verra usata una closure per manipolare il DOM. @@ -110,7 +110,7 @@ function dragElement(terrariumElement) { Inoltre, al terrariumElement passato a questa funzione viene assegnato un evento di riconoscimento pressione pulsante (`pointerdown`), che fa parte delle [API web](https://developer.mozilla.org/it/docs/Web/API) progettate per aiutare con la gestione del DOM. `onpointerdown` si attiva quando viene premuto un pulsante o, in questo caso, viene toccato un elemento trascinabile. Questo gestore di evento funziona sia su browser [web che su browser di dispositivi mobili](https://caniuse.com/?search=onpointerdown), con poche eccezioni. -✅ Il [gestore di evento `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) ha molto più supporto intra-browser; perché non viene usato qui? Si pensi al tipo esatto di interazione con lo schermo che si sta cercando di creare qui. +✅ Il [gestore di evento `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) ha molto più supporto intra-browser; perché non viene usato qui? Si pensi al tipo esatto di interazione con lo schermo che si sta cercando di creare qui. --- @@ -205,9 +205,9 @@ Aggiungere un nuovo gestore di eventi alla closure per fare qualcosa di più con ## Revisione e Auto Apprendimento -Mentre trascinare elementi sullo schermo sembra banale, ci sono molti modi per farlo e molte insidie, a seconda dell'effetto che si cerca. In effetti, esiste un'intera [API di trascinamento della selezione](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) che si può provare. Non è stata usata in questo modulo perché l'effetto che si voleva era leggermente diverso, tuttavia provare questa API sul proprio progetto per vedere cosa si può ottenere. +Mentre trascinare elementi sullo schermo sembra banale, ci sono molti modi per farlo e molte insidie, a seconda dell'effetto che si cerca. In effetti, esiste un'intera [API di trascinamento della selezione](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) che si può provare. Non è stata usata in questo modulo perché l'effetto che si voleva era leggermente diverso, tuttavia provare questa API sul proprio progetto per vedere cosa si può ottenere. -Trovare ulteriori informazioni sugli eventi di puntamento nei [documenti W3C](https://www.w3.org/TR/pointerevents1/) e nei [documenti Web MDN](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events). +Trovare ulteriori informazioni sugli eventi di puntamento nei [documenti W3C](https://www.w3.org/TR/pointerevents1/) e nei [documenti Web MDN](https://developer.mozilla.org/docs/Web/API/Pointer_events). Controllare sempre le funzionalità del browser utilizzando [CanIUse.com](https://caniuse.com/). diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ja.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ja.md index 2c400ff7..b2bfd52e 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ja.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ja.md @@ -1,6 +1,6 @@ # テラリウムプロジェクト その3: DOM の操作とクロージャ - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## レッスン前の小テスト diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ko.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ko.md index 6c55316b..cf624715 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ko.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ko.md @@ -1,6 +1,6 @@ # Terrarium 프로젝트 파트 3: DOM 조작과 클로저 - + > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) ## 강의 전 퀴즈 @@ -9,9 +9,9 @@ ### 소개 -DOM 또는 "Document Object Model"을 조작하는 것은 웹 개발의 핵심입니다. [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction)에 따르면, "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." 이라고 합니다. 웹의 DOM 조작과 관련하여 간혹 DOM을 관리하기 위해 순수 JavaScript 대신 JavaScript 프레임워크를 도전하게 되는 원동력이지만, 우리는 스스로 관리할 것입니다! +DOM 또는 "Document Object Model"을 조작하는 것은 웹 개발의 핵심입니다. [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)에 따르면, "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." 이라고 합니다. 웹의 DOM 조작과 관련하여 간혹 DOM을 관리하기 위해 순수 JavaScript 대신 JavaScript 프레임워크를 도전하게 되는 원동력이지만, 우리는 스스로 관리할 것입니다! -추가로, 이 강의에서는 [JavaScript closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)에 대한 아이디어를 소개합니다. 내부 함수가 외부 함수의 범위에 접근할 수 있도록 합니다. +추가로, 이 강의에서는 [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures)에 대한 아이디어를 소개합니다. 내부 함수가 외부 함수의 범위에 접근할 수 있도록 합니다. DOM을 조작하기 위해 클로저를 사용할 예정입니다. @@ -106,9 +106,9 @@ function dragElement(terrariumElement) { `dragElement`는 스크립트 상단의 선언에서 `terrariumElement` 객체를 가져옵니다. 그러고, 함수에 전달된 객체의 일부 로컬 위치를 `0`으로 설정합니다. 클로저 안에서 드래그 앤 드롭 기능을 각 요소에 추가할 때 각 요소에 대해 조작될 지역 변수입니다. terrarium에 드래그된 요소로 채워지므로, 애플리케이션은 배치된 위치를 추적해야 합니다. -추가로, 이 함수에 전달되는 terrariumElement에는 DOM 관리에 도움이 되도록 설계된 [web APIs](https://developer.mozilla.org/en-US/docs/Web/API)의 일부인 `pointerdown` 이벤트가 할당됩니다. `onpointerdown`은 버튼이 눌리거나 드래그 하는 요소가 터치될 때 발생합니다. 이 이벤트 핸들러는 몇 가지 예외를 제외하고, [웹과 모바일 브라우저](https://caniuse.com/?search=onpointerdown) 다 작동합니다. +추가로, 이 함수에 전달되는 terrariumElement에는 DOM 관리에 도움이 되도록 설계된 [web APIs](https://developer.mozilla.org/docs/Web/API)의 일부인 `pointerdown` 이벤트가 할당됩니다. `onpointerdown`은 버튼이 눌리거나 드래그 하는 요소가 터치될 때 발생합니다. 이 이벤트 핸들러는 몇 가지 예외를 제외하고, [웹과 모바일 브라우저](https://caniuse.com/?search=onpointerdown) 다 작동합니다. -✅ [event handler `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick)은 크로스 브라우저 지원이 훨씬 더 많습니다. 왜 여기서 사용하지 않나요? 여기에서 만들고자 하는 정확한 화면 상호작용 타입에 대해 생각해보세요. +✅ [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick)은 크로스 브라우저 지원이 훨씬 더 많습니다. 왜 여기서 사용하지 않나요? 여기에서 만들고자 하는 정확한 화면 상호작용 타입에 대해 생각해보세요. --- @@ -203,9 +203,9 @@ function stopElementDrag() { ## 리뷰 & 자기주도 학습 -화면에서 요소를 드래그하는 것은 사소한 것처럼 보이지만, 원하는 효과에 따라 여러 가지 방식과 함정이 있습니다. 실제로, 시도할 수 있는 전체 [drag and drop API](https://developer.mozilla.org/en-US/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 docs](https://www.w3.org/TR/pointerevents1/)와 [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events)에서 확인하세요. +포인터 이벤트에 대한 자세한 내용은 [W3C docs](https://www.w3.org/TR/pointerevents1/)와 [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events)에서 확인하세요. 항상 [CanIUse.com](https://caniuse.com/)으로 브라우저 기능을 확인하십시오. diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ms.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ms.md index d41f99e5..cea0c17d 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ms.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.ms.md @@ -1,6 +1,6 @@ # Projek Terrarium Bahagian 3: Memanipulasi DOM dan Penutupan - + > Sketchnote karya [Tomomi Imura](https://twitter.com/girlie_mac) ## Kuiz Pra Kuliah @@ -9,11 +9,11 @@ ### Pengenalan -Memanipulasi DOM, atau "Document Object Model", adalah aspek penting dalam pengembangan web. Menurut [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) adalah representasi data dari objek yang terdiri dari struktur dan kandungan dokumen di web. " Cabaran di sekitar manipulasi DOM di web sering menjadi dorongan di belakang menggunakan kerangka kerja JavaScript dan bukannya JavaScript vanila untuk menguruskan DOM, tetapi kami akan menguruskannya sendiri! +Memanipulasi DOM, atau "Document Object Model", adalah aspek penting dalam pengembangan web. Menurut [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Document Object Model (DOM) adalah representasi data dari objek yang terdiri dari struktur dan kandungan dokumen di web. " Cabaran di sekitar manipulasi DOM di web sering menjadi dorongan di belakang menggunakan kerangka kerja JavaScript dan bukannya JavaScript vanila untuk menguruskan DOM, tetapi kami akan menguruskannya sendiri! -Selain itu, pelajaran ini akan memperkenalkan idea [Penutupan JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), yang dapat anda fikirkan sebagai fungsi yang dilampirkan oleh yang lain berfungsi sehingga fungsi dalaman mempunyai akses ke ruang fungsi scope luar. +Selain itu, pelajaran ini akan memperkenalkan idea [Penutupan JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), yang dapat anda fikirkan sebagai fungsi yang dilampirkan oleh yang lain berfungsi sehingga fungsi dalaman mempunyai akses ke ruang fungsi scope luar. -> Penutupan JavaScript adalah topik yang luas dan kompleks. Pelajaran ini menyentuh idea paling asas bahawa dalam kod terarium ini, anda akan menemui penutup: fungsi dalaman dan fungsi luar yang dibina dengan cara yang membolehkan fungsi dalaman mengakses ke ruang lingkup fungsi luar. Untuk lebih banyak maklumat mengenai cara ini berfungsi, sila lawati [dokumentasi yang luas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). +> Penutupan JavaScript adalah topik yang luas dan kompleks. Pelajaran ini menyentuh idea paling asas bahawa dalam kod terarium ini, anda akan menemui penutup: fungsi dalaman dan fungsi luar yang dibina dengan cara yang membolehkan fungsi dalaman mengakses ke ruang lingkup fungsi luar. Untuk lebih banyak maklumat mengenai cara ini berfungsi, sila lawati [dokumentasi yang luas](https://developer.mozilla.org/docs/Web/JavaScript/Closures). Kami akan menggunakan penutup untuk memanipulasi DOM. @@ -108,9 +108,9 @@ function dragElement(terrariumElement) { `dragElement` dapatkan objek` terrariumElement` dari pernyataan di bahagian atas skrip. Kemudian, anda menetapkan beberapa kedudukan tempatan pada `0` untuk objek yang dilewatkan ke dalam fungsi. Ini adalah pemboleh ubah tempatan yang akan dimanipulasi untuk setiap elemen semasa anda menambahkan fungsi seret dan lepas dalam penutupan ke setiap elemen. Terarium akan dihuni oleh unsur-unsur yang diseret ini, jadi aplikasinya perlu memantau lokasi mereka ditempatkan. -Selain itu, elemen terarium yang diteruskan ke fungsi ini diberikan acara `pointerdown`, yang merupakan sebahagian dari [web API](https://developer.mozilla.org/en-US/docs/Web/API) yang dirancang untuk membantu pengurusan DOM. `onpointerdown` menyala apabila butang ditekan, atau dalam kes kita, elemen yang boleh diseret disentuh. Pengendali acara ini berfungsi pada [penyemak imbas web dan mudah alih](https://caniuse.com/?search=onpointerdown), dengan beberapa pengecualian. +Selain itu, elemen terarium yang diteruskan ke fungsi ini diberikan acara `pointerdown`, yang merupakan sebahagian dari [web API](https://developer.mozilla.org/docs/Web/API) yang dirancang untuk membantu pengurusan DOM. `onpointerdown` menyala apabila butang ditekan, atau dalam kes kita, elemen yang boleh diseret disentuh. Pengendali acara ini berfungsi pada [penyemak imbas web dan mudah alih](https://caniuse.com/?search=onpointerdown), dengan beberapa pengecualian. -✅ [Pengendali acara (event handler) `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) mempunyai sokongan penyemak imbas yang lebih banyak; mengapa anda tidak menggunakannya di sini? Fikirkan jenis interaksi skrin yang tepat yang ingin anda buat di sini. +✅ [Pengendali acara (event handler) `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) mempunyai sokongan penyemak imbas yang lebih banyak; mengapa anda tidak menggunakannya di sini? Fikirkan jenis interaksi skrin yang tepat yang ingin anda buat di sini. --- @@ -205,9 +205,9 @@ Tambahkan pengendali acara (event handler) baharu ke penutupan anda untuk melaku ## Mengkaji & Belajar Sendiri -Walaupun menyeret elemen di sekitar skrin kelihatan remeh, ada banyak cara untuk melakukan ini dan banyak perangkap, bergantung pada kesan yang anda cari. Sebenarnya, terdapat keseluruhan [drag and drop API] (https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) yang boleh anda cuba. Kami tidak menggunakannya dalam modul ini kerana kesan yang kami mahukan agak berbeza, tetapi cuba API ini pada projek anda sendiri dan lihat apa yang boleh anda capai. +Walaupun menyeret elemen di sekitar skrin kelihatan remeh, ada banyak cara untuk melakukan ini dan banyak perangkap, bergantung pada kesan yang anda cari. Sebenarnya, terdapat keseluruhan [drag and drop API] (https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) yang boleh anda cuba. Kami tidak menggunakannya dalam modul ini kerana kesan yang kami mahukan agak berbeza, tetapi cuba API ini pada projek anda sendiri dan lihat apa yang boleh anda capai. -Dapatkan lebih banyak maklumat mengenai peristiwa penunjuk pada [dokumen W3C](https://www.w3.org/TR/pointerevents1/) dan di [dokumen web MDN](https://developer.mozilla.org/en-US/ dokumen / Web / API / Pointer_events). +Dapatkan lebih banyak maklumat mengenai peristiwa penunjuk pada [dokumen W3C](https://www.w3.org/TR/pointerevents1/) dan di [dokumen web MDN](https://developer.mozilla.org/ dokumen / Web / API / Pointer_events). Sentiasa periksa keupayaan penyemak imbas menggunakan [CanIUse.com](https://caniuse.com/). diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/README.zh-tw.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.zh-tw.md new file mode 100644 index 00000000..5c7c75c2 --- /dev/null +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/README.zh-tw.md @@ -0,0 +1,219 @@ +# 盆栽盒專案 Part 3 - DOM 元素控制與閉包 + + +> 由 [Tomomi Imura](https://twitter.com/girlie_mac) 繪製 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/19?loc=zh_tw) + +### 大綱 + +操作 DOM (Document Object Model) 是網頁開發的一項關鍵。根據[MDN 文件](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction), 「Document Object Model (DOM) 元素能根據網頁文件的結構與內容來呈現物件」。藉由使用 JavaScript 框架而非原始的 JavaScript 程式碼來管理 DOM,在網頁上操作 DOM 的挑戰已經不比以前困難了,但這裡我們要自己來管理它們! + +此外,這堂課也會介紹有關[JavaScript 閉包(Closure)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)的概念,你可以想像成一個函式被包在另一個函式中,以訪問外面函式範圍中的變數。 + +> JavaScript 閉包是個廣闊且複雜的主題。本堂課只觸及建立盆栽盒需要的最基礎概念。你能得知一個閉包為:內部函式和外部函式建立一項關係,允許內部函式存取外部函式的變數等作用域。要得知更多關於閉包的原理,請造訪觀看[額外的文件](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)。 + +我們會使用閉包來操控 DOM。 + +想像 DOM 就像一棵樹,表現出所有操作網頁的方式。多樣的 APIs (Application Program Interfaces) 提供程式開發者,依照自己使用的程式語言,以存取、編輯、編排等方式管理 DOM 元素。 + + + +> HTML 語法會參考 DOM 的呈現方式。出自 [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)。 + +在這堂課中,我們會完成我們的盆栽盒專案,建立 JavaScript 來對網頁中的植物進行互動式操作。 + +### 開始之前 + +確保盆栽盒的 HTML 與 CSS 已經編輯完成。這堂課會新增拖曳植物進出盆栽罐的功能。 + +### 課題 + +在專案資料夾中,新增檔案 `script.js`。 匯入該檔案在 HTML 檔 `<head>` 的部分: + +```html + <script src="./script.js" defer></script> +``` + +> 筆記:匯入外部 JavaScript 檔案到 HTML 檔案須使用 `defer`,讓 JavaScript 檔案只有在 HTML 被完全載入時才被執行。你也可以使用 `async` 的屬性,允許 JavaScript 在解析 HTML 檔時就被執行。這項專案中,我們必須確保 HTML 的元件被完整建立後才允許使用拖曳功能。 +--- + +## DOM 元素 + +我們要做的第一件事是建立 DOM 下,要被操控的物件的連結。在專案例子中,我們有罐子外的十四株植物等著被拖曳。 + +### 課題 + +```html +dragElement(document.getElementById('plant1')); +dragElement(document.getElementById('plant2')); +dragElement(document.getElementById('plant3')); +dragElement(document.getElementById('plant4')); +dragElement(document.getElementById('plant5')); +dragElement(document.getElementById('plant6')); +dragElement(document.getElementById('plant7')); +dragElement(document.getElementById('plant8')); +dragElement(document.getElementById('plant9')); +dragElement(document.getElementById('plant10')); +dragElement(document.getElementById('plant11')); +dragElement(document.getElementById('plant12')); +dragElement(document.getElementById('plant13')); +dragElement(document.getElementById('plant14')); +``` + +發生了什麼事?你正以 DOM 搜尋網頁檔內的物件,藉由 Id 作為依據來搜尋。回想第一堂 HTML 課中,我們可每一株植物一個專屬的 Id (`id="plant1"`),現在你就可以使用它。在辨別完每一株植物物件後,傳遞給待編輯的函式 `dragElement`,讓 HTML 物件可以被拖曳。 + +✅ 為什麼我們要以 Id 作為物件的參考?為什麼不以 CSS 的 class 作為參考?請參考以前的 CSS 課程回答此問題。 + +--- + +## 閉包(Closure) + +現在,你已經準備好要建立 dragElement 閉包,建立包在外部函式內的內部函式組,在我們的例子中,會用上三個函式。 + +閉包在一或多個以上函式要存取外部函式時非常好用。看看下面的例子: + +```javascript +function displayCandy(){ + let candy = ['jellybeans']; + function addCandy(candyType) { + candy.push(candyType) + } + addCandy('gumdrops'); +} +displayCandy(); +console.log(candy) +``` + +這項例子中,函式 displayCandy 包住另一個函式 addCandy,新增新的糖果樣式到已存在的矩陣當中。當執行這段程式時,矩陣 `candy` 會被認作是未定義,因為它是函式的本地變數。 + +✅ 你能讓矩陣 `candy` 被存取嗎?試著將它移到閉包外面。這時,矩陣會變成全域變數,取消閉包內的存取限制。 + +### 課題 + +在檔案 `script.js` 的元素宣告下方,新增函式: + +```javascript +function dragElement(terrariumElement) { + //set 4 positions for positioning on the screen + let pos1 = 0, + pos2 = 0, + pos3 = 0, + pos4 = 0; + terrariumElement.onpointerdown = pointerDrag; +} +``` + +`dragElement` 藉由程式定義的參數取得 `terrariumElement` 物件。之後,設定一些位置 `0` 的變數給函式內的物件使用。它們是本地變數,給每一個進到拖曳函式內的物件操控。盆栽盒會被這些拖曳物件填充,我們的網頁應用必須要持續追蹤這些物件的位置。 + +此外,進到函式的 terrariumElement 也被新增了 `pointerdown` 事件,它是管理 DOM 的其中一項[網頁 APIs](https://developer.mozilla.org/en-US/docs/Web/API)。當按鈕按下時,或是在我們案例中,一個拖曳物件被點擊時,`onpointerdown` 事件就會被觸發。這個事件處理器(event handler)皆運作在[網頁與行動瀏覽器](https://caniuse.com/?search=onpointerdown)上,只有少部分的例外。 + +✅ [事件處理器 `onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick)支援更多的瀏覽器。為什麼我們不在這邊使用它? 想想看我們在這此建立的視窗互動類型。 + +--- + +## 函式 pointerDrag + +terrariumElement 已經準備好被拖曳了。當觸發 `onpointerdown` 事件時,函式 pointerDrag 會參與其中。新增這項函式在程式碼 `terrariumElement.onpointerdown = pointerDrag;` 下方: + +### 課題 + +```javascript +function pointerDrag(e) { + e.preventDefault(); + console.log(e); + pos3 = e.clientX; + pos4 = e.clientY; +} +``` + +許多事情會發生。首先,你使用 `e.preventDefault();` 取消掉 pointerdown 原先的預設事件。這樣你可以操作更多的介面行為。 + +> 回到你建立的程式碼中,試著刪除 `e.preventDefault()` 並執行看看,發生了什麼事? + +第二,用瀏覽器打開 `index.html` 並調查我們的介面。當你點擊植物時,你可以發現 'e' 事件被觸發了。專研一下,一個 pointerdown 事件會產生多少資訊! + +接下來,紀錄本地變數 `pos3` 和 `pos4` 被設定為 e.clientX 和 e.clientY。你可以在觀察面板中,會發現 `e` 的數值。這項數值取得按下植物瞬間的 x 與 y 座標資訊。為了全面的控制植物行為,在拖曳植物時,我們會持續更新座標資訊。 + +✅ 將整個網頁應用建立在一個大閉包下,會讓程式碼變得比較清楚嗎?如果沒有,你有其他方法管理這十四株可拖曳的植物嗎? + +增加初始化函式,在程式碼 `pos4 = e.clientY` 下方加上下列兩行事件處理: + +```html +document.onpointermove = elementDrag; +document.onpointerup = stopElementDrag; +``` + +現在,在游標拖曳時,你的植物能跟著你的游標走,而在你取消點擊時停下來。`onpointermove` 和 `onpointerup` 也是 `onpointerdown` 類型相同的 API。然而,現在介面會出現錯誤訊息,因為我們還沒建立函式 `elementDrag` 與 `stopElementDrag`。 + +## 函式 elementDrag 與 stopElementDrag + +新增兩條內部函式在閉包中,它們會處理拖曳植物與停止拖曳的事件。你希望你可以拖曳任何一株植物且放在螢幕上的任一地方。介面並沒有強制你盆栽盒的配置格式,你可以自由地增加、移除與移動盆栽罐內的植物。 + +### 課題 + +新增函式 `elementDrag` 在函式閉包 `pointerDrag` 宣告列的正下方: + +```javascript +function elementDrag(e) { + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + console.log(pos1, pos2, pos3, pos4); + terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px'; + terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px'; +} +``` + +在這條函式之前,你編輯了四個本地變數位置的初始值在外部函式中。這邊又做了什麼事? + +當你拖曳物件時,你更新數值 `pos1` 為 `pos3` 減去現在的 `e.clientX`,而 `pos3` 在之前被初始化為為 `e.clientX`。同樣的行為套用在 `pos2`上。之後,你更新 `pos3` 與 `pos4` 到新的 XY 座標點位置。你能在 console 下看到數值在拖曳下更新的情況。我們也更新植物的 CSS 造型中的定位點為 `pos1` 與 `pos2`,比較植物左上方座標點與新座標點的關係。 + +> `offsetTop` 和 `offsetLeft` 是 CSS 的屬性,決定物件與它父關係物件的定位關係。父關係物件可以是任何元素,只要它的定位屬性不為 `static`。 + +這些座標點的計算式讓你成功校整了植物與盆栽盒之間的行為。 + +### 課題 + +最後的課題是在介面上新增 `stopElementDrag` 函式,我們將它加在函式閉包 `elementDrag` 的正下方: + +```javascript +function stopElementDrag() { + document.onpointerup = null; + document.onpointermove = null; +} +``` + +這條小函式重制 `onpointerup` 與 `onpointermove` 事件,這樣你可以重新開始該植物的拖曳事件,或是拖曳新的植物。 + +✅ 如果不將這些事件設為空值時,會發生什麼事? + +我們終於完成了這項專案! + +🥇 恭喜你!你建立了一個漂亮的盆栽盒。 + +--- + +## 🚀 挑戰 + +新增新的事件處理器到你的閉包中,讓你能對植物做更多的事情。舉例來說,雙擊植物讓它排列到最上層。發揮你的創意吧! + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/20?loc=zh_tw) + +## 複習與自學 + +在螢幕上拖曳物件看似簡單,但依照不同的目的與實現方法會遭遇到不同的問題。事實上,這邊有一份關於你可以嘗試的[拖曳 API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)。我們沒在專案中使用是為了建立不一樣的實現方法,試著使用這些 API 到專案中,看看你能完成什麼。 + +在[W3C 文件](https://www.w3.org/TR/pointerevents1/) 和 [MDN 網頁文件](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events)上取得更多關於 pointer 的事件。 + +記得習慣性用[CanIUse.com](https://caniuse.com/)檢查網頁的瀏覽器兼容性。 + +## 作業 + +[用 DOM 做更多事](assignment.zh-tw.md) + diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.es.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.es.md index 8ba7506b..22c214bd 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.es.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.es.md @@ -2,7 +2,7 @@ ## Instrucciones -Investigue el DOM un poco más 'adoptando' un elemento DOM. Visite la [lista de interfaces DOM de MSDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) y elija una. Encuéntrelo en un sitio web en la web y escriba una explicación de cómo se usa. +Investigue el DOM un poco más 'adoptando' un elemento DOM. Visite la [lista de interfaces DOM de MSDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) y elija una. Encuéntrelo en un sitio web en la web y escriba una explicación de cómo se usa. ## Rúbrica diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.hi.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.hi.md index 66234dc5..d9d5efb2 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.hi.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.hi.md @@ -2,7 +2,7 @@ ## अनुदेश -DOM तत्व को 'अपनाकर' DOM को थोड़ा और रिसर्च करें. MSDN की [डॉम इंटरफेसेस सुचि](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) पे जाये और एक चयन करे . इसे वेब में एक वेब साइट पर उपयोग किया जा रहा है, और यह कैसे उपयोग किया जाता है एक व्याख्या लिखें। +DOM तत्व को 'अपनाकर' DOM को थोड़ा और रिसर्च करें. MSDN की [डॉम इंटरफेसेस सुचि](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) पे जाये और एक चयन करे . इसे वेब में एक वेब साइट पर उपयोग किया जा रहा है, और यह कैसे उपयोग किया जाता है एक व्याख्या लिखें। ## शीर्ष diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ko.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ko.md index 181b3310..fe1208b5 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ko.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ko.md @@ -2,7 +2,7 @@ ## 설명 -DOM 요소를 '채택'하여 DOM을 조금 더 조사합니다. MSDN의 [DOM 인터페이스 목록](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)을 방문하여 하나를 선택합니다. 웹의 웹 사이트에서 사용중인 것을 찾아 사용 방법에 대한 설명을 작성해봅니다. +DOM 요소를 '채택'하여 DOM을 조금 더 조사합니다. MSDN의 [DOM 인터페이스 목록](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)을 방문하여 하나를 선택합니다. 웹의 웹 사이트에서 사용중인 것을 찾아 사용 방법에 대한 설명을 작성해봅니다. ## 평가 기준 diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ms.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ms.md index 2a7726ca..21c0edff 100644 --- a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ms.md +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.ms.md @@ -2,7 +2,7 @@ ## Arahan -Mengkaji DOM sedikit dengan 'menerapkan' elemen DOM. Lawati laman MSDN [senarai antara muka DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) dan pilih satu. Cari ia digunakan di laman web di web, dan tulis penjelasan bagaimana ia digunakan. +Mengkaji DOM sedikit dengan 'menerapkan' elemen DOM. Lawati laman MSDN [senarai antara muka DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) dan pilih satu. Cari ia digunakan di laman web di web, dan tulis penjelasan bagaimana ia digunakan. ## Rubrik diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.nl.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.nl.md new file mode 100644 index 00000000..12bffbf3 --- /dev/null +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Werk wat meer met de DOM + +## Instructies + +Onderzoek de DOM een beetje meer door een DOM-element te 'adopteren'. Bezoek de [lijst met DOM-interfaces](https://developer.mozilla.org/nl/docs/Web/API/Document_Object_Model) van MSN en kies er een. Zoek dat het wordt gebruikt op een website op internet en schrijf een uitleg over hoe het wordt gebruikt. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- | +| | Er wordt een alinea-opsomming gegeven, met een voorbeeld | Paragraafopmaak wordt gepresenteerd, zonder voorbeeld | Er wordt geen beschrijving gepresenteerd | diff --git a/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.zh-tw.md b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.zh-tw.md new file mode 100644 index 00000000..fe7049d8 --- /dev/null +++ b/3-terrarium/3-intro-to-DOM-and-closures/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 用 DOM 做更多事 + +## 簡介 + +調查其中一項 DOM 的元素。造訪 MSN 關於[DOM 介面的清單](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)挑選其中一項。在網路上找尋一個使用這項元素的網頁,並解釋如何使用它。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------------- | ---------------- | ---------------- | +| | 完整的評論文章附帶例子 | 評論文章不帶例子 | 評論文章並不完整 | diff --git a/3-terrarium/translations/README.es.md b/3-terrarium/translations/README.es.md index 5d922ac4..779d6d61 100644 --- a/3-terrarium/translations/README.es.md +++ b/3-terrarium/translations/README.es.md @@ -20,7 +20,7 @@ La obra de arte fue dibujada a mano por [Jen Looper](http://jenlooper.com) usand La solución para elementos arrastrables se inspiró en la solución de w3schools para crear un [Elemento HTML arrastrable](https://www.w3schools.com/howto/howto_js_draggable.asp). -Encuentre más información sobre eventos de punteros en los [documentos del W3C](https://www.w3.org/TR/pointerevents1/) y en los [documentos web de MDN](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events). +Encuentre más información sobre eventos de punteros en los [documentos del W3C](https://www.w3.org/TR/pointerevents1/) y en los [documentos web de MDN](https://developer.mozilla.org/docs/Web/API/Pointer_events). Siempre verifique las capacidades del navegador usando [CanIUse.com](https://caniuse.com/). diff --git a/3-terrarium/translations/README.nl.md b/3-terrarium/translations/README.nl.md new file mode 100644 index 00000000..5ca0c198 --- /dev/null +++ b/3-terrarium/translations/README.nl.md @@ -0,0 +1,34 @@ +# Mijn Terrarium: een project om te leren over HTML-, CSS- en DOM-manipulatie met JavaScript 🌵🌱 + +Een kleine codemeditatie met drag and drop. Met een beetje HTML, JS en CSS kunt u een webinterface bouwen, deze opmaken en een interactie toevoegen. + + + +# Lessen + +1. [Inleiding tot HTML](../1-intro-to-html/translations/README.nl.md) +2. [Inleiding tot CSS](../2-intro-to-css/translations/README.nl.md) +3. [Inleiding tot DOM en JS Sluitingen](../3-intro-to-DOM-and-closures/translations/README.nl.md) + +## Credits + +Geschreven met ♥ ️door [Jen Looper](https://www.twitter.com/jenlooper) + +Het terrarium gemaakt via CSS is geïnspireerd op de glazen pot van Jakub Mandra [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY). + +Het artwork is met de hand getekend door [Jen Looper](http://jenlooper.com) met Procreate. + +## Zet uw terrarium in + +U kunt uw terrarium op internet zetten of publiceren met Azure Static Web Apps. + +1. Fork deze repo + +2. druk op deze knop + +[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-13441-cxa#create/Microsoft.StaticApp) + +3. Loop door de wizard om uw app te maken. Zorg ervoor dat u de app-root instelt op `/solution` of de root van uw codebase. Er zit geen API in deze app, dus maakt u geen zorgen om die toe te voegen. Er wordt een .github-map gemaakt in uw geforkte repo die Azure Static Web Apps helpt bij het bouwen van services en het publiceren van uw app naar een nieuwe URL. + + + diff --git a/3-terrarium/translations/README.zh-tw.md b/3-terrarium/translations/README.zh-tw.md new file mode 100644 index 00000000..ab650959 --- /dev/null +++ b/3-terrarium/translations/README.zh-tw.md @@ -0,0 +1,34 @@ +# 我的盆栽盒:一個關於 HTML、CSS 與 JavaScript DOM 控制的專案 🌵🌱 + +深思一項小型互動式拖放程式專案,在 HTML、JS 與 CSS 的帶領下,你可以建立網頁介面,美化它,並增加互動功能。 + + + +# 課程 + +1. [HTML 簡介](../1-intro-to-html/translations/README.zh-tw.md) +2. [CSS 簡介](../2-intro-to-css/translations/README.zh-tw.md) +3. [DOM 簡介與閉包](../translations/3-intro-to-DOM-and-closures/README.zh-tw.md) + +## 參與人員 + +由 [Jen Looper](https://www.twitter.com/jenlooper) 用滿滿的 ♥️ 來編寫。 + +用 CSS 建立盆栽盒的發想來自於 Jakub Mandra 的玻璃罐 [CodePen](https://codepen.io/Rotarepmi/pen/rjpNZY)。 + +手繪插圖由 [Jen Looper](http://jenlooper.com) 使用 Procreate 繪製。 + +## 建置你的盆栽盒 + +你可以利用 Azure Static Web Apps 建置、發布你的盆栽盒到網路上。 + +1. 分叉這個數據庫 + +2. 按下下方按鈕 + +[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-13441-cxa#create/Microsoft.StaticApp) + +3. 遵循指示建立你的網頁應用。請確保你的程式根目錄為 `/solution` 或者是你自己的專案位置。這項專案並不包含任何 API,你不需要考慮額外匯入的問題。 .github 資料夾會建立在你的分叉數據庫中,它會幫助 Azure Static Web Apps 的組建服務並發布你的應用到新的網址。 + + + diff --git a/4-typing-game/translations/README.nl.md b/4-typing-game/translations/README.nl.md new file mode 100644 index 00000000..e45c22a3 --- /dev/null +++ b/4-typing-game/translations/README.nl.md @@ -0,0 +1,30 @@ +# Event-Driven Programming - Bouw een Typspel + +## Inleiding + +Typen is een van de meest onderschatte vaardigheden van de ontwikkelaar. De mogelijkheid om snel gedachten van uw hoofd naar uw editor over te brengen, zorgt ervoor dat creativiteit vrijelijk kan stromen. Een van de beste manieren om te leren is door een spel te spelen! + +> Dus laten we een typspel bouwen! + +Je gaat de JavaScript-, HTML- en CSS-vaardigheden gebruiken die u tot nu toe hebt opgebouwd om een typspel te maken. Het spel zal de speler een willekeurig citaat laten zien (we gebruiken [Sherlock Holmes](https://nl.wikipedia.org/wiki/Sherlock_Holmes) aanhalingstekens) en de tijd hoe lang het duurt voordat de speler het nauwkeurig intypt. U gaat de JavaScript-, HTML- en CSS-vaardigheden gebruiken die u tot nu toe hebt opgebouwd om een typspel te maken. + + + +## Vereisten + +In deze les wordt ervan uitgegaan dat u bekend bent met de volgende concepten: + +- Tekstinvoer en knopbedieningen maken +- CSS en het instellen van stijlen met behulp van class +- JavaScript-basisprincipes + - Een array maken + - Een willekeurig nummer maken + - De huidige tijd ophalen + +## Les + +[Een typspel maken met behulp van event driven programming](../typing-game/translations/README.it.md) + +## Credits + +Geschreven met ♥ ️door [Christopher Harrison](http://www.twitter.com/geektrainer) diff --git a/4-typing-game/translations/README.zh-tw.md b/4-typing-game/translations/README.zh-tw.md new file mode 100644 index 00000000..d7b62c81 --- /dev/null +++ b/4-typing-game/translations/README.zh-tw.md @@ -0,0 +1,30 @@ +# 事件驅動程式設計 ── 建立一款打字遊戲 + +## 大綱 + +打字可說是開發者被嚴重低估的技能之一,將腦中的想法快速地轉換到編輯器中,讓你流暢地發揮你的想像力。其中一個訓練方法就是遊玩遊戲! + +> 因此,讓我們來開發一款打字遊戲吧! + +你會使用到你學到的 JavaScript、HTML 與 CSS 技法來建立打字遊戲。這款遊戲提供隨機的引文作為玩家的目標(使用[夏洛克·福爾摩斯](https://zh.wikipedia.org/wiki/%E6%AD%87%E6%B4%9B%E5%85%8B%C2%B7%E7%A6%8F%E5%B0%94%E6%91%A9%E6%96%AF)的引文),計算玩家準確輸入所需要花費的時間。 + + + +## 開始之前 + +這堂課會假設你已經熟悉下列的概念: + +- 建立文字輸入及按鈕控制 +- CSS 與 class 的造型設定 +- JavaScript 基礎觀念 + - 建立矩陣 + - 建立隨機數 + - 取得目前時間 + +## 課程 + +[使用事件驅動程式設計,建立一款打字遊戲](../typing-game/translations/README.zh-tw.md) + +## 參與人員 + +由 [Christopher Harrison](http://www.twitter.com/geektrainer) 用滿滿的 ♥️ 來編寫。 diff --git a/4-typing-game/typing-game/README.md b/4-typing-game/typing-game/README.md index 71baadd4..156dab6c 100644 --- a/4-typing-game/typing-game/README.md +++ b/4-typing-game/typing-game/README.md @@ -20,10 +20,10 @@ To handle events (button clicking, typing, etc.), we register **event listeners* There are [dozens of events](https://developer.mozilla.org/docs/Web/Events) available for you to listen to when creating an application. Basically anything a user does on a page raises an event, which gives you a lot of power to ensure they get the experience you desire. Fortunately, you'll normally only need a small handful of events. Here's a few common ones (including the two we'll use when creating our game): -- [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): The user clicked on something, typically a button or hyperlink -- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): The user clicked the right mouse button -- [select](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): The user highlighted some text -- [input](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): The user input some text +- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): The user clicked on something, typically a button or hyperlink +- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): The user clicked the right mouse button +- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): The user highlighted some text +- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): The user input some text ## Creating the game @@ -332,7 +332,7 @@ Add more functionality ## Review & Self Study -Read up on [all the events available](https://developer.mozilla.org/en-US/docs/Web/Events) to the developer via the web browser, and consider the scenarios in which you would use each one. +Read up on [all the events available](https://developer.mozilla.org/docs/Web/Events) to the developer via the web browser, and consider the scenarios in which you would use each one. ## Assignment diff --git a/4-typing-game/typing-game/translations/README.it.md b/4-typing-game/typing-game/translations/README.it.md index 7c67117c..2884061b 100644 --- a/4-typing-game/typing-game/translations/README.it.md +++ b/4-typing-game/typing-game/translations/README.it.md @@ -20,10 +20,10 @@ Per gestire gli eventi (clic sul pulsante, digitazione, ecc.), si registrano gli Ci sono [dozzine di eventi](https://developer.mozilla.org/docs/Web/Events) disponibili da ascoltare quando si crea un'applicazione. Fondamentalmente qualsiasi cosa un utente fa su una pagina genera un evento, il che dà molto potere allo sviluppatore per assicurarsi che egli ottenga l'esperienza che desidera. Fortunatamente, in genere si avrà solo bisogno di una piccola manciata di eventi. Eccone alcuni comuni (inclusi i due che verranno usati durante la creazione del gioco): -- [clic](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): l'utente ha fatto clic su qualcosa, in genere un pulsante o un collegamento ipertestuale -- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): l'utente ha fatto clic con il pulsante destro del mouse -- [select](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): l'utente ha evidenziato del testo -- [input](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): l'utente ha inserito del testo +- [clic](https://developer.mozilla.org/docs/Web/API/Element/click_event): l'utente ha fatto clic su qualcosa, in genere un pulsante o un collegamento ipertestuale +- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): l'utente ha fatto clic con il pulsante destro del mouse +- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): l'utente ha evidenziato del testo +- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): l'utente ha inserito del testo ## Creare il gioco @@ -332,7 +332,7 @@ Aggiungere più funzionalità ## Revisione e Auto Apprendimento -Informarsi su [tutti gli eventi disponibili](https://developer.mozilla.org/en-US/docs/Web/Events) per lo sviluppatore tramite il browser web e considerare gli scenari nei quali si userebbe ciascuno di essi. +Informarsi su [tutti gli eventi disponibili](https://developer.mozilla.org/docs/Web/Events) per lo sviluppatore tramite il browser web e considerare gli scenari nei quali si userebbe ciascuno di essi. ## Compito diff --git a/4-typing-game/typing-game/translations/README.ja.md b/4-typing-game/typing-game/translations/README.ja.md index 24b352e8..11143e76 100644 --- a/4-typing-game/typing-game/translations/README.ja.md +++ b/4-typing-game/typing-game/translations/README.ja.md @@ -21,7 +21,7 @@ アプリケーションを作成するときに聞くことができる[多数のイベント](https://developer.mozilla.org/ja/docs/Web/Events)があります。基本的に、ユーザーがページ上で何かをするとイベントが発生しますが、これはプレイヤーがあなたの意図した経験を得られるようにするうえで大きな力となります。幸いなことに、通常はほんの一握りのイベントしか必要ありません。ここでは、(ゲームを作成する際に使用する 2 つのイベントを含む) いくつかの一般的なイベントを紹介します: - [click](https://developer.mozilla.org/ja/docs/Web/API/Element/click_event): ユーザーが何かをクリックした場合、通常はボタンやハイパーリンクをクリックします -- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): ユーザーがマウスの右ボタンをクリックした場合 +- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): ユーザーがマウスの右ボタンをクリックした場合 - [select](https://developer.mozilla.org/ja/docs/Web/API/Element/select_event): ユーザーがテキストをハイライトした場合 - [input](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/input_event): ユーザーが何かテキストを入力した場合 diff --git a/4-typing-game/typing-game/translations/README.ko.md b/4-typing-game/typing-game/translations/README.ko.md index af6a3e5b..def36057 100644 --- a/4-typing-game/typing-game/translations/README.ko.md +++ b/4-typing-game/typing-game/translations/README.ko.md @@ -20,10 +20,10 @@ 응용 프로그램을 만들 때 수신할 수 있는 [dozens of events](https://developer.mozilla.org/docs/Web/Events)가 있습니다. 기본적으로 사용자가 페이지에서 수행하는 모든 작업은 이벤트를 발생시키므로, 원하는 경험으로 많은 도움을 줍니다. 다행스럽게, 일반적인 이벤트만 필요합니다. 다음은 일반적 몇가지입니다 (게임을 만들 때 사용할 두 가지를 포함합니다): -- [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): 사용자가 버튼 또는 하이퍼링크와 같은 무언가를 클릭했습니다 -- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): 사용자가 우측 마우스 버튼을 클릭했습니다 -- [select](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): 사용자가 어떤 텍스트를 강조했습니다 -- [input](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): 사용자가 어떤 텍스트를 입력했습니다 +- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): 사용자가 버튼 또는 하이퍼링크와 같은 무언가를 클릭했습니다 +- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): 사용자가 우측 마우스 버튼을 클릭했습니다 +- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): 사용자가 어떤 텍스트를 강조했습니다 +- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): 사용자가 어떤 텍스트를 입력했습니다 ## 게임 만들기 @@ -331,7 +331,7 @@ typedValueElement.addEventListener('input', () => { ## 리뷰 & 자기주도 학습 -웹 브라우저를 통해 [all the events available]((https://developer.mozilla.org/en-US/docs/Web/Events)) to the developer를 읽고, 각 이벤트를 사용할 시나리오를 고려합니다. +웹 브라우저를 통해 [all the events available]((https://developer.mozilla.org/docs/Web/Events)) to the developer를 읽고, 각 이벤트를 사용할 시나리오를 고려합니다. ## 과제 diff --git a/4-typing-game/typing-game/translations/README.ms.md b/4-typing-game/typing-game/translations/README.ms.md index 9fa3a691..86a47133 100644 --- a/4-typing-game/typing-game/translations/README.ms.md +++ b/4-typing-game/typing-game/translations/README.ms.md @@ -20,10 +20,10 @@ Untuk menangani acara (klik butang, menaip, dll.), Kami mendaftarkan **pendengar Terdapat [puluhan acara](https://developer.mozilla.org/docs/Web/Events) yang tersedia untuk anda dengarkan semasa membuat aplikasi. Pada asasnya apa sahaja yang dilakukan pengguna pada halaman menimbulkan peristiwa, yang memberi anda banyak kekuatan untuk memastikan mereka mendapat pengalaman yang anda inginkan. Nasib baik, anda biasanya hanya memerlukan sebilangan kecil acara. Berikut adalah beberapa perkara biasa (termasuk dua yang akan kami gunakan semasa membuat permainan kami): -- [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): Pengguna mengklik sesuatu, biasanya butang atau hyperlink -- [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): Pengguna mengklik butang tetikus kanan -- [select](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): Pengguna menyoroti beberapa teks -- [input](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): Pengguna memasukkan beberapa teks +- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): Pengguna mengklik sesuatu, biasanya butang atau hyperlink +- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): Pengguna mengklik butang tetikus kanan +- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): Pengguna menyoroti beberapa teks +- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): Pengguna memasukkan beberapa teks ## Membuat permainan @@ -332,7 +332,7 @@ Tambahkan lebih banyak fungsi ## Mengkaji & Belajar Sendiri -Bacalah [semua acara yang ada](https://developer.mozilla.org/en-US/docs/Web/Events) kepada pembangun melalui penyemak imbas web, dan pertimbangkan senario di mana anda akan menggunakannya. +Bacalah [semua acara yang ada](https://developer.mozilla.org/docs/Web/Events) kepada pembangun melalui penyemak imbas web, dan pertimbangkan senario di mana anda akan menggunakannya. ## Tugasan diff --git a/4-typing-game/typing-game/translations/README.zh-tw.md b/4-typing-game/typing-game/translations/README.zh-tw.md new file mode 100644 index 00000000..cdf588f6 --- /dev/null +++ b/4-typing-game/typing-game/translations/README.zh-tw.md @@ -0,0 +1,339 @@ +# 使用事件建立遊戲 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/21?loc=zh_tw) + +## 事件驅動程式設計 + +當我們建立專為瀏覽器設計的應用程式時,我們會提供 Graphical User Interface (GUI) 給用戶使用,在我們建立的格式上進行互動。最常見的互動方式是透過點擊或輸入在多樣的物件。開發者面臨的問題是,我們不了解用戶會何時對這些物件產生互動! + +[事件驅動程式設計](https://zh.wikipedia.org/zh-tw/%E4%BA%8B%E4%BB%B6%E9%A9%85%E5%8B%95%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88)是一種程式設計的方式,以建立我們的 GUI。若拆解該名詞的話,我們知道主軸關鍵會是**事件(Event)**。根據 Merriam-Webster,[事件](https://www.merriam-webster.com/dictionary/event)according定義為「將發生的事」。它能有效地解決我們面臨的問題。我們知道當用戶產生互動時,什麼程式必須回應其要求,只差在我們不知道用戶會何時產生互動。 + +藉由建立新的函式,我們可以標記這段將被運行的程式碼。我們回顧一下[程序式程式設計](https://zh.wikipedia.org/wiki/%E8%BF%87%E7%A8%8B%E5%BC%8F%E7%BC%96%E7%A8%8B),函式會依照順序一行一行的被運行。這同樣也會被實踐在事件驅動程式設計上,差別在於**如何**去呼叫這些函式。 + +要處理這些事件:點擊按鈕、輸入字串等等,我們需註冊**事件監聽者(Event Listeners)**。事件監聽者是函式之一,負責回應當事件觸發時,提供相對應的回應。事件監聽者可以根據用戶的行為,更新使用者介面,呼叫伺服器,或是任何你想要它做的事。我們利用[addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)新增事件監聽者,提供要被運行的函式。 + +> **注意** 值得注意我們有許多建立事件監聽者的方式。你可以使用匿名函式(anonymous functions),或是有名字的;你可以使用多種的快捷,好比直接設定 `click` 屬性,或使用 `addEventListener`。在我們練習過程中,主要專注在 `addEventLister` 與匿名函式上,它們可能是開發者最常見的網頁開發技巧。同時,也是彈性最高的: `addEventListener` 作用在任何事件,任何以參數方式輸入的事件名稱。 + +### 常見事件 + +創造應用時,這邊有[數種事件](https://developer.mozilla.org/docs/Web/Events)提供給你監聽。基本上,使用者在網頁上做的任何行為都會觸發事件,你需要花大量時間、大量精力確保它們有相對應的使用者體驗。幸運的是,你只需要處理少部分的事件類型。這邊是一些常見的事件類型,我們會使用其中兩種來建立遊戲: + +- [點擊](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event): 使用者點擊物件,通常會是按鈕或是連結。 +- [右鍵選單](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event): 使用者點擊滑鼠右鍵。 +- [選取](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event): 使用者標記特定文字。 +- [輸入](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event): 使用者輸入文字。 + +## 建立遊戲 + +現在我們藉由建立遊戲,了解事件是如何在 JavaScript 上運作的。我們的遊戲會測試玩家的打字技巧,一項程式開發員被忽略的技能之一。我們應該時刻練習打字技術!大致的遊戲流程如下: + +- 玩家點擊「開始」按鈕並產生一行要被輸入的引文 +- 玩家盡快地輸入這段文字到文字框中 + - 當單字輸入完畢時,立即標記下一個單字。 + - 當玩家打錯字時,將文字框轉為紅色。 + - 當玩家完成引文輸入時,顯示祝賀語與花費的時間。 + +讓我們開始建立遊戲,學習事件驅動吧! + +### 檔案結構 + +我們總共需要三個檔案:**index.html**、**script.js**與**style.css**。我們來設定它們,以完成後續的步驟。 + +- 建立新的資料夾存放我們的遊戲,開啟 Console 或是終端機,輸入下列指令: + +```bash +# Linux 或 macOS +mkdir typing-game && cd typing-game + +# Windows +md typing-game && cd typing-game +``` + +- 打開文字編輯器 Visual Studio Code + +```bash +code . +``` + +- 現在,在 Visual Studio Code 中新增三個檔案到資料夾中,分別為: + - index.html + - script.js + - style.css + +## 建立使用者介面 + +藉由回顧我們的需求,我們在 HTML 頁面上新增一些元素。這就像是看一份食譜,你需要對應的食材: + +- 一個地方呈現將被輸入的引文 +- 一個地方呈現任何訊息,好比祝賀文 +- 一個玩家輸入的文字框 +- 一個開始按鈕。 + +每一個物件都需要 ID ,讓 JavaScript 程式能控制它們。另外,在 HTML 檔案匯入 CSS 與 JavaScript 檔,我們等一下會編輯它們。 + +在新的 **index.html** 檔案中,加入下列程式碼: + +```html +<!-- inside index.html --> +<html> +<head> + <title>Typing game</title> + <link rel="stylesheet" href="style.css"> +</head> +<body> + <h1>Typing game!</h1> + <p>Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!</p> + <p id="quote"></p> <!-- This will display our quote --> + <p id="message"></p> <!-- This will display any status messages --> + <div> + <input type="text" aria-label="current word" id="typed-value" /> <!-- The textbox for typing --> + <button type="button" id="start">Start</button> <!-- To start the game --> + </div> + <script src="script.js"></script> +</body> +</html> +``` + +### 執行應用程式 + +最好的逐段開發模式是定期的確認程式結果。讓我們來執行現在的應用程式。Visual Studio Code 上有一個好用的擴充套件為[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer),它會在你儲存網頁檔案時,同時架設並更新瀏覽器上的網頁。 + +- 安裝[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer),點擊連結中的 **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 會架設並發布你的網頁成果 +- 開啟瀏覽器,前往 **https://localhost:5500** +- 現在你能看到你所做的網頁! + +讓我們來為網頁增加更多功能。 + +## 加入 CSS + +建立完 HTML 檔,現在我們為了造型加入 CSS。我們需要標記玩家需要輸入的單字,若單字輸入錯誤時需要改變文字框的顏色。利用兩組 class 來完成: + +在檔案 **style.css** 加入下列語法: + +```css +/* 在 style.css 中 */ +.highlight { + background-color: yellow; +} + +.error { + background-color: lightcoral; + border: red; +} +``` + +✅ 處理 CSS 時,你可以規劃任何你想要的介面布局。花點時間讓你的網頁更迷人: + +- 變更其他字型 +- 改變標題顏色 +- 改變物件大小 + +## JavaScript + +建立完使用者介面後,我們要專注在 JavaScript 上,提供網頁邏輯處理的能力。我們將工作分為下列步驟: + +- [建立常數](#建立常數) +- [事件監聽者 - 開始遊戲](#加入開始邏輯) +- [事件監聽者 - 輸入文字](#加入打字邏輯) + +首先,我們先編輯檔案 **script.js**。 + +### 建立常數 + +加入一些變數給程式使用。同樣地,就像食譜一樣,我們需要的食材如下: + +- 矩陣,儲存所有引文 +- 空矩陣,儲存單一引文的所有單字 +- 變數,儲存空矩陣的索引,標記玩家現在面對的單字 +- 變數,紀錄玩家點擊開始時的時間 + +我們也需要將使用者介面上的物件做連結: + +- 文字框 (**typed-value**) +- 顯示引文 (**quote**) +- 訊息欄 (**message**) + +```javascript +// 在檔案 script.js 中 +// 所有的引文內容 +const quotes = [ + 'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.', + 'There is nothing more deceptive than an obvious fact.', + 'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.', + 'I never make exceptions. An exception disproves the rule.', + 'What one man can invent another can discover.', + 'Nothing clears up a case so much as stating it to another person.', + 'Education never ends, Watson. It is a series of lessons, with the greatest for the last.', +]; +// 儲存單字列表及目前要輸入的單字索引 +let words = []; +let wordIndex = 0; +// 開始時間 +let startTime = Date.now(); +// 網頁物件連結 +const quoteElement = document.getElementById('quote'); +const messageElement = document.getElementById('message'); +const typedValueElement = document.getElementById('typed-value'); +``` + +✅ 試著加入更多的引文到你的遊戲中。 + +> **筆記** 我們可以接收任何物件,只要使用程式碼 `document.getElementById`。因為我們需要定期參考這些元素,所以使用常數來確認是否有單字輸入錯誤的問題。框架如[Vue.js](https://vuejs.org/)或[React](https://reactjs.org/)可以幫助你更好管理你的程式碼。 + +花點時間觀看下列關於 `const`、`let` 與 `var` 的影片。 + +[](https://youtube.com/watch?v=JNIXfGiDWM8 "變數類型") + +> 點擊上方圖片以觀賞關於變數的影片。 + +### 加入開始邏輯 + +為了開始我們的遊戲,玩家會點擊開始按鈕。當然,我們不知道何時玩家會開始遊戲,這就是為什麼我們使用[事件監聽者](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)到程式中。一個事件監聽者允許我們監看事件的觸發與對應的回應程式。在這個例子,我們希望當使用者點擊開始時,執行某些程式。 + +當玩家點擊 **start** 按鈕後,我們需要挑選一段引文、設定使用者介面並追蹤現在玩家的要輸入的單字與時間。下列為我們需要新增的程式碼,我們會在之後逐行解釋。 + +```javascript +// 在 script.js 末端 +document.getElementById('start').addEventListener('click', () => { + // 取得一行引文 + const quoteIndex = Math.floor(Math.random() * quotes.length); + const quote = quotes[quoteIndex]; + // 將引文分成許多單字,存在矩陣中。 + words = quote.split(' '); + // 重制單字索引來做追蹤 + wordIndex = 0; + + // 更新使用者介面 + // 建立 span 元素的矩陣,設定 class 用。 + const spanWords = words.map(function(word) { return `<span>${word} </span>`}); + // 轉換成字串並以 innerHTML 顯示引文 + quoteElement.innerHTML = spanWords.join(''); + // 標記第一個單字 + quoteElement.childNodes[0].className = 'highlight'; + // 清除訊息欄之前的訊息 + messageElement.innerText = ''; + + // 設定文字框 + // 清除文字框 + typedValueElement.value = ''; + // 設定 focus + typedValueElement.focus(); + // 設定事件驅動程式 + + // 開始計時器 + startTime = new Date().getTime(); +}); +``` + +我們來分解程式碼吧! + +- 設定單字追蹤 + - 使用[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` 組成的矩陣,追蹤目前玩家正在輸入的單字 + - `wordIndex` 設定為 0,玩家會從第一的單字開始輸入 +- 設定使用者介面 + - 建立矩陣 `spanWords`,將每一個單字包在 `span` 元素中 + - 這讓我們能高光標記單字 + - `join` 矩陣來建立字串,我們可以在 `quoteElement` 上更新 `innerHTML` + - 這會顯示引文給玩家檢視 + - 設定第一個 `span` 元素的 `className` 成 `highlight`,來標記單字呈黃色 + - 修改 `messageElement`的 `innerText` 成 `''`,這會清除訊息欄的內容 +- 設定文字框 + - 清除目前 `typedValueElement` 的 `value` + - 設定 `typedValueElement` 成 `focus` +- 呼叫 `getTime` 來啟始計時器 + +### 加入打字邏輯 + +當玩家開始打字時,`input` 事件會被觸發。對應的事件監聽者需要檢查玩家是否輸入正確的單字,監控目前的遊戲狀況。回到檔案 **script.js**,加入下方程式碼到檔案最下方。我們會在後續解釋程式碼。 + +```javascript +// script.js 最末端 +typedValueElement.addEventListener('input', () => { + // 取得目前的單字 + const currentWord = words[wordIndex]; + // 取得目前輸入的數值 + const typedValue = typedValueElement.value; + + if (typedValue === currentWord && wordIndex === words.length - 1) { + // 句子最末端 + // 顯示成功 + const elapsedTime = new Date().getTime() - startTime; + const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`; + messageElement.innerText = message; + } else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) { + // 單字最末端 + // 清除輸入的數值,準備給新的單字使用 + typedValueElement.value = ''; + // 移動到下一個單字 + wordIndex++; + // 重設所有引文子元素的 class 名稱 + for (const wordElement of quoteElement.childNodes) { + wordElement.className = ''; + } + // 標記新單字 + quoteElement.childNodes[wordIndex].className = 'highlight'; + } else if (currentWord.startsWith(typedValue)) { + // 單字目前輸入正確 + // 標記下一個單字 + typedValueElement.className = ''; + } else { + // 單字輸入錯誤 + typedValueElement.className = 'error'; + } +}); +``` + +讓我們分解程式碼吧!我們開始取得目前的單字與玩家輸入的數值。我們建立一系列的邏輯,檢查引文是否輸入完成,單字是否輸入完成,單字是否正確、是否錯誤。 + +- 引文完成,檢查 `typedValue` 與 `currentWord` 相等且 `wordIndex` 與 `words` 的 `length` 減一相等。 + - 計算 `elapsedTime` ,利用目前時間減去 `startTime` 取得遊戲時長 + - `elapsedTime` 除以 1,000 ,轉化毫秒單位為秒單位 + - 顯示成功訊息 +- 單字完成,以 `typedValue` 間的空白為界,檢查 `typedValue` 是否與 `currentWord` 相等 + - 設定 `typedElement` 的 `value` 成 `''` ,準備給下一個單字輸入進來 + - 增加 `wordIndex` 到下一個單字 + - 進迴圈,每一個 `quoteElement` 的 `childNodes` ,它們的 `className` 都被設為 `''` ,代表預設的單字呈現規則 + - 設定單字的 `className` 成 `highlight` 來標記為下一個被輸入的單字 +- 單字目前輸入正確但未完成,從 `typedValue` 開始檢查 `currentWord` + - 確保清除 `typedValueElement` 的 `className`,顯示預設的呈現方式。 +- 若此時輸入錯誤,我們加上錯誤規則 + - 設定 `typedValueElement` 的 `className` 成 `error` + +## 測試你的應用程式 + +我們做到最後了!最後一步就是確保我們的應用程式運作正常。試試看!不要擔心程式出現錯誤,**所有的開發者**都會面臨錯誤。有需要時,檢查程式訊息並偵錯。 + +點擊按鈕 **start**,馬上開始輸入單字!你可以看看這預覽動畫。 + + + +--- + +## 🚀 挑戰 + +加入更多功能。 + +- 在完成遊戲時,關閉 `input` 事件監聽者;遊戲重新開始時,再重新開啟它。 +- 當玩家完成引文時,關閉文字框 +- 以對話窗格的方式顯示恭賀訊息 +- 利用[localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)儲存最高分的資料 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/22?loc=zh_tw) + +## 複習與自學 + +在瀏覽器上閱讀[所有開發者可運用的事件](https://developer.mozilla.org/en-US/docs/Web/Events),想想你能在什麼樣的場合使用各個事件。 + +## 作業 + +[建立一款新的鍵盤遊戲](assignment.zh-tw.md) diff --git a/4-typing-game/typing-game/translations/assignment.nl.md b/4-typing-game/typing-game/translations/assignment.nl.md new file mode 100644 index 00000000..551971f9 --- /dev/null +++ b/4-typing-game/typing-game/translations/assignment.nl.md @@ -0,0 +1,12 @@ +# Maak een nieuw toetsenbordspel + +## Instructies + +Maak een klein spel dat toetsenbordgebeurtenissen gebruikt om taken uit te voeren. Het kan een ander soort typespel zijn, of een kunstspel dat bij toetsaanslagen pixels op het scherm schildert. Wees creatief! + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------ | ------------------------ | ----------------- | +| | Er wordt een volledig spel gepresenteerd | De game is erg minimaal | De game bevat bugs | +| | \ No newline at end of file diff --git a/4-typing-game/typing-game/translations/assignment.zh-tw.md b/4-typing-game/typing-game/translations/assignment.zh-tw.md new file mode 100644 index 00000000..a85f9f8b --- /dev/null +++ b/4-typing-game/typing-game/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 建立一款新的鍵盤遊戲 + +## 簡介 + +建立一款使用鍵盤事件的小遊戲。它可以是不同的鍵盤輸入遊戲:使用鍵盤在視窗上繪製像素點的繪圖遊戲。激發你的創意吧! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ------------------ | ------------ | ------------ | +| | 呈現完整的遊戲內容 | 遊戲內容單調 | 遊戲出現問題 | diff --git a/5-browser-extension/1-about-browsers/README.md b/5-browser-extension/1-about-browsers/README.md index 57cbc05d..5ef5fc50 100644 --- a/5-browser-extension/1-about-browsers/README.md +++ b/5-browser-extension/1-about-browsers/README.md @@ -1,6 +1,6 @@ # Browser Extension Project Part 1: All about Browsers - + > Sketchnote by [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## Pre-Lecture Quiz @@ -69,7 +69,7 @@ CO2 Signal's API. - the [starter code](../start). Download the `start` folder; you will be completing code in this folder. - [NPM](https://www.npmjs.com) - NPM is a package management tool; install it locally and the packages listed in you `package.json` file will be installed for use by your web asset -✅ Learn more about package management in this [excellent Learn module](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa) +✅ Learn more about package management in this [excellent Learn module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa) Take a minute to look through the codebase: @@ -156,7 +156,7 @@ Take a look at a browser extension store and install one to your browser. You ca In this lesson you learned a little about the history of the web browser; take this opportunity to learn about how the inventors of the World Wide Web envisioned its use by reading more about its history. Some useful sites include: -[The History of Web Browsers](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) +[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/) [History of the Web](https://webfoundation.org/about/vision/history-of-the-web/) diff --git a/5-browser-extension/1-about-browsers/translations/README.es.md b/5-browser-extension/1-about-browsers/translations/README.es.md index 5296910c..76a46e4d 100644 --- a/5-browser-extension/1-about-browsers/translations/README.es.md +++ b/5-browser-extension/1-about-browsers/translations/README.es.md @@ -1,6 +1,6 @@ # Proyecto de extensión del navegador Parte 1: Todo sobre los navegadores - + > Sketchnote de [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## [Pre-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/23) @@ -68,7 +68,7 @@ API de CO2 Signal. - el [código de inicio](../inicio). Descargue la carpeta `start`; completará el código en esta carpeta. - [NPM](https://www.npmjs.com) - NPM es una herramienta de gestión de paquetes; instálelo localmente y los paquetes enumerados en su archivo `package.json` se instalarán para que los use su recurso web -✅ Obtenga más información sobre la administración de paquetes en este [excelente módulo de aprendizaje](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa) +✅ Obtenga más información sobre la administración de paquetes en este [excelente módulo de aprendizaje](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa) Tómate un minuto para revisar el código base: @@ -151,7 +151,7 @@ Felicitaciones, ha dado los primeros pasos para crear una extensión de navegado En esta lección aprendió un poco sobre la historia del navegador web; Aproveche esta oportunidad para aprender cómo los inventores de la World Wide Web imaginaron su uso leyendo más sobre su historia. Algunos sitios útiles incluyen: -[La historia de los navegadores web](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) +[La historia de los navegadores web](https://www.mozilla.org/firefox/browsers/browser-history/) [Historia de la Web](https://webfoundation.org/about/vision/history-of-the-web/) diff --git a/5-browser-extension/1-about-browsers/translations/README.it.md b/5-browser-extension/1-about-browsers/translations/README.it.md index bdff1237..1b45ecef 100644 --- a/5-browser-extension/1-about-browsers/translations/README.it.md +++ b/5-browser-extension/1-about-browsers/translations/README.it.md @@ -1,6 +1,6 @@ # Progetto di Estensione del Browser Parte 1: Tutto sui Browser - + > Sketchnote di [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## Quiz Pre-Lezione diff --git a/5-browser-extension/1-about-browsers/translations/README.ja.md b/5-browser-extension/1-about-browsers/translations/README.ja.md index a5fea876..2a7f2749 100644 --- a/5-browser-extension/1-about-browsers/translations/README.ja.md +++ b/5-browser-extension/1-about-browsers/translations/README.ja.md @@ -1,6 +1,6 @@ # ブラウザ拡張機能プロジェクト その 1: ブラウザのすべて - + > Sketchnote by [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## レッスン前の小テスト @@ -155,7 +155,7 @@ npm install このレッスンでは、Web ブラウザの歴史について少し学びました。この機会に、Web ブラウザの歴史を読むことで、World Wide Web の発明者がどのように Web ブラウザの使用を想定しているかを学びましょう。役に立つサイトをいくつか紹介します。 -[Web ブラウザの歴史](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) +[Web ブラウザの歴史](https://www.mozilla.org/firefox/browsers/browser-history/) [Web の歴史](https://webfoundation.org/about/vision/history-of-the-web/) diff --git a/5-browser-extension/1-about-browsers/translations/README.ko.md b/5-browser-extension/1-about-browsers/translations/README.ko.md index ebc49db1..062bc55f 100644 --- a/5-browser-extension/1-about-browsers/translations/README.ko.md +++ b/5-browser-extension/1-about-browsers/translations/README.ko.md @@ -1,6 +1,6 @@ # 브라우저 확장 프로젝트 파트 1: 브라우저에 대한 모든 것 - + > Sketchnote by [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## 강의 전 퀴즈 @@ -68,7 +68,7 @@ - [starter code](../start). `start` 폴더를 다운로드하세요; 이 폴더에서 코드를 완성하게됩니다. - [NPM](https://www.npmjs.com) - NPM은 패키지 관리 도구입니다. 로컬에 설치하고 `package.json` 파일에 나열된 패키지를 웹 어셋에서 사용하도록 설치합니다. -✅ 이 [excellent Learn module](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa)에서 패키지 관리에 대해 자세히 알아보세요 +✅ 이 [excellent Learn module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa)에서 패키지 관리에 대해 자세히 알아보세요 잠시 시간을 내어 코드베이스를 보세요: @@ -155,7 +155,7 @@ npm install 이 강의에서는 웹 브라우저의 역사에 대해 조금 배웠습니다; 이 기회에 역사를 더 많이 읽어보면서 World Wide Web의 탐험가들이 어떻게 사용했는지에 대해 알아보십시오. 유용한 사이트는 다음과 같습니다: -[The History of Web Browsers](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) +[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/) [History of the Web](https://webfoundation.org/about/vision/history-of-the-web/) diff --git a/5-browser-extension/1-about-browsers/translations/README.ms.md b/5-browser-extension/1-about-browsers/translations/README.ms.md index c58a4597..1e5f1e6b 100644 --- a/5-browser-extension/1-about-browsers/translations/README.ms.md +++ b/5-browser-extension/1-about-browsers/translations/README.ms.md @@ -1,6 +1,6 @@ # Projek Pelanjutan Penyemak Imbas Bahagian 1: Semua mengenai Penyemak Imbas - + > Sketchnote karya [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) ## Kuiz Pra Kuliah @@ -69,7 +69,7 @@ CO2 Signal's API. - [kod pemula](../start). Muat turun folder `start`; anda akan melengkapkan kod dalam folder ini. - [NPM](https://www.npmjs.com) - NPM adalah alat pengurusan pakej; memasangnya secara tempatan dan pakej yang disenaraikan dalam fail `package.json` anda akan dipasang untuk digunakan oleh aset web anda -✅ Ketahui lebih lanjut mengenai pengurusan pakej dalam [modul pembelajaran yang sangat baik](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/) +✅ Ketahui lebih lanjut mengenai pengurusan pakej dalam [modul pembelajaran yang sangat baik](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/) Luangkan masa sebentar untuk melihat pangkalan kode: @@ -156,7 +156,7 @@ Lihatlah kedai pelanjutan penyemak imbas dan pasang satu di penyemak imbas anda. Dalam pelajaran ini anda belajar sedikit mengenai sejarah penyemak imbas web; ambil kesempatan ini untuk mengetahui bagaimana pencipta World Wide Web membayangkan penggunaannya dengan membaca lebih banyak mengenai sejarahnya. Beberapa laman web yang berguna termasuk: -[Sejarah Penyemak Imbas Web](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) +[Sejarah Penyemak Imbas Web](https://www.mozilla.org/firefox/browsers/browser-history/) [Sejarah Tentang Web](https://webfoundation.org/about/vision/history-of-the-web/) diff --git a/5-browser-extension/1-about-browsers/translations/README.zh-tw.md b/5-browser-extension/1-about-browsers/translations/README.zh-tw.md new file mode 100644 index 00000000..507b579c --- /dev/null +++ b/5-browser-extension/1-about-browsers/translations/README.zh-tw.md @@ -0,0 +1,167 @@ +# 瀏覽器擴充功能專案 Part 1:關於瀏覽器 + + +> 由 [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob) 繪製 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/23?loc=zh_tw) + +### 大綱 + +瀏覽器擴充功能新增額外的功能給瀏覽器。在你建立之前,你應該學習瀏覽器是如何運作的。 + +### 關於瀏覽器 + +在這一系列的課程中,你會學習如何建立瀏覽器擴充功能,運作在 Chrome、Firefox 與 Edge 瀏覽器上。在這一章中,你會探索瀏覽器是如何運作,建立瀏覽器擴充功能的內容。 + +但到底何謂瀏覽器?它是幫助用戶顯示伺服器內容到網頁上的程式軟體。 + +✅ 小歷史:第一個網頁瀏覽器為 'WorldWideWeb',由 Timothy Berners-Lee 爵士於 1990 年建立。 + + +> 這邊有一些早期的瀏覽器,請參考[Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing) + +用戶使用網址 URL (Uniform Resource Locator) 位置連上網路,通常以 `http` 或 `https` 位置開頭使用超文本傳輸協定(Hypertext Transfer Protocol),瀏覽器便能與該伺服器溝通並抓取網頁的資料。 + +這時,瀏覽器轉譯引擎會呈現到用戶的裝置上,可以是手機、桌機或是筆記型電腦。 + +瀏覽器也有能力暫存內容,不需要每一次都向伺服器請求內容。瀏覽器儲存用戶的瀏覽紀錄、儲存 'cookies',一種包含用戶活動資訊的小型資料。 + +請記得一件重要的事,各家瀏覽器並不會相同!每一種瀏覽器都有各自的長處短處,專業的網頁開發人員必須了解如何讓網頁在不同瀏覽器上運作正常。這包含處理手機的小視窗,處理離線用戶的行為。 + +這邊有一個值得加到你書籤的實用網頁:[caniuse.com](https://www.caniuse.com)。當你在建構網頁時,你可以查詢 caniuse 技術支援清單,確保你能提供用戶最佳的使用體驗。 + +✅ 你知道你的網頁用戶最常使用什麼瀏覽器嗎?檢查你的分析程式,你可以安裝各種分析程式當作是你開發的一種環節,它們會告訴你那些瀏覽器最常被使用。 + +## 瀏覽器擴充功能 + +為什麼你需要建立瀏覽器擴充功能?它能附加在瀏覽器上,讓你快速地重複執行部分功能。舉例來說,如果你需要在網頁中檢查你所互動的顏色,你或許需要顏色選擇器擴充功能;如果你有記憶帳號密碼的困擾,你可能需要密碼管理擴充功能。 + +瀏覽器擴充功能在開發上也很有趣。它們有效地管理並執行少部分任務課題。 + +✅ 你最喜歡哪一項瀏覽器擴充功能?它們提供了什麼功能? + +### 安裝擴充功能 + +在你建立擴充功能以前,先看看建制與安裝瀏覽器擴充功能的流程。每一種瀏覽器在管理套件上可能有些不同,Edge上的管理過程就與 Chrome 與 Firefox 相似: + + + +大體而言,過程為: + +- 指令 `npm run build` 建制你的管理套件 +- 在瀏覽器中的延伸模組區點擊右上方的「更多設定」按鈕 +- 如果這是新的套件,選擇 `load unpacked` 從資料夾上傳新的擴充套件(在我們的例子中, `/dist` ) +- 如果這是已安裝的套件,點擊 `reload` 按鈕 + +✅ 上述教學步驟讓你導入自己建立的擴充功能;若要安裝已公開的套件,你可以前往瀏覽器擴充功能商店,逛逛這些[商店](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home)並安裝你選擇的套件。 + +### 展開行動 + +你打算寫一套擴充功能來顯示你國家的碳足跡,顯示國家的能源使用量與可用能源量。套件內會有 API Key 來存取網頁 CO2 Signal 的 API。 + +**你需要:** + +- [一組 API key](https://www.co2signal.com/):在網頁上輸入你的電子信箱,它會寄一組鑰匙給你 +- 給[Electricity Map](https://www.electricitymap.org/map)使用的[國家區域代碼](http://api.electricitymap.org/v3/zones) (舉個例子,在波士頓使用'US-NEISO') +- [程式碼](../../start),下載 `start` 資料夾,你需要修改裡面的程式碼檔案。 +- [NPM](https://www.npmjs.com),NPM 是一套軟體包管理工具,在本地安裝的軟體包會被列在 `package.json` 檔案中,成為網頁利用的資源。 + +✅ 從[這個優質的學習套件](https://docs.microsoft.com/en-us/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-13441-cxa)中,學習更多關於軟體包管理。 + +花點時間看一下程式檔案結構 + +dist + -|manifest.json (defaults set) + -|index.html (前端 HTML) + -|background.js (background JS) + -|main.js (built JS) +src + -|index.js (你的 JS 程式碼) + +✅ 當你取得你的 API Key 與國家區域代碼後,紀錄在筆記中給之後的課程使用。 + +### 建立給擴充功能使用的 HTML + +這套擴充功能有兩個重點。一個是取得 API Key 與國家區域代碼: + + + +與顯示國家的碳排放量: + + + +讓我們開始建立輸入欄位的 HTML 與它的 CSS 吧。 + +在資料夾 `/dist` 中,建立輸入表單與結果顯示區域。在檔案 `index.html` 中,規劃表單區域: + +```HTML +<form class="form-data" autocomplete="on"> + <div> + <h2>New? Add your Information</h2> + </div> + <div> + <label for="region">Region Name</label> + <input type="text" id="region" required class="region-name" /> + </div> + <div> + <label for="api">Your API Key from tmrow</label> + <input type="text" id="api" required class="api-key" /> + </div> + <button class="search-btn">Submit</button> +</form> +``` +這個表單儲存你的輸入資訊並儲存到 Local Storage 中。 + +接下來,建立結果輸出區。在 form tag 後面新增一些 divs: + +```HTML +<div class="result"> + <div class="loading">loading...</div> + <div class="errors"></div> + <div class="data"></div> + <div class="result-container"> + <p><strong>Region: </strong><span class="my-region"></span></p> + <p><strong>Carbon Usage: </strong><span class="carbon-usage"></span></p> + <p><strong>Fossil Fuel Percentage: </strong><span class="fossil-fuel"></span></p> + </div> + <button class="clear-btn">Change region</button> +</div> +``` +這時,你可以試著建制這個專案。請確保安裝擴充套建的軟體依賴套件,輸入: + +``` +npm install +``` + +這項指令會使用 NPM (Node Package Manager)安裝 webpack 給你的擴充套件建制過程中使用。Webpack 是一個處理程式編譯的工具組合包。你可以在 `/dist/main.js` 看到它的執行後的結果 ── 程式碼已經被打好包了。 + +到目前為止,擴充套件已經被建制,如果你導入此套件到 Edge 中也能完整地呈現出來。 + +恭喜你,你已經達成建立擴充套件的第一步驟。在接下來的課程中,你會新增更多功能,讓它更加的實用。 + +--- + +## 🚀 挑戰 + +逛逛瀏覽器擴充商店,安裝一套擴充功能到你的瀏覽器中。你可以查看它的檔案群。你發現了什麼? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/24?loc=zh_tw) + +## 複習與自學 + +這堂課中你學到了一些瀏覽器的歷史。趁這個機會閱讀更多它的歷史,學習網際網路的發明者是如何構思網路的應用。這邊有一些實用的網頁: + +[瀏覽器的歷史](https://www.mozilla.org/en-US/firefox/browsers/browser-history/) + +[網路的歷史](https://webfoundation.org/about/vision/history-of-the-web/) + +[與 Tim Berners-Lee 的訪談](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.zh-tw.md) + diff --git a/5-browser-extension/1-about-browsers/translations/assignment.nl.md b/5-browser-extension/1-about-browsers/translations/assignment.nl.md new file mode 100644 index 00000000..bccf428b --- /dev/null +++ b/5-browser-extension/1-about-browsers/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Restyle uw extensie + +## Instructies + +De codebase voor deze extensie wordt compleet geleverd met stijlen, maar u hoeft ze niet te gebruiken; maak uw extensie uw eigen door deze te restylen door het css-bestand te bewerken. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | -------------------------------------------- | --------------------- | ----------------- | +| | Code wordt ingediend met functionele nieuwe stijlen | Styling is niet compleet | Stijlen zijn buggy | \ No newline at end of file diff --git a/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md b/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md new file mode 100644 index 00000000..2b7dc4d9 --- /dev/null +++ b/5-browser-extension/1-about-browsers/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 重新造型你的套件 + +## 簡介 + +本課程的擴充套件已經包含了造型設定,但你不需要非得使用它們。改寫它的 CSS 檔來重新構築擴充插件的造型。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------- | -------------- | ------------ | +| | 新造型能正常地套用在程式中 | 造型規劃不完整 | 套件出現問題 | \ No newline at end of file diff --git a/5-browser-extension/2-forms-browsers-local-storage/README.md b/5-browser-extension/2-forms-browsers-local-storage/README.md index 90f041a4..9d15a3ea 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/README.md +++ b/5-browser-extension/2-forms-browsers-local-storage/README.md @@ -94,7 +94,7 @@ In this function, there is some interesting logic. Reading through it, can you s - hide the form - show the reset button -Before moving on, it's useful to learn about a very important concept available in browsers: [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). LocalStorage is a useful way to store strings in the browser as a `key-value` pair. This type of web storage can be manipulated by JavaScript to manage data in the browser. LocalStorage does not expire, while SessionStorage, another kind of web storage, is cleared when the browser is closed. The various types of storage have pros and cons to their usage. +Before moving on, it's useful to learn about a very important concept available in browsers: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage is a useful way to store strings in the browser as a `key-value` pair. This type of web storage can be manipulated by JavaScript to manage data in the browser. LocalStorage does not expire, while SessionStorage, another kind of web storage, is cleared when the browser is closed. The various types of storage have pros and cons to their usage. > Note - your browser extension has its own local storage; the main browser window is a different instance and behaves separately. @@ -145,7 +145,7 @@ Before going further, we should discuss APIs. APIs, or [Application Programming ✅ The term 'REST' stands for 'Representational State Transfer' and features using variously-configured URLs to fetch data. Do a little research on the various types of APIs available to developers. What format appeals to you? -There are important things to note about this function. First notice the [`async` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Writing your functions so that they run asynchronously means that they wait for an action, such as data being returned, to be completed before continuing. +There are important things to note about this function. First notice the [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Writing your functions so that they run asynchronously means that they wait for an action, such as data being returned, to be completed before continuing. Here's a quick video about `async`: @@ -200,7 +200,7 @@ This is a big function. What's going on here? - once the API responds, you assign various elements of its response data to the parts of your screen you set up to show this data. - if there's an error, or if there is no result, you show an error message. -✅ Using asyncronous programming patterns is another very useful tool in your toolbox. Read [about the various ways](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) you can configure this type of code. +✅ Using asyncronous programming patterns is another very useful tool in your toolbox. Read [about the various ways](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) you can configure this type of code. Congratulations! If you build your extension (`npm run build`) and refresh it in your extensions pane, you have a working extension! The only thing that isn't working is the icon, and you'll fix that in the next lesson. @@ -208,7 +208,7 @@ Congratulations! If you build your extension (`npm run build`) and refresh it in ## 🚀 Challenge -We've discussed several types of API so far in these lessons. Choose a web API and research in depth what it offers. For example, take a look at APIs available within browsers such as the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API). What makes a great API in your opinion? +We've discussed several types of API so far in these lessons. Choose a web API and research in depth what it offers. For example, take a look at APIs available within browsers such as the [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). What makes a great API in your opinion? ## Post-Lecture Quiz diff --git a/5-browser-extension/2-forms-browsers-local-storage/assignment.md b/5-browser-extension/2-forms-browsers-local-storage/assignment.md index e1d2e1b4..b7f68bc4 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/assignment.md +++ b/5-browser-extension/2-forms-browsers-local-storage/assignment.md @@ -2,7 +2,7 @@ ## Instructions -APIs can be very fun to play with. Here is a [list of many free ones](https://github.com/public-apis/public-apis). Pick and API, and build a browser extension that solves a problem. It can be as small a problem of not having enough pet pictures (so, try the [dog CEO API](https://dog.ceo/dog-api/)) or something bigger - have fun! +APIs can be very fun to play with. Here is a [list of many free ones](https://github.com/public-apis/public-apis). Pick an API, and build a browser extension that solves a problem. It can be as small a problem of not having enough pet pictures (so, try the [dog CEO API](https://dog.ceo/dog-api/)) or something bigger - have fun! ## Rubric diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.es.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.es.md index 55adbbff..160a96ac 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/translations/README.es.md +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.es.md @@ -93,7 +93,7 @@ En esta función, hay una lógica interesante. Al leerlo, ¿puedes ver lo que su - ocultar el formulario - mostrar el botón de reinicio -Antes de continuar, es útil conocer un concepto muy importante disponible en los navegadores: [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). LocalStorage es una forma útil de almacenar cadenas en el navegador como un par "clave-valor". Este tipo de almacenamiento web puede ser manipulado por JavaScript para administrar datos en el navegador. LocalStorage no caduca, mientras que SessionStorage, otro tipo de almacenamiento web, se borra cuando se cierra el navegador. Los distintos tipos de almacenamiento tienen ventajas y desventajas para su uso. +Antes de continuar, es útil conocer un concepto muy importante disponible en los navegadores: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage es una forma útil de almacenar cadenas en el navegador como un par "clave-valor". Este tipo de almacenamiento web puede ser manipulado por JavaScript para administrar datos en el navegador. LocalStorage no caduca, mientras que SessionStorage, otro tipo de almacenamiento web, se borra cuando se cierra el navegador. Los distintos tipos de almacenamiento tienen ventajas y desventajas para su uso. > Nota: la extensión de su navegador tiene su propio almacenamiento local; la ventana principal del navegador es una instancia diferente y se comporta por separado. @@ -193,13 +193,13 @@ Esta es una gran función. ¿Que está pasando aqui? - una vez que la API responde, asigna varios elementos de sus datos de respuesta a las partes de su pantalla que configura para mostrar estos datos. - si hay un error o si no hay ningún resultado, muestra un mensaje de error. -✅ El uso de patrones de programación asíncronos es otra herramienta muy útil en su caja de herramientas. Lea [acerca de las diversas formas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) puede configurar este tipo de código. +✅ El uso de patrones de programación asíncronos es otra herramienta muy útil en su caja de herramientas. Lea [acerca de las diversas formas](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) puede configurar este tipo de código. ¡Felicidades! Si construye su extensión (`npm run build`) y la actualiza en su panel de extensiones, ¡tiene una extensión que funciona! Lo único que no funciona es el ícono, y lo solucionará en la próxima lección. --- -🚀 Desafío: hemos discutido varios tipos de API hasta ahora en estas lecciones. Elija una API web e investigue en profundidad lo que ofrece. Por ejemplo, eche un vistazo a las API disponibles en los navegadores, como la [API HTML de arrastrar y soltar](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API). En tu opinión, ¿qué hace que una API sea excelente? +🚀 Desafío: hemos discutido varios tipos de API hasta ahora en estas lecciones. Elija una API web e investigue en profundidad lo que ofrece. Por ejemplo, eche un vistazo a las API disponibles en los navegadores, como la [API HTML de arrastrar y soltar](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). En tu opinión, ¿qué hace que una API sea excelente? ## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/26) diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.it.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.it.md index f2922d05..eab2226b 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/translations/README.it.md +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.it.md @@ -145,7 +145,7 @@ Prima di andare oltre, si dovrebbe parlare delle API. Le API, o [Application Pro ✅ Il termine "REST" sta per "Representational State Transfer" e prevede l'utilizzo di URL variamente configurati per recuperare dati. Fare una piccola ricerca sui vari tipi di API disponibili per gli sviluppatori. Quale formato piace? -Ci sono cose importanti da notare su questa funzione. Per prima cosa nota la [parola chiave `async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Scrivere le funzioni in modo che vengano eseguite in modo asincrono significa che attendono il completamento di un'azione, come la restituzione dei dati, prima di continuare. +Ci sono cose importanti da notare su questa funzione. Per prima cosa nota la [parola chiave `async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Scrivere le funzioni in modo che vengano eseguite in modo asincrono significa che attendono il completamento di un'azione, come la restituzione dei dati, prima di continuare. Ecco un breve video su `async`: @@ -200,7 +200,7 @@ Questa è una grande funzione. Cosa sta succedendo qui? - una volta che l'API risponde, si assegnano i vari elementi dei suoi dati di risposta alle parti dello schermo che sono state impostate per mostrare questi dati. - se c'è un errore, o se non c'è risultato, viene mostrato un messaggio di errore. -✅ L'utilizzo di schemi di programmazione asincrona è un altro strumento molto utile nella propria cassetta degli attrezzi. Informarsi [sui vari modi in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) cui si può configurare questo tipo di codice. +✅ L'utilizzo di schemi di programmazione asincrona è un altro strumento molto utile nella propria cassetta degli attrezzi. Informarsi [sui vari modi in](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) cui si può configurare questo tipo di codice. Complimenti! Se si compila la propria estensione`(npm run build`) e la si aggiorna nel pannello delle estensioni, si avrà un'estensione funzionante! L'unica cosa che non funziona è l'icona, verrà risolto nella prossima lezione. @@ -208,7 +208,7 @@ Complimenti! Se si compila la propria estensione`(npm run build`) e la si aggior ## 🚀 Sfida -Finora si è discusso sui diversi tipi di API in queste lezioni. Scegliere un'API web e cercare in profondità cosa offre. Ad esempio, dare un'occhiata alle API disponibili nei browser come l' [API HTML Drag and Drop](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API). Cosa si ritiene renda grande un'API? +Finora si è discusso sui diversi tipi di API in queste lezioni. Scegliere un'API web e cercare in profondità cosa offre. Ad esempio, dare un'occhiata alle API disponibili nei browser come l' [API HTML Drag and Drop](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Cosa si ritiene renda grande un'API? ## Quiz Post-Lezione diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.ko.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.ko.md index bf8b69de..67f4bbbb 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/translations/README.ko.md +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.ko.md @@ -94,7 +94,7 @@ function reset(e) { - 폼 숨기기 - 리셋 버튼 보이기 -계속 진행하기 전, 브라우저에서 사용할 수 있는 매우 중요한 개념: [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)에 대해 알아 보는 것이 좋습니다. LocalStorage는 브라우저에 문자열을 `key-value` 쌍으로 저장하는 유용한 방법입니다. 이런 타입의 웹 저장소는 브라우저에서 데이터를 관리하기 위해 JavaScript로 제어할 수 있습니다. LocalStorage는 만료되지 않지만, 다른 종류의 웹 저장소인 SessionStorage는 브라우저를 닫는 즉시 지워집니다. 다양한 타입의 저장소를 사용하는 것은 장점과 단점이 존재합니다. +계속 진행하기 전, 브라우저에서 사용할 수 있는 매우 중요한 개념: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)에 대해 알아 보는 것이 좋습니다. LocalStorage는 브라우저에 문자열을 `key-value` 쌍으로 저장하는 유용한 방법입니다. 이런 타입의 웹 저장소는 브라우저에서 데이터를 관리하기 위해 JavaScript로 제어할 수 있습니다. LocalStorage는 만료되지 않지만, 다른 종류의 웹 저장소인 SessionStorage는 브라우저를 닫는 즉시 지워집니다. 다양한 타입의 저장소를 사용하는 것은 장점과 단점이 존재합니다. > Note - 이 브라우저 확장은 로컬 저장소를 가집니다; 주요 브라우저 창은 각자 다른 객체이며 별도로 동작합니다. @@ -145,7 +145,7 @@ function setUpUser(apiKey, regionName) { ✅ 'REST'라는 용어는 'Representational State Transfer'를 의미하고 데이터를 가져오기 위해서 다양하게-구성된 URL을 쓰는 기능입니다. 개발자가 사용할 수 있는 다양한 타입의 API에 대해 약간 알아보십시오. 어떤 포맷이 좋습니까? -이 함수에 대해 유의해야 할 중요 사항이 있습니다. 먼저 [`async` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)를 확인합니다. 비동기로 실행되도록 함수를 작성한다는 것은 수행되기 전 데이터 반환 작업이 완료될 때를 기다린다는 점을 의미합니다. +이 함수에 대해 유의해야 할 중요 사항이 있습니다. 먼저 [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)를 확인합니다. 비동기로 실행되도록 함수를 작성한다는 것은 수행되기 전 데이터 반환 작업이 완료될 때를 기다린다는 점을 의미합니다. 다음은 `async`에 대한 간단한 영상입니다 : @@ -198,7 +198,7 @@ async function displayCarbonUsage(apiKey, region) { - API가 응답하면, 이 데이터를 출력하도록 설정한 화면에 응답 데이터의 다양한 요소를 할당합니다. - 오류가 있거나, 결과가 없는 경우에는, 오류 메시지가 출력됩니다. -✅ 비동기 프로그래밍 패턴을 사용하는 것은 툴박스의 다른 매우 유용한 도구입니다. [about the various ways](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)를 읽고 이런 타입의 코드를 구성할 수 있습니다. +✅ 비동기 프로그래밍 패턴을 사용하는 것은 툴박스의 다른 매우 유용한 도구입니다. [about the various ways](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)를 읽고 이런 타입의 코드를 구성할 수 있습니다. 축하합니다! 확장을 빌드하고 (`npm run build`) 확장 패널에서 새로 고치면, 작동하는 확장이 있습니다! 아이콘만 작동하지 않으며 다음 강의에서 수정할 예정입니다. @@ -206,7 +206,7 @@ async function displayCarbonUsage(apiKey, region) { ## 🚀 도전 -지금까지 이 강의에서 여러 타입의 API에 대해 논의했습니다. 웹 API를 선택하고 제공하는 내용에 대해 자세히 알아보세요. 예시로, [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)와 같은 브라우저에서 쓸 수 있는 API를 보세요. 당신의 의견에 비추어 볼 때 좋은 API를 만드는 방법은 무엇일까요? +지금까지 이 강의에서 여러 타입의 API에 대해 논의했습니다. 웹 API를 선택하고 제공하는 내용에 대해 자세히 알아보세요. 예시로, [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API)와 같은 브라우저에서 쓸 수 있는 API를 보세요. 당신의 의견에 비추어 볼 때 좋은 API를 만드는 방법은 무엇일까요? ## 강의 후 퀴즈 diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.ms.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.ms.md index 1ba31d65..39eabe86 100644 --- a/5-browser-extension/2-forms-browsers-local-storage/translations/README.ms.md +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.ms.md @@ -94,7 +94,7 @@ Dalam fungsi ini, terdapat beberapa logik yang menarik. Bacalah, anda dapat meli - sembunyikan borang - tunjukkan butang set semula -Sebelum meneruskan, berguna untuk mengetahui konsep yang sangat penting yang terdapat dalam penyemak imbas: [LocalStorage] https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). LocalStorage adalah cara yang berguna untuk menyimpan rentetan dalam penyemak imbas sebagai pasangan `kunci-nilai` . Jenis storan web ini dapat dimanipulasi oleh JavaScript untuk menguruskan data di penyemak imbas. LocalStorage tidak akan habis masa berlakunya, sementara SessionStorage, jenis penyimpanan web lain, akan dihapus apabila penyemak imbas ditutup. Pelbagai jenis storan mempunyai kebaikan dan keburukan terhadap penggunaannya. +Sebelum meneruskan, berguna untuk mengetahui konsep yang sangat penting yang terdapat dalam penyemak imbas: [LocalStorage] https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage adalah cara yang berguna untuk menyimpan rentetan dalam penyemak imbas sebagai pasangan `kunci-nilai` . Jenis storan web ini dapat dimanipulasi oleh JavaScript untuk menguruskan data di penyemak imbas. LocalStorage tidak akan habis masa berlakunya, sementara SessionStorage, jenis penyimpanan web lain, akan dihapus apabila penyemak imbas ditutup. Pelbagai jenis storan mempunyai kebaikan dan keburukan terhadap penggunaannya. > Catatan - pelanjutan penyemak imbas anda mempunyai storan tempatan sendiri; tetingkap penyemak imbas utama adalah contoh yang berbeza dan berkelakuan secara berasingan. @@ -143,7 +143,7 @@ Sebelum melangkah lebih jauh, kita harus membincangkan API. API, atau [Applicati ✅ Istilah 'REST' adalah singkatan dari 'Representational State Transfer' dan ciri menggunakan URL yang dikonfigurasikan dengan pelbagai untuk mengambil data. Lakukan sedikit kajian mengenai pelbagai jenis API yang tersedia untuk pembangun. Format apa yang menarik bagi anda? -Terdapat perkara penting yang perlu diperhatikan mengenai fungsi ini. Perhatikan dahulu kata kunci [`async` kata kunci](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Menulis fungsi anda supaya mereka berjalan secara tidak segerak bermakna mereka menunggu tindakan, seperti data yang dikembalikan, diselesaikan sebelum meneruskan. +Terdapat perkara penting yang perlu diperhatikan mengenai fungsi ini. Perhatikan dahulu kata kunci [`async` kata kunci](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Menulis fungsi anda supaya mereka berjalan secara tidak segerak bermakna mereka menunggu tindakan, seperti data yang dikembalikan, diselesaikan sebelum meneruskan. Inilah video ringkas mengenai `async`: @@ -198,7 +198,7 @@ Ini adalah fungsi besar. Apa yang berlaku di sini? - setelah API bertindak balas, anda menetapkan pelbagai elemen data responsnya ke bahagian-bahagian skrin yang anda siapkan untuk menunjukkan data ini. - jika ada ralat, atau jika tidak ada hasil, anda akan menunjukkan mesej ralat. -✅ Menggunakan corak pengaturcaraan tak segerak adalah alat lain yang sangat berguna dalam kotak alat anda. Baca untuk[mengenai pelbagai cara](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) anda boleh mengkonfigurasi jenis kod ini. +✅ Menggunakan corak pengaturcaraan tak segerak adalah alat lain yang sangat berguna dalam kotak alat anda. Baca untuk[mengenai pelbagai cara](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) anda boleh mengkonfigurasi jenis kod ini. Tahniah! Sekiranya anda membina pelanjutan anda (`npm run build`) dan menyegarkannya di panel pelanjutan anda, anda mempunyai sambungan yang berfungsi! Satu-satunya perkara yang tidak berfungsi ialah ikon, dan anda akan memperbaikinya pada pelajaran seterusnya. @@ -206,7 +206,7 @@ Tahniah! Sekiranya anda membina pelanjutan anda (`npm run build`) dan menyegarka ## 🚀 Cabaran -Kami telah membincangkan beberapa jenis API setakat ini dalam pelajaran ini. Pilih API web dan teliti secara mendalam apa yang ditawarkannya. Sebagai contoh, perhatikan API yang tersedia dalam penyemak imbas seperti [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API). Apa yang menjadikan API hebat pada pendapat anda? +Kami telah membincangkan beberapa jenis API setakat ini dalam pelajaran ini. Pilih API web dan teliti secara mendalam apa yang ditawarkannya. Sebagai contoh, perhatikan API yang tersedia dalam penyemak imbas seperti [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Apa yang menjadikan API hebat pada pendapat anda? ## Kuiz Pasca Kuliah diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md b/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md new file mode 100644 index 00000000..c10d9d61 --- /dev/null +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/README.zh-tw.md @@ -0,0 +1,224 @@ +# 瀏覽器擴充功能專案 Part 1:呼叫 API,使用 Local Storage + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/25?loc=zh_tw) + +### 大綱 + +在這堂課中,藉由傳遞你的擴充功能表單並顯示結果來呼叫 API。此外,你會了解如何儲存資料到瀏覽器的 Local Storage 中給未來使用。 + +✅ 請參考下列程式碼段,加入程式碼到檔案適當的位置 + +### 設定控制擴充功能的元素: + +現在你有已建好的 HTML 表單與結果區 `<div>`。接下來,你需要在 `/src/index.js` 做一些處理,一點一點地構築出你的擴充功能。參考[前一堂課程](../../1-about-browsers/translations/README.zh-tw.md)來設置你的專案與了解建制過程。 + +處理 `index.js` 檔案,建立一些 `const` 變數來儲存不同用途的數值: + +```JavaScript +// 表單區域 +const form = document.querySelector('.form-data'); +const region = document.querySelector('.region-name'); +const apiKey = document.querySelector('.api-key'); + +// 結果區域 +const errors = document.querySelector('.errors'); +const loading = document.querySelector('.loading'); +const results = document.querySelector('.result-container'); +const usage = document.querySelector('.carbon-usage'); +const fossilfuel = document.querySelector('.fossil-fuel'); +const myregion = document.querySelector('.my-region'); +const clearBtn = document.querySelector('.clear-btn'); +``` + +這些區域會被 CSS class 給參考,它們在前一堂課中已經被你設定好了。 + +### 新增監聽者 + +接下來,新增提交與重置表單的事件監聽者與按鈕,讓使用者能提交表單或是點擊重置鈕時,事件會發生。新增初始化呼叫處理到應用中,在檔案的最下方新增: + +```JavaScript +form.addEventListener('submit', (e) => handleSubmit(e)); +clearBtn.addEventListener('click', (e) => reset(e)); +init(); +``` + +✅ 注意提交事件與點擊事件的寫法,事件是如何被傳入到 handleSubmit 或是 reset 函式中的。你能在不改變功能的情況下,改寫成較長的格式嗎?你比較喜歡哪一種寫法? + +### 建立 init() 函式與 reset() 函式: + +現在你需要建立函式 init(),處理應用程式的初始化部分: + +```JavaScript +function init() { + //如果任何東西存在 localStorage 中,取出來 + const storedApiKey = localStorage.getItem('apiKey'); + const storedRegion = localStorage.getItem('regionName'); + + //設定 icon 為通用綠色 + //todo + + if (storedApiKey === null || storedRegion === null) { + //如果沒有 keys,顯示表單 + form.style.display = 'block'; + results.style.display = 'none'; + loading.style.display = 'none'; + clearBtn.style.display = 'none'; + errors.textContent = ''; + } else { + //localStorage 有 saved keys/regions,顯示結果 + displayCarbonUsage(storedApiKey, storedRegion); + results.style.display = 'none'; + form.style.display = 'none'; + clearBtn.style.display = 'block'; + } +}; + +function reset(e) { + e.preventDefault(); + //只清除 local storage 國家區域代碼 + localStorage.removeItem('regionName'); + init(); +} + +``` +在函式中,有一些有趣的邏輯。閱讀它們,你看出發生什麼事嗎? + +- 兩個 `const` 被設定為檢查用戶是否有儲存 APIKey 與國家區域代碼在 local storage 中。 +- 若兩者皆為 null,將造型設為 'block' 來顯示表單 +- 隱藏 results、loading 與 clearBtn,設定 error 文字為空字串 +- 若存在 key 與代碼,開始新的流程: + - 呼叫 API 取得碳排放資訊 + - 隱藏結果區域 + - 隱藏表單 + - 顯示重置按鈕 + +在下一步之前,你可以學習一些瀏覽器的重要成員:[LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)。 LocalStorage 是瀏覽器儲存字串的有效方法,以 `key-value` 配對兩兩一組。這種儲存型態可以被 JavaScript 管理並控制瀏覽器的資料。LocalStorage 沒有期限,而另一款網頁儲存 SessionStorage 會在瀏覽器關閉時清除內容。不同的儲存方式有各自的優缺點。 + +> 注意 ── 你的瀏覽器擴充套件有自己的 local storage。主瀏覽器視窗是不同的個體,兩者會做各自的行為。 + +你設定 APIKey 紀錄字串數值。你可以在 Edge 瀏覽器上「檢查」一個網頁 (右鍵瀏覽器來檢查),在 Applications 標籤中觀察儲存區的使用情況。 + + + +✅ 想想那些情況你不需要儲存資料到 LocalStorage 中。總體而言,將 API Keys 放在 LocalStorage 是個很糟糕的想法!你知道為什麼嗎?在我們的例子中,我們的應用程式是以教學為目的,並不會發布在應用程式商店中,所以我們選擇此中處理方式。 + +你可以發現網頁 API 能處理 LocalStorage,使用 `getItem()`、`setItem()` 或是 `removeItem()`。它們廣泛地支援不同的瀏覽器。 + +在建立函式 `init()` 中的函式 `displayCarbonUsage()` 之前,我們先建立表單提交初始化的功能。 + +### 處理表單提交 + +建立函式 `handleSubmit`,接收事件參數 `(e)`。終止網頁移轉的事件(在本例子中,我們終止瀏覽器刷新的處理)並呼叫新的函式 `setUpUser`,傳送參數 `apiKey.value` 與 `region.value`。藉由這個方式,你能將兩個初始表單的數值正確地移轉到適合的位置。 + +```JavaScript +function handleSubmit(e) { + e.preventDefault(); + setUpUser(apiKey.value, region.value); +} +``` +✅ 刷新你的記憶 ── 上堂課中的 HTML 檔案開頭有兩個輸入區域,它們的 `values` 被存到 `const` 中,並且被定為 `required`,表示瀏覽器禁止使用者輸入空值。 + +### 設定使用者 + +來到函式 `setUpUser`,這裡你能找到 apiKey 與 regionName 被存到 Local Storage 中。新增函式: + +```JavaScript +function setUpUser(apiKey, regionName) { + localStorage.setItem('apiKey', apiKey); + localStorage.setItem('regionName', regionName); + loading.style.display = 'block'; + errors.textContent = ''; + clearBtn.style.display = 'block'; + //建立初始化呼叫 + displayCarbonUsage(apiKey, regionName); +} +``` +這個函式設定當 API 被呼叫時,顯示讀取訊息。到這裡,你即將建立這個擴充功能專案最重要的函式! + +### 顯示碳排放量 + +最後,是時候查詢 API 了! + +在前往下一步前,我們先來討論何謂 API。API,[Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html),是網頁開發者工具箱內最重要的成員。它們提供程式標準的互動模式與溝通介面,舉例來說,如果你建立一個需要存取資料庫的網頁,資料庫方可能就有人建立了 API 供你使用。API 有各式各樣的種類,最普遍使用的為[REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)。 + +✅ 'REST' 全名為 'Representational State Transfer',提供各式各樣 URL 形式來抓取資料。對網路開發者的 API 種類做一點研究,什麼形式的 API 最吸引你? + +這條函式中有一個重要到值得紀錄的事情。第一點為[關鍵字 `async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)。讓你的函式非同步地執行,在行為完成前做等待,譬如資料被回傳。 + +這裡有一個簡短的影片介紹 `async`: + +[](https://youtube.com/watch?v=YwmlRkrxvkk "Async 與 Await 處理 promises 物件") + +> 點擊上方圖片以觀賞關於 async/await 的影片。 + +建立新的函式來詢問 C02Signal 的 API: + +```JavaScript +import axios from '../node_modules/axios'; + +async function displayCarbonUsage(apiKey, region) { + try { + await axios + .get('https://api.co2signal.com/v1/latest', { + params: { + countryCode: region, + }, + headers: { + 'auth-token': apiKey, + }, + }) + .then((response) => { + let CO2 = Math.floor(response.data.data.carbonIntensity); + + //calculateColor(CO2); + + loading.style.display = 'none'; + form.style.display = 'none'; + myregion.textContent = region; + usage.textContent = + Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)'; + fossilfuel.textContent = + response.data.data.fossilFuelPercentage.toFixed(2) + + '% (percentage of fossil fuels used to generate electricity)'; + results.style.display = 'block'; + }); + } catch (error) { + console.log(error); + loading.style.display = 'none'; + results.style.display = 'none'; + errors.textContent = 'Sorry, we have no data for the region you have requested.'; + } +} +``` + +這是一個挺大的函式,發生了什麼事? + +- 遵循程式實踐過程,你使用關鍵字 `async` 讓函式非同步地作行為。函式內的 `try/catch` 區塊會在 API 回傳資料時回傳 promise 物件。因為我們無法控制 API 會多快地回應訊息(甚至無法回應訊息!),你需要處理這種不確定性的時序關係。 +- 藉由提供 API Key 訪問 co2signal API 以取得你的地區資料。要使用這把鑰匙,你必須在網頁標頭中新增認證參數。 +- 當 API 回應時,你將各種物件填入回傳的數值,並輸出到畫面上中。 +- 如果發生錯誤,或沒有結果產生,輸出錯誤訊息。 + +✅ 非同步程式設計是一種實用的工具。閱讀[更多使用方法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)設定非同步程式的程式碼。 + +恭喜你!當你建制你的專案(`npm run build`)並在瀏覽器上刷新功能,你有個可以運作的應用套件了!現在只差圖示無法正常顯示,我們會在下一堂課中修正它。 + +--- + +## 🚀 挑戰 + +我們在課程中討論了不同種類的 API。選擇一樣網頁 API 並做更深度的研究。舉例來說,看看瀏覽器內支援的 API 如 [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)。依你看,什麼決定了 API 的優劣? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/26?loc=zh_tw) + +## 複習與自學 + +這堂課你學會關於 LocalStorage 與 API,它們對資深網頁開發者提供很大的幫助。你能想想這兩樣東西如何彼此相互合作呢?想想你會如何建構你的網頁,讓 API 得以使用你所儲存的資料。 + +## 作業 + +[認領一項 API](assignment.zh-tw.md) + diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.nl.md b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.nl.md new file mode 100644 index 00000000..68e4f2bd --- /dev/null +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Adopteer een API + +## Instructies + +API's kunnen erg leuk zijn om mee te spelen. Hier is een [lijst met vele gratis](https://github.com/public-apis/public-apis). Kies een API, en bouw een browserextensie die een probleem oplost. Het kan een zo klein probleem zijn als u niet genoeg foto's van huisdieren hebt (dus probeer de [dog CEO API](https://dog.ceo/dog-api/)) of iets groters - veel plezier! + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | -------------------------------------------------------------------------- | ---------------------------------------- | ----------------------- | +| | Een volledige browserextensie wordt ingediend met behulp van een API uit de bovenstaande lijst | Er is een gedeeltelijke browserextensie ingediend | De inzending bevat bugs | \ No newline at end of file diff --git a/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md new file mode 100644 index 00000000..c40fea7c --- /dev/null +++ b/5-browser-extension/2-forms-browsers-local-storage/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 認領一項 API + +## 大綱 + +API 可以是很好玩的。這裡有[許多公開 API 的清單](https://github.com/public-apis/public-apis)。挑選一項 API,建立一個網頁擴充功能來解決問題。問題可以很小,如找不到足夠的寵物照片,這時你可以嘗試使用[dog CEO API](https://dog.ceo/dog-api/));或是解決更大問題。好好享受吧! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | --------------------------------------------- | ------------------------ | ------------ | +| | 使用上述清單內的 API 建立完整的瀏覽器擴充功能 | 建立部分的瀏覽器擴充功能 | 套件存在問題 | \ No newline at end of file diff --git a/5-browser-extension/3-background-tasks-and-performance/README.md b/5-browser-extension/3-background-tasks-and-performance/README.md index f2c4db88..1b4da135 100644 --- a/5-browser-extension/3-background-tasks-and-performance/README.md +++ b/5-browser-extension/3-background-tasks-and-performance/README.md @@ -22,7 +22,7 @@ The Performance tab contains a Profiling tool. Open a web site (try, for example  -✅ Visit the [Microsoft Documentation](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa) on the Performance panel in Edge +✅ Visit the [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa) on the Performance panel in Edge > Tip: to get a true reading of your web site's startup time, clear your browser's cache diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.es.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.es.md index ebe74673..7a8723f0 100644 --- a/5-browser-extension/3-background-tasks-and-performance/translations/README.es.md +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.es.md @@ -20,7 +20,7 @@ La pestaña Rendimiento contiene una herramienta de creación de perfiles. Abra  -✅ Visite la [Documentación de Microsoft](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa) en el panel Rendimiento en Edge +✅ Visite la [Documentación de Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa) en el panel Rendimiento en Edge > Consejo: para obtener una lectura real de la hora de inicio de su sitio web, borre la memoria caché de su navegador diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.it.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.it.md index 78a01c39..fc261155 100644 --- a/5-browser-extension/3-background-tasks-and-performance/translations/README.it.md +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.it.md @@ -22,7 +22,7 @@ La scheda Prestazioni contiene uno strumento di profilazione. Aprire un sito web  -✅ Visitare la [documentazione Microsoft](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance) nel pannello Prestazioni in Edge +✅ Visitare la [documentazione Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance) nel pannello Prestazioni in Edge > Suggerimento: per ottenere una lettura fedele del tempo di avvio del proprio sito web, svuotare la cache del browser diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.ko.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.ko.md index 073f8d84..6f88b65c 100644 --- a/5-browser-extension/3-background-tasks-and-performance/translations/README.ko.md +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.ko.md @@ -22,7 +22,7 @@ Performance 탭에는 Profiling 도구가 있습니다. 웹 사이트를 열고  -✅ Edge에서 Performance 패널에서 [Microsoft Documentation](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa)를 방문하세요 +✅ Edge에서 Performance 패널에서 [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa)를 방문하세요 > Tip: 웹 사이트의 시작 시간을 순수하게 보려면, 브라우저의 캐시를 지우세요 diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.ms.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.ms.md index 94ee3f38..80db50fe 100644 --- a/5-browser-extension/3-background-tasks-and-performance/translations/README.ms.md +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.ms.md @@ -22,7 +22,7 @@ Tab Prestasi mengandungi alat Profil. Buka laman web (cuba, misalnya, https://ww  -✅ Lawati [Microsoft Documentation](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance) pada panel Performance di Edge +✅ Lawati [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance) pada panel Performance di Edge > Petua: untuk mendapatkan bacaan sebenar mengenai masa permulaan laman web anda, kosongkan cache penyemak imbas anda diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md b/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md new file mode 100644 index 00000000..6d7805aa --- /dev/null +++ b/5-browser-extension/3-background-tasks-and-performance/translations/README.zh.tw.md @@ -0,0 +1,160 @@ +# 瀏覽器擴充功能專案 Part 1:學習背景工作與效能 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/27?loc=zh_tw) + +### 大綱 + +在前兩堂課程中,你學會如何建立表單、顯示 API 回覆的資料在結果區塊中,這是網頁處理網頁資訊的標準行為。你甚至學會了如何非同步性地抓取資料。你的擴充套件就快完成了。 + +它只剩管理背景工作:包括刷新套件的圖示顏色,我們來討論瀏覽器是如何處理這類的工作。也讓我們探討你所建立的網頁,瀏覽器會多有效地處理其中的內容。 + +## 網頁處理效能的基礎 + +> "網頁處理效能攸關兩件事:網頁多快地載入,與程式多快地執行。" -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/) + +關於如何讓你的網頁能快速地運作在各類裝置、各個使用者以及各種情況,是一件難以想像的龐大主題。這裡有一些要點確保你在開發網頁或是擴充功能時,銘記在心。 + +第一件事為確保網頁收集關於網頁效能的資料,在瀏覽器的開發者工具中可以實現它。在 Edge 中,選擇「設定及更多」按鈕(瀏覽器上三個點的圖示),並選擇更多工具 > 開發人員工具並開啟 Performance 分頁。你也可以使用鍵盤快捷鍵,Windows 上的 `Ctrl` + `Shift` + `I` 與 Mac 上的 `Option` + `Command` + `I` 來開啟開發人員工具。 + +Performance 分頁包括了效能分析工具。開啟一個網頁,例如 https://www.microsoft.com,點擊 'Record' 按鈕並重新整理網頁。停止錄製後你就能取得網頁的 'script'、'render' 與 'paint' 的過程與資訊: + + + +✅ 造訪[Microsoft 文件](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/performance?WT.mc_id=academic-13441-cxa)觀看 Edge 的 Performance 分頁資訊 + +> 提示:要取得真正的網頁開啟時間,記得清除你的瀏覽器快取。 + +選擇一樣網頁在載入時,時間列中出現的事件物件。 + +觀看它的總覽面板並截圖你的網頁效能。 + + + +檢查 Event Log 面板,是否有網頁事件花超過 15 毫秒: + + + +✅ 了解你的性能分析工具!在這個網頁中,開啟開發者工具,檢查是否有任何 bottleneck。什麼是載入最久的物件?哪個又是最快的? + +## 效能分析 + +總體而言,每一位網頁開發者一定要注意一些「有問題的地方」,避免在發布作品時有令人意想不到的驚喜。 + +**資產(Asset)大小**:過去幾年來,網頁「變重」了,也因此變慢了。有些負擔來自於圖片的使用。 + +✅ 查詢[Internet Archive](https://httparchive.org/reports/page-weight),看看過去的網頁負擔等資訊。 + +一個好的習慣是確保你的圖片有做最佳化,呈現合理的檔案大小及解析度影像給你的使用者。 + +**DOM 查找元素(Traversal)**:瀏覽器必須依照你的程式碼建立 Document Object Model,請確保你的 tags 最小化,網頁只使用必須的功能與造型。另外,過量的網頁 CSS 也可以被最佳化,舉例來說,造型樣板只用在單頁上,而非全域上。 + +**JavaScript**:每一位 JavaScript 開發者會觀察 'render-blocking' 腳本,它會在 DOM 查找與瀏覽器呈現前被載入好。請考慮使用 `defer` 在你的程式碼中,我們的盆栽盒專案就有實踐這行。 + +✅ 在[網頁測速網](https://www.webpagetest.org/)上測試一些網頁,學習確認網頁效能的基本檢查。 + +現在你了解瀏覽器如何呈現你所提供的資產,我們來看看我們的擴充功能最後需要補齊的項目: + +### 建立函式計算顏色 + +編輯 `/src/index.js`,新增函式 `calculateColor()` 在一系列為了 DOM 存取的 `const` 變數之後: + +```JavaScript +function calculateColor(value) { + let co2Scale = [0, 150, 600, 750, 800]; + let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02']; + + let closestNum = co2Scale.sort((a, b) => { + return Math.abs(a - value) - Math.abs(b - value); + })[0]; + console.log(value + ' is closest to ' + closestNum); + let num = (element) => element > closestNum; + let scaleIndex = co2Scale.findIndex(num); + + let closestColor = colors[scaleIndex]; + console.log(scaleIndex, closestColor); + + chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } }); +} +``` + +發生了什麼事?你傳遞了 API 回傳的二氧化碳濃度數值,計算出它最適合對應的顏色矩陣索引位置。之後,你將這個顏色數值傳給了 chrome runtime。 + +chrome.runtime 有[一個 API](https://developer.chrome.com/extensions/runtime)處理所有的背景工作,你的擴充套件借助了此功能: + +> "在應用程式中,使用 chrome.runtime API 來接收背景頁面,回傳關於 manifest 的資訊,監聽並回應事件。你也可以利用此 API 轉換 URL 的相對路徑成絕對路徑。" + +✅ 如果你正打算開發此專案給 Edge 瀏覽器上使用,你會訝異你使用的是 chrome API。新的 Edge 瀏覽器執行在 Chromium browser 引擎上,所以你也能使用這些工具。 + +> 注意,如果你想要剖析瀏覽器擴充功能,請在擴充套件上執行開發者工具,它與瀏覽器主視窗為不同的個體。 + +### 設定圖示預設顏色 + +現在,在函式 `init()` 中,利用呼叫 chrome `updateIcon` 設定圖示顏色為通用綠: + +```JavaScript +chrome.runtime.sendMessage({ + action: 'updateIcon', + value: { + color: 'green', + }, +}); +``` +### 呼叫函式、執行呼叫 + +接下來,在 C02Signal API 回傳的 promise 物件下方呼叫函式: + +```JavaScript +//let CO2... +calculateColor(CO2); +``` +最後,在檔案 `/dist/background.js` 中,新增事件監聽者給這些背景行為的呼叫: + +```JavaScript +chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + if (msg.action === 'updateIcon') { + chrome.browserAction.setIcon({ imageData: drawIcon(msg.value) }); + } +}); +//參考 energy lollipop extension,很好的程式! +function drawIcon(value) { + let canvas = document.createElement('canvas'); + let context = canvas.getContext('2d'); + + context.beginPath(); + context.fillStyle = value.color; + context.arc(100, 100, 50, 0, 2 * Math.PI); + context.fill(); + + return context.getImageData(50, 50, 100, 100); +} +``` +在此程式中,你建立了事件監聽者給任何前到背景工作管理者的訊息。若 'updateIcon' 被呼叫,則接下來的程式會被執行,利用 Canvas API 繪製出對應顏色的圖示。 + +✅ 你會學習更多關於 Canvas API 在往後的[太空遊戲課程](../../6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md)。 + +現在,重新建制你的擴充功能(`npm run build`),刷新並運行你的套件,觀察圖示的顏色變化。現在是時候去跑腿或是洗碗嗎?現在你知道了! + +恭喜你,你已經建立了一款實用的瀏覽器擴充功能,並學到更多瀏覽器的運作方式與監測它的效能分析。 + +--- + +## 🚀 挑戰 + +調查一些悠久的開源網站,並根據它們的 GitHub 歷史,你能分辨它們過去幾年以來效能上的調整嗎?什麼它們是共同的痛點? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/28?loc=zh_tw) + +## 複習與自學 + +請考慮註冊[performance newsletter](https://perf.email/) + +調查瀏覽器測量網頁效能的方法,查看開發者工具內的 Performance 分頁。你能找到什麼巨大的差別嗎? + +## 作業 + +[分析網頁效能](assignment.zh-tw.md) + diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/assignment.nl.md b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.nl.md new file mode 100644 index 00000000..c59647ac --- /dev/null +++ b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.nl.md @@ -0,0 +1,9 @@ +# Analyseer een site op prestaties + +Geef een gedetailleerd rapport van een website, met de gebieden waar de prestaties problematisch zijn. Analyseer waarom de site traag is en wat u zou kunnen doen om deze te versnellen. Vertrouw niet alleen op de browsertools, maar doe wat onderzoek naar andere tools die u kunnen helpen bij uw rapportage + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ---------------------------------------------------------------------------------------------------------- | --------------------------- | ----------------------------- | +| | Er wordt een rapport gepresenteerd met details die niet alleen uit browsertools zijn gehaald, maar ook uit tools van derden, indien beschikbaar | Er wordt een basisrapport gepresenteerd | Er wordt een minimaal rapport gepresenteerd | \ No newline at end of file diff --git a/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md new file mode 100644 index 00000000..8f733b7e --- /dev/null +++ b/5-browser-extension/3-background-tasks-and-performance/translations/assignment.zh-tw.md @@ -0,0 +1,9 @@ +# 分析網頁效能 + +請提供一份詳細的報告,點出一個網頁效能上的問題點。分析網頁緩慢的原因並提供改善它的方案。不要只依賴瀏覽器工具,做一點研究尋找更多幫助你的工具。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------------------------- | -------------- | ------------ | +| | 詳細的報告包括非瀏覽器的第三方工具 | 呈現出標準報告 | 報告內容有限 | \ No newline at end of file diff --git a/5-browser-extension/translations/README.nl.md b/5-browser-extension/translations/README.nl.md new file mode 100644 index 00000000..40ad0080 --- /dev/null +++ b/5-browser-extension/translations/README.nl.md @@ -0,0 +1,28 @@ +# Een browserextensie bouwen + +Het bouwen van browserextensies is een leuke en interessante manier om na te denken over de prestaties van uw apps terwijl u een ander type webitem bouwt. Deze module bevat lessen over hoe browsers werken en hoe u een browserextensie implementeert, hoe u een formulier bouwt, een API aanroept en lokale opslag gebruikt, en hoe u de prestaties van uw website peilt en deze verbetert. + +U bouwt een browserextensie die werkt op Edge, Chrome en Firefox. Deze extensie, die lijkt op een mini-website die is afgestemd op een zeer specifieke taak, controleert de [C02 Signal API](https://www.co2signal.com) voor het elektriciteitsverbruik en de koolstofintensiteit van een bepaalde regio en geeft een lezing over de ecologische voetafdruk van de regio. + +Deze extensie kan door een gebruiker ad-hoc worden genoemd zodra een API-sleutel en regiocode in een formulier zijn ingevoerd om het lokale elektriciteitsverbruik te bepalen en daardoor gegevens te bieden die de elektriciteitsbeslissingen van een gebruiker kunnen beïnvloeden. Het kan bijvoorbeeld de voorkeur hebben om het gebruik van een wasdroger (een koolstofintensieve activiteit) uit te stellen tijdens een periode van hoog elektriciteitsverbruik in uw regio. + +### Onderwerpen + +1. [Over de browser](../1-about-browsers/translations/README.nl.md) +2. [Formulieren en lokale opslag](../2-forms-browsers-local-storage/translations/README.nl.md) +3. [Achtergrondtaken en prestaties](../3-background-tasks-and-performance/translations/README.nl.md) + +### Credits + + + +## Credits + +Het idee voor deze web-koolstoftrigger werd aangedragen door Asim Hussain, hoofd bij Microsoft van het Green Cloud Advocacy-team en auteur van de [Green Principles](https://principles.green/). Het was oorspronkelijk een [websiteproject](https://github.com/jlooper/green). + +De structuur van de browserextensie werd beïnvloed door [de COVID-extensie van Adebola Adeniran](https://github.com/onedebos/covtension). + +Het concept achter het 'punt'-pictogramsysteem werd gesuggereerd door de pictogramstructuur van de [Energy Lollipop](https://energylollipop.com/) browserextensie voor Californische emissies. + +Deze lessen zijn geschreven met ♥ door [Jen Looper](https://www.twitter.com/jenlooper) + diff --git a/5-browser-extension/translations/README.zh-tw.md b/5-browser-extension/translations/README.zh-tw.md new file mode 100644 index 00000000..8a0ec8d1 --- /dev/null +++ b/5-browser-extension/translations/README.zh-tw.md @@ -0,0 +1,28 @@ +# 建立瀏覽器擴充功能 + +建立瀏覽器擴充功能是個好玩且有趣的方式來思考應用程式的執行效能,包含各式各樣類型的網頁資產。這堂學習模組介紹了瀏覽器運作方式、如何架設擴充功能、建立表單、呼叫 API、使用 Local Storage 和測量網頁效能的方法並增進它。 + +你會建立一個支援在 Edge、Chrome 與 Firefox 的瀏覽器擴充功能。這個擴充功能就像小型的網頁,專門滿足特定課題:利用[C02 Signal API](https://www.co2signal.com)檢查地區的電力使用與碳排濃度,回傳地區的碳足跡。 + +這款特設擴充功能允許使用者在輸入完 API Key 與國家地區代碼到表單後,取得當地電力使用量與其他資訊,決定使用者後續的行為。舉例來說,在地區高電力用量時,你可能會延後烘衣機的使用(增加碳排)。 + +### 主題 + +1. [關於瀏覽器](../1-about-browsers/translations/README.zh-tw.md) +2. [表單與 Local Storage](../2-forms-browsers-local-storage/translations/README.zh-tw.md) +3. [背景工作與效能](../3-background-tasks-and-performance/translations/README.zh-tw.md) + +### 成就 + + + +## 參與人員 + +網頁碳排放追蹤的發想出自於 Asim Hussain,微軟綠能雲端倡導小組的領導人與[Green Principles](https://principles.green/)的作者。這源自於一個[網頁專案](https://github.com/jlooper/green)。 + +擴充功能的結構受[Adebola Adeniran 的 COVID 擴充功能](https://github.com/onedebos/covtension)啟發。 + +「點」圖示系統的概念參考[Energy Lollipop](https://energylollipop.com/)的加州排放擴充功能。 + +這些課程由 [Jen Looper](https://www.twitter.com/jenlooper) 用滿滿的 ♥️ 來編寫。 + diff --git a/6-space-game/1-introduction/README.md b/6-space-game/1-introduction/README.md index 09f79680..658bde55 100644 --- a/6-space-game/1-introduction/README.md +++ b/6-space-game/1-introduction/README.md @@ -29,7 +29,7 @@ All we described above are behavior that game objects can have. So how do we enc The idea is to use `classes` in conjunction with `inheritance` to accomplish adding a certain behavior to a class. -✅ Inheritance is an important concept to understand. Learn more on [MDN's article about inheritance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). +✅ Inheritance is an important concept to understand. Learn more on [MDN's article about inheritance](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). Expressed via code, a game object can typically look like this: @@ -217,7 +217,7 @@ Think about how the pub-sub pattern can enhance a game. Which parts should emit ## Review & Self Study -Learn more about Pub/Sub by [reading about it](https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa). +Learn more about Pub/Sub by [reading about it](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa). ## Assignment diff --git a/6-space-game/1-introduction/translations/README.es.md b/6-space-game/1-introduction/translations/README.es.md index f4291066..661ae11c 100644 --- a/6-space-game/1-introduction/translations/README.es.md +++ b/6-space-game/1-introduction/translations/README.es.md @@ -27,7 +27,7 @@ Todo lo que describimos anteriormente son comportamientos que pueden tener los o La idea es usar `classes` junto con `inheritance` para lograr agregar un cierto comportamiento a una clase. -✅ La herencia es un concepto importante de comprender. Obtenga más información en el [artículo de MDN sobre herencia](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). +✅ La herencia es un concepto importante de comprender. Obtenga más información en el [artículo de MDN sobre herencia](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). Expresado a través de código, un objeto de juego normalmente puede verse así: @@ -211,6 +211,6 @@ A medida que las cosas se complican cuando tu juego crece, este patrón permanec ## Revisión y autoestudio -Obtenga más información sobre Pub / Sub al [leer sobre él](https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa). +Obtenga más información sobre Pub / Sub al [leer sobre él](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa). **Tarea**: [Mock up a game](assignment.es.md) \ No newline at end of file diff --git a/6-space-game/1-introduction/translations/README.hi.md b/6-space-game/1-introduction/translations/README.hi.md index bffa5eb1..1aec19df 100644 --- a/6-space-game/1-introduction/translations/README.hi.md +++ b/6-space-game/1-introduction/translations/README.hi.md @@ -29,7 +29,7 @@ विचार एक क्लास के लिए एक निश्चित व्यवहार को जोड़ने के लिए `inheritence` के साथ संयोजन में `inheritence` का उपयोग करने के लिए है. -✅ समझने के लिए इन्हेरिटेंस एक महत्वपूर्ण अवधारणा है। [एमडीएन के इन्हेरिटेंस के बारे में लेख](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototyp_chain) पर और जानें. +✅ समझने के लिए इन्हेरिटेंस एक महत्वपूर्ण अवधारणा है। [एमडीएन के इन्हेरिटेंस के बारे में लेख](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototyp_chain) पर और जानें. कोड के माध्यम से व्यक्त, एक गेम ऑब्जेक्ट आमतौर पर इस तरह दिख सकता है: @@ -215,7 +215,7 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => { ## समीक्षा और स्व अध्ययन -pub/sub[के बारे में पढ़े](https://docs.microsoft.com/en-us/azure/altecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa) और अधिक जानें . +pub/sub[के बारे में पढ़े](https://docs.microsoft.com/azure/altecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa) और अधिक जानें . ## असाइनमेंट diff --git a/6-space-game/1-introduction/translations/README.ko.md b/6-space-game/1-introduction/translations/README.ko.md index 7f2eaa24..133d69e9 100644 --- a/6-space-game/1-introduction/translations/README.ko.md +++ b/6-space-game/1-introduction/translations/README.ko.md @@ -29,7 +29,7 @@ 아이디어로는 클래스에 특정 동작을 추가하기 위해 `inheritance`과 함께 `classes`를 사용하는 것입니다. -✅ 상속은 이해해야 할 중요한 컨셉입니다. [MDN's article about inheritance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)로 더 배워보세요. +✅ 상속은 이해해야 할 중요한 컨셉입니다. [MDN's article about inheritance](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)로 더 배워보세요. 코드를 통해 표현되는, 게임 객체는 일반적으로 다음과 같습니다: @@ -217,7 +217,7 @@ pub-sub 패턴이 어떻게 게임을 발전시킬 수 있는지 생각해보세 ## 리뷰 & 자기주도 학습 -[reading about it](https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa)으로 Pub/Sub에 대해 조금 더 배워봅시다. +[reading about it](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa)으로 Pub/Sub에 대해 조금 더 배워봅시다. ## 과제 diff --git a/6-space-game/1-introduction/translations/README.ms.md b/6-space-game/1-introduction/translations/README.ms.md index 7b48c2c7..70299ff4 100644 --- a/6-space-game/1-introduction/translations/README.ms.md +++ b/6-space-game/1-introduction/translations/README.ms.md @@ -29,7 +29,7 @@ Yang kami terangkan di atas adalah tingkah laku yang boleh dimiliki oleh objek p Ideanya adalah untuk menggunakan `kelas` bersama dengan `pewarisan` untuk menyelesaikan penambahan tingkah laku tertentu ke kelas. -✅ Warisan adalah konsep penting untuk difahami. Ketahui lebih lanjut mengenai [artikel MDN mengenai pewarisan](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). +✅ Warisan adalah konsep penting untuk difahami. Ketahui lebih lanjut mengenai [artikel MDN mengenai pewarisan](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). Diekspresikan melalui kod, objek permainan biasanya dapat terlihat seperti ini: @@ -217,7 +217,7 @@ Fikirkan bagaimana corak pub-sub dapat meningkatkan permainan. Bahagian mana yan ## Mengkaji & Belajar Sendiri -Ketahui lebih lanjut mengenai Pub/Sub dengan [membaca mengenainya](https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber). +Ketahui lebih lanjut mengenai Pub/Sub dengan [membaca mengenainya](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber). ## Tugasan diff --git a/6-space-game/1-introduction/translations/README.zh-tw.md b/6-space-game/1-introduction/translations/README.zh-tw.md new file mode 100644 index 00000000..b73cf989 --- /dev/null +++ b/6-space-game/1-introduction/translations/README.zh-tw.md @@ -0,0 +1,224 @@ +# 建立太空遊戲 Part 1:簡介 + + + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/29?loc=zh_tw) + +### 遊戲開發中的繼承(Inheritance)與組合(Composition) + +在之前的課程中,因為專案較小的規模,我們不需要去擔憂應用程式的設計結構。然而,當你的應用程式規模越來越大時,結構的選擇就是一大課題。在 JavaScript 中,有兩種大方向來建立龐大的應用程式:*組合(Composition)*與*繼承(Inheritance)*。它們有各自的優缺點,我們會藉由遊戲內容來進行說明。 + +✅ 其中一本有名的程式設計用書是有關於[設計模式](https://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%9A%E5%8F%AF%E5%A4%8D%E7%94%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BD%AF%E4%BB%B6%E7%9A%84%E5%9F%BA%E7%A1%80)。 + +在遊戲中你會有`遊戲物件`,顯示在畫面中。這代表它們在笛卡爾座標系中有各自的位置,以 `x` 與 `y` 座標點定義。當你在開發遊戲時,你會注意到所有的遊戲物件都有一套標準的規範,和大多數的遊戲相似,通常會有這些元素: + +- **適地性** 大多數遊戲元素都是建立在位置上的。這代表他們有各自的所在處,一組 `x` 與 `y`。 +- **可移動的** 這些物件可以移動到新的位置。典型來說有英雄、怪物或是 NPC(Non Player Character),但有些例外,好比是樹這種常駐物件。 +- **可自毀的** 這些物件只能存在於一小段時間,接著它們就會自我刪除。通常這是`死亡`或是`被摧毀`的布林訊號傳遞給遊戲引擎,告知物件不再需要被描繪出來。 +- **冷卻時間** 「冷卻時間」是存活週期短的典型物件屬性。好比是一段文字、爆炸的視覺特效,只能呈現數毫秒的時間。 + +✅ 想想看遊戲小精靈(Pac-Man)。你能辨別出符合上述清單的其中四種物件嗎? + +### 行為表達 + +以上的敘述皆在表達遊戲物件所進行的行為。那我們該如何去編寫它們呢?我們可以使用方法(methods)連接 classes 或是物件(objects)來表達這些行為。 + +**Classes** + +這個想法是結合 `classes` 與`繼承`的方式來在 class 中添加特定行為。 + +✅ 繼承是一個重要概念。在[有關繼承的 MDN 文章中](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)學習更多內容。 + +以程式碼來表達的話,一個遊戲物件通常會呈現這種形式: + +```javascript + +//設定 class GameObject +class GameObject { + constructor(x, y, type) { + this.x = x; + this.y = y; + this.type = type; + } +} + +//這個 class 會繼承 GameObject 中 class 內容 +class Movable extends GameObject { + constructor(x,y, type) { + super(x,y, type) + } + +//這個可移動物件可以在畫面上移動 + moveTo(x, y) { + this.x = x; + this.y = y; + } +} + +//這是特定的 class 繼承 Movable class,它能使用所有繼承到的屬性內容 +class Hero extends Movable { + constructor(x,y) { + super(x,y, 'Hero') + } +} + +//另一方面,這個 class 只繼承到 GameObject 的內容 +class Tree extends GameObject { + constructor(x,y) { + super(x,y, 'Tree') + } +} + +//英雄可以移動...... +const hero = new Hero(); +hero.moveTo(5,5); + +//但樹木卻不能 +const tree = new Tree(); +``` + +✅ 花點時間重新構思小精靈(Pac-Man)的主角,或是 Inky、Pinky 與 Blinky 這幾隻鬼魂。它們該如何以 JavaScript 表現? + +**組合** + +另一種處理物件繼承的方式為*組合(Composition)*。物件以這種方式呈現它們的行為: + +```javascript +//建立常數 gameObject +const gameObject = { + x: 0, + y: 0, + type: '' +}; + +//...與常數 movable +const movable = { + moveTo(x, y) { + this.x = x; + this.y = y; + } +} +//常數 movableObject 是 gameObject 與 movable 的組合 +const movableObject = {...gameObject, ...movable}; + +//利用函式建立新的英雄,繼承 movableObject 的內容 +function createHero(x, y) { + return { + ...movableObject, + x, + y, + type: 'Hero' + } +} +//...與常駐物件只繼承 gameObject 的屬性 +function createStatic(x, y, type) { + return { + ...gameObject + x, + y, + type + } +} +//建立可以移動的英雄 +const hero = createHero(10,10); +hero.moveTo(5,5); +//和建立只能佇立於此的樹木 +const tree = createStatic(0,0, 'Tree'); +``` + +**我該使用哪一種設計模式?** + +這都取決於你選擇何種設計模式。JavaScript 支援這兩種範例。 + +-- + +另一種在遊戲開發中常見的設計模式負責處理玩家的遊戲表現與遊戲體驗。 + +## 發布訂閱設計模式 + +✅ Pub/Sub 全名為 'publish-subscribe' + +這個設計模式將應用程式內不同的模組分開處理,讓彼此不知道彼此的行為。為何要這樣做?這讓我們總觀上更輕易地了解各個模組的行為。也可以在你想要時輕易地改變模組的行為模式。我們該如何實踐它呢?我們先建立這幾個概念: + +- **訊息**: 一個訊息通常會以文字字串與額外的負載(payload) ── 一組定義訊息內容的資料 ── 呈現。遊戲中典型的訊息可以是 `KEY_PRESSED_ENTER`。 +- **發布者**: 這個元素*發布*訊息給所有的訂閱者。 +- **訂閱者**: 這個元素*監聽*特定的訊息,並藉由執行某些任務以作為訊息的回應,例如發射雷射光。 + +實踐方法雖小,但這是功能強大的設計方式。這是它的建立方式: + +```javascript +//設定 EventEmitter class 容納監聽者 +class EventEmitter { + constructor() { + this.listeners = {}; + } +//當訊息接收時,讓監聽者處理它的負載 + on(message, listener) { + if (!this.listeners[message]) { + this.listeners[message] = []; + } + this.listeners[message].push(listener); + } +//當訊息發出時,附上負載發給監聽者 + emit(message, payload = null) { + if (this.listeners[message]) { + this.listeners[message].forEach(l => l(message, payload)) + } + } +} + +``` + +利用上述程式我們建立一套小型實作內容: + +```javascript +//設定訊息種類 +const Messages = { + HERO_MOVE_LEFT: 'HERO_MOVE_LEFT' +}; +//調用你設定的 eventEmitter +const eventEmitter = new EventEmitter(); +//設定英雄 +const hero = createHero(0,0); +//讓 eventEmitter 監聽有關英雄往左移的訊息,並執行動作 +eventEmitter.on(Messages.HERO_MOVE_LEFT, () => { + hero.move(5,0); +}); + +//設定遊戲視窗來監聽鍵盤事件,當左方向鍵按壓時,發出英雄往左移的訊息 +window.addEventListener('keyup', (evt) => { + if (evt.key === 'ArrowLeft') { + eventEmitter.emit(Messages.HERO_MOVE_LEFT) + } +}); +``` + +我們連接了鍵盤事件 `ArrowLeft` 並傳遞 `HERO_MOVE_LEFT` 訊息。我們監聽該訊息並移動 `hero` 作為結果。這種開發方式讓事件監聽者與英雄區隔開來。你也可以將 `ArrowLeft` 換成 `A` 鍵。此外,我們能修改 eventEmitter 的 on 函式,讓 `ArrowLeft` 事件產生截然不同的行為。 + +```javascript +eventEmitter.on(Messages.HERO_MOVE_LEFT, () => { + hero.move(5,0); +}); +``` + +當遊戲越來越豐富、物件越來越複雜時,這套設計方式能維持程式碼的整潔。由衷建議善用這套設計模式。 + +--- + +## 🚀 挑戰 + +想想看發布訂閱模式可以如何增進一款遊戲。哪一個部份該發送事件,而遊戲又該如何回應事件?現在你有機會發揮你的創意,思考一款新遊戲和它運作的模組。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/30?loc=zh_tw) + +## 複習與自學 + +藉由[閱讀此連結](https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber?WT.mc_id=academic-13441-cxa)來認識更多關於發布與訂閱的設計模式。 + +## 作業 + +[建立遊戲雛形](assignment.zh-tw.md) diff --git a/6-space-game/1-introduction/translations/assignment.nl.md b/6-space-game/1-introduction/translations/assignment.nl.md new file mode 100644 index 00000000..8ceecc1c --- /dev/null +++ b/6-space-game/1-introduction/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Maak een spel na + +## Instructies + +Gebruik de codevoorbeelden in de les om een weergave te maken van een spel dat u leuk vindt. Het zal een eenvoudig spel moeten zijn, maar het doel is om ofwel de class of het compositiepatroon en het pub/subpatroon te gebruiken om te laten zien hoe een spel zou kunnen starten. Wees creatief! + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------------- | +| | Drie elementen worden op het scherm geplaatst en gemanipuleerd | Twee elementen worden op het scherm geplaatst en gemanipuleerd | Een element wordt op het scherm geplaatst en gemanipuleerd | \ No newline at end of file diff --git a/6-space-game/1-introduction/translations/assignment.zh-tw.md b/6-space-game/1-introduction/translations/assignment.zh-tw.md new file mode 100644 index 00000000..22477e5f --- /dev/null +++ b/6-space-game/1-introduction/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 建立遊戲雛形 + +## 簡介 + +使用本課程中的程式案例,編寫一款你喜歡的遊戲呈現方式。這是一款簡單小規模的遊戲,目的是要能以 class、組合模式與發布訂閱模式呈現遊戲的運作方式。發揮你的創意! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------- | -------------------------- | ---------------------------- | +| | 畫面上有三個元素且能被控制 | 畫面上有兩個元素且能被控制 | 畫面上只有一個元素且能被控制 | diff --git a/6-space-game/2-drawing-to-canvas/README.md b/6-space-game/2-drawing-to-canvas/README.md index 0e9d7d38..6474fd32 100644 --- a/6-space-game/2-drawing-to-canvas/README.md +++ b/6-space-game/2-drawing-to-canvas/README.md @@ -8,7 +8,7 @@ The canvas is an HTML element that by default has no content; it's a blank slate. You need to add to it by drawing on it. -✅ Read [more about the Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) on MDN. +✅ Read [more about the Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) on MDN. Here's how it's typically declared, as part of the page's body: @@ -27,7 +27,7 @@ Above we are setting the `id`, `width` and `height`. The Canvas is using a cartesian coordinate system to draw things. Thus it uses an x-axis and y-axis to express where something is located. The location `0,0` is the top left position and the bottom right is what you said to be the WIDTH and HEIGHT of the canvas.  -> Image from [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) +> Image from [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) To draw on the canvas element you will need to go through the following steps: @@ -52,7 +52,7 @@ ctx.fillStyle = 'red'; ctx.fillRect(0,0, 200, 200) // x,y,width, height ``` -✅ The Canvas API mostly focuses on 2D shapes, but you can also draw 3D elements to a web site; for this, you might use the [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API). +✅ The Canvas API mostly focuses on 2D shapes, but you can also draw 3D elements to a web site; for this, you might use the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API). You can draw all sorts of things with the Canvas API like: @@ -201,7 +201,7 @@ Please try solving it yourself first but if you get stuck, have a look at a [sol ## 🚀 Challenge -You've learned about drawing with the 2D-focused Canvas API; take a look at the [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), and try to draw a 3D object. +You've learned about drawing with the 2D-focused Canvas API; take a look at the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API), and try to draw a 3D object. ## Post-Lecture Quiz @@ -209,7 +209,7 @@ You've learned about drawing with the 2D-focused Canvas API; take a look at the ## Review & Self Study -Learn more about the Canvas API by [reading about it](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +Learn more about the Canvas API by [reading about it](https://developer.mozilla.org/docs/Web/API/Canvas_API). ## Assignment diff --git a/6-space-game/2-drawing-to-canvas/translations/README.es.md b/6-space-game/2-drawing-to-canvas/translations/README.es.md index 2a4490b3..e6fdf57d 100644 --- a/6-space-game/2-drawing-to-canvas/translations/README.es.md +++ b/6-space-game/2-drawing-to-canvas/translations/README.es.md @@ -8,7 +8,7 @@ El lienzo es un elemento HTML que por defecto no tiene contenido; es una pizarra en blanco. Necesita agregarle dibujo sobre él. -✅ Lea [más sobre la API Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) en MDN. +✅ Lea [más sobre la API Canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API) en MDN. Así es como se declara normalmente, como parte del cuerpo de la página: @@ -27,7 +27,7 @@ Arriba estamos configurando el `id`, `width` y `alto`. Canvas utiliza un sistema de coordenadas cartesiano para dibujar cosas. Por lo tanto, usa un eje xy un eje y para expresar dónde se encuentra algo. La ubicación `0,0` es la posición superior izquierda y la inferior derecha es lo que dijiste que era el ANCHO y ALTO del lienzo. ! [cuadrícula del lienzo](canvas_grid.png) -> Imagen de [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) +> Imagen de [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) Para dibujar en el elemento de lienzo, deberá seguir los siguientes pasos: @@ -52,7 +52,7 @@ ctx.fillStyle = 'red'; ctx.fillRect(0,0, 200, 200) // x, y, ancho, alto ``` -✅ La API de Canvas se enfoca principalmente en formas 2D, pero también puede dibujar elementos 3D en un sitio web; para esto, puede usar la [API WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API). +✅ La API de Canvas se enfoca principalmente en formas 2D, pero también puede dibujar elementos 3D en un sitio web; para esto, puede usar la [API WebGL](https://developer.mozilla.org/docs/Web/API/WebGL_API). Puede dibujar todo tipo de cosas con la API de Canvas como: @@ -200,13 +200,13 @@ El resultado final debería verse así: Intente resolverlo usted mismo primero, pero si se atasca, eche un vistazo a una [solución](solution/app.js) -🚀 Desafío: ha aprendido a dibujar con la API Canvas enfocada en 2D; eche un vistazo a la [API WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) e intente dibujar un objeto 3D. +🚀 Desafío: ha aprendido a dibujar con la API Canvas enfocada en 2D; eche un vistazo a la [API WebGL](https://developer.mozilla.org/docs/Web/API/WebGL_API) e intente dibujar un objeto 3D. ## [Post-lecture prueba](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/32) ## Revisión y autoestudio -Obtenga más información sobre la API de Canvas [leyendo sobre ella](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +Obtenga más información sobre la API de Canvas [leyendo sobre ella](https://developer.mozilla.org/docs/Web/API/Canvas_API). **Tarea**: [Jugar con la API de Canvas](assignment.es.md) \ No newline at end of file diff --git a/6-space-game/2-drawing-to-canvas/translations/README.hi.md b/6-space-game/2-drawing-to-canvas/translations/README.hi.md index 210a0332..c75c9aef 100644 --- a/6-space-game/2-drawing-to-canvas/translations/README.hi.md +++ b/6-space-game/2-drawing-to-canvas/translations/README.hi.md @@ -8,7 +8,7 @@ कैनवास एक HTML तत्व है जो डिफ़ॉल्ट रूप से कोई सामग्री नहीं है; यह एक खाली स्लेट है. आपको उस पर ड्राइंग करके इसे जोड़ना होगा. -✅ MDN पर [कैनवस एपीआई के बारे में और पढ़ें](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +✅ MDN पर [कैनवस एपीआई के बारे में और पढ़ें](https://developer.mozilla.org/docs/Web/API/Canvas_API). यहां बताया गया है कि पेज के मुख्य भाग के रूप में यह आमतौर पर घोषित किया जाता है: @@ -29,7 +29,7 @@  -> [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) से छवि +> [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) से छवि कैनवास तत्व पर आकर्षित करने के लिए आपको निम्नलिखित चरणों से गुजरना होगा: @@ -54,7 +54,7 @@ ctx.fillStyle = "red"; ctx.fillRect(0, 0, 200, 200); // x,y,width, height ``` -✅ कैनवस एपीआई ज्यादातर 2डी आकृतियों पर केंद्रित है, लेकिन आप एक वेब साइट पर 3डी तत्वों को भी आकर्षित कर सकते हैं; इसके लिए, आप [वेबगियल एपीआई](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) का उपयोग कर सकते हैं. +✅ कैनवस एपीआई ज्यादातर 2डी आकृतियों पर केंद्रित है, लेकिन आप एक वेब साइट पर 3डी तत्वों को भी आकर्षित कर सकते हैं; इसके लिए, आप [वेबगियल एपीआई](https://developer.mozilla.org/docs/Web/API/WebGL_API) का उपयोग कर सकते हैं. आप कैनवस एपीआई के साथ सभी प्रकार की चीजें आकर्षित कर सकते हैं जैसे की : @@ -203,7 +203,7 @@ npm start ## 🚀 चुनौती -आपने 2डी-केंद्रित कैनवस एपीआई के साथ ड्राइंग के बारे में सीखा है; [वेबगियल एपीआई](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) पर एक नज़र डालें, और एक 3D ऑब्जेक्ट खींचने का प्रयास करें. +आपने 2डी-केंद्रित कैनवस एपीआई के साथ ड्राइंग के बारे में सीखा है; [वेबगियल एपीआई](https://developer.mozilla.org/docs/Web/API/WebGL_API) पर एक नज़र डालें, और एक 3D ऑब्जेक्ट खींचने का प्रयास करें. ## पोस्ट-व्याख्यान प्रश्नोत्तरी @@ -211,7 +211,7 @@ npm start ## समीक्षा और स्व अध्ययन -कैनवस एपीआई के बारे में अधिक जानकारी के लिए [इसके बारे में पढ़े](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +कैनवस एपीआई के बारे में अधिक जानकारी के लिए [इसके बारे में पढ़े](https://developer.mozilla.org/docs/Web/API/Canvas_API). ## असाइनमेंट diff --git a/6-space-game/2-drawing-to-canvas/translations/README.it.md b/6-space-game/2-drawing-to-canvas/translations/README.it.md index f460000d..3f048ee0 100644 --- a/6-space-game/2-drawing-to-canvas/translations/README.it.md +++ b/6-space-game/2-drawing-to-canvas/translations/README.it.md @@ -8,7 +8,7 @@ Canvas è un elemento HTML che per impostazione predefinita non ha contenuto; è una lavagna vuota. Si può riempirla disegnandoci sopra. -✅ [Ulteriori informazioni sull'API Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) su MDN. +✅ [Ulteriori informazioni sull'API Canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API) su MDN. Ecco come viene tipicamente dichiarato, come parte dell'elemento body della pagina: @@ -27,7 +27,7 @@ Sopra si è impostato l'`id`entificativo, la larghezza `(width)` e l'altezza (` Canvas utilizza un sistema di coordinate cartesiane per disegnare le cose. Quindi utilizza un asse x e un asse y per esprimere dove si trova qualcosa. La posizione `0,0` è la posizione in alto a sinistra e quella in basso a destra è ciò che si è determinato come larghezza (WIDTH) e altezza (HEIGHT) del canvas  -> Immagine da [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) +> Immagine da [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) Per disegnare sull'elemento canvas si dovranno eseguire i seguenti passaggi: @@ -52,7 +52,7 @@ ctx.fillStyle = 'red'; ctx.fillRect(0,0, 200, 200) // x,y,larghezza, altezza ``` -✅ L'API Canvas si concentra principalmente su forme 2D, ma si possono anche disegnare elementi 3D su un sito web; per questo, si potrebbe utilizzare l' [API WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API). +✅ L'API Canvas si concentra principalmente su forme 2D, ma si possono anche disegnare elementi 3D su un sito web; per questo, si potrebbe utilizzare l' [API WebGL](https://developer.mozilla.org/docs/Web/API/WebGL_API). Si può disegnare ogni sorta di cose con l'API Canvas come: @@ -209,7 +209,7 @@ Si è imparato a disegnare con l'API Canvas incentrata sul 2D; dare un'occhiata ## Revisione e Auto Apprendimento -Scoprire di più sull'API Canvas raccogliendo [informazioni su di essa](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +Scoprire di più sull'API Canvas raccogliendo [informazioni su di essa](https://developer.mozilla.org/docs/Web/API/Canvas_API). ## Compito diff --git a/6-space-game/2-drawing-to-canvas/translations/README.ko.md b/6-space-game/2-drawing-to-canvas/translations/README.ko.md index 408c2ebb..73da781b 100644 --- a/6-space-game/2-drawing-to-canvas/translations/README.ko.md +++ b/6-space-game/2-drawing-to-canvas/translations/README.ko.md @@ -8,7 +8,7 @@ canvas는 내용이 없는 게 기본인 HTML 요소입니다; 빈 상태입니다. 그리는 작업으로 추가해야 합니다. -✅ MDN애서 [Canvas API에 대하여 더](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) 읽어보세요. +✅ MDN애서 [Canvas API에 대하여 더](https://developer.mozilla.org/docs/Web/API/Canvas_API) 읽어보세요. 보통 페이지 본문의 일부로 선언되는 방법은 다음과 같습니다: @@ -27,7 +27,7 @@ canvas는 내용이 없는 게 기본인 HTML 요소입니다; 빈 상태입니 캔버스는 데카르트 좌표계로 사물을 그립니다. 따라서 x-축과 y-축을 이용하여 무언가의 위치를 나타냅니다. 위치 `0,0`은 죄측 상단이며 우측 하단은 캔버스의 너비와 높이라고 말한 위치입니다.  -> Image from [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) +> Image from [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) 캔버스 요소에 그리려면 다음 단계를 거쳐야 합니다: @@ -52,7 +52,7 @@ ctx.fillStyle = 'red'; ctx.fillRect(0,0, 200, 200) // x,y,width, height ``` -✅ Canvas API는 2D 모양에 가장 초점이 맞추어져 있습니다, 그러나 웹사이트에서 3D 요소를 그려야 된다면, [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)를 사용해야 할 수도 있습니다. +✅ Canvas API는 2D 모양에 가장 초점이 맞추어져 있습니다, 그러나 웹사이트에서 3D 요소를 그려야 된다면, [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API)를 사용해야 할 수도 있습니다. Canvas API를 사용하면 다음과 같은 모든 종류를 그릴 수 있습니다: @@ -201,7 +201,7 @@ npm start ## 🚀 도전 -2D-중심의 Canvas API로 그리는 방식에 대해 배웠습니다; [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)를 살펴보고, 3D 개체를 그려보세요. +2D-중심의 Canvas API로 그리는 방식에 대해 배웠습니다; [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API)를 살펴보고, 3D 개체를 그려보세요. ## 강의 후 퀴즈 @@ -209,7 +209,7 @@ npm start ## 리뷰 & 자기주도 학습 -[reading about it](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)을 통해 Canvas API에 대해 자세히 알아보세요. +[reading about it](https://developer.mozilla.org/docs/Web/API/Canvas_API)을 통해 Canvas API에 대해 자세히 알아보세요. ## 과제 diff --git a/6-space-game/2-drawing-to-canvas/translations/README.ms.md b/6-space-game/2-drawing-to-canvas/translations/README.ms.md index bda8281d..2af525e3 100644 --- a/6-space-game/2-drawing-to-canvas/translations/README.ms.md +++ b/6-space-game/2-drawing-to-canvas/translations/README.ms.md @@ -8,7 +8,7 @@ Kanvas adalah elemen HTML yang secara lalai tidak mempunyai isi; itu batu tulis kosong. Anda perlu menambahkannya dengan melukisnya. -✅ Baca [lebih lanjut mengenai Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) di MDN. +✅ Baca [lebih lanjut mengenai Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) di MDN. Inilah cara ia dinyatakan secara umum, sebagai bahagian badan halaman: @@ -27,7 +27,7 @@ Di atas kita menetapkan `id`, `lebar` dan `tinggi`. Canvas menggunakan sistem koordinat kartesian untuk menarik sesuatu. Oleh itu ia menggunakan paksi-x dan paksi-y untuk menyatakan di mana sesuatu berada. Lokasi `0,0` adalah kedudukan kiri atas dan kanan bawah adalah yang anda katakan sebagai Luas dan TINGGI kanvas.  -> Imej dari [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) +> Imej dari [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) Untuk menggunakan elemen kanvas, anda perlu melalui langkah-langkah berikut: @@ -52,7 +52,7 @@ ctx.fillStyle = 'red'; ctx.fillRect(0,0, 200, 200) // x,y,luas,tinggi ``` -✅ Canvas API kebanyakannya memfokuskan pada bentuk 2D, tetapi anda juga dapat menarik elemen 3D ke laman web; untuk ini, anda mungkin menggunakan [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API). +✅ Canvas API kebanyakannya memfokuskan pada bentuk 2D, tetapi anda juga dapat menarik elemen 3D ke laman web; untuk ini, anda mungkin menggunakan [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API). Anda boleh menarik pelbagai perkara dengan Canvas API seperti: @@ -201,7 +201,7 @@ Cuba selesaikannya sendiri terlebih dahulu tetapi jika anda buntu, lihatlah [sol ## 🚀 Cabaran -Anda telah belajar melukis dengan Canvas API 2D; lihatlah [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), dan cuba lukis objek 3D. +Anda telah belajar melukis dengan Canvas API 2D; lihatlah [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API), dan cuba lukis objek 3D. ## Kuiz Pasca Kuliah @@ -209,7 +209,7 @@ Anda telah belajar melukis dengan Canvas API 2D; lihatlah [WebGL API](https://de ## Mengkaji & Belajar Sendiri -Ketahui lebih lanjut mengenai Canvas API dengan [membaca mengenainya](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API). +Ketahui lebih lanjut mengenai Canvas API dengan [membaca mengenainya](https://developer.mozilla.org/docs/Web/API/Canvas_API). ## Tugasan diff --git a/6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md b/6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md new file mode 100644 index 00000000..f27dc7e2 --- /dev/null +++ b/6-space-game/2-drawing-to-canvas/translations/README.zh-tw.md @@ -0,0 +1,216 @@ +# 建立太空遊戲 Part 2:在畫布上繪製英雄與怪物 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/31?loc=zh_tw) + +## Canvas + +Canvas 是 HTML 中的元素,預設上不帶有任何內容,就如一塊白板。你需要自己彩繪上去。 + +✅ 在 MDN 上閱讀[更多關於 Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)。 + +這是它典型的宣告方式,位在頁面的 body 中: + +```html +<canvas id="myCanvas" width="200" height="100"></canvas> +``` + +上面我們設定了 `id`、`width` 和 `height`。 + +- `id`:讓你在處理物件時,能快速地取得參考位置。 +- `width`:物件的寬度。 +- `height`:物件的高度。 + +## 繪製簡單幾何圖樣 + +Canvas 使用了笛卡爾座標系繪製圖案。因此有 x 軸與 y 軸來表達物件的所在地點。座標點 `0,0` 位在畫布的左上方;而右下方則是我們定義畫布的寬度與高度。 + + +> 圖片出自於 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) + +要在 Canvas 物件上繪製圖案,你需要執行下列步驟: + +1. **取得 Canvas 物件的參考位置**。 +1. **取得 Context 物件的參考位置**,定義在 Canvas 元素中。 +1. 使用 context 元素**進行繪製動作**。 + +以程式碼表達上述步驟會呈現成: + +```javascript +// 繪製紅色矩形 +//1. 取得 canvas 參考點 +canvas = document.getElementById("myCanvas"); + +//2. 設定 context 為 2D 以繪製基本圖形 +ctx = canvas.getContext("2d"); + +//3. 填入色彩紅色 +ctx.fillStyle = 'red'; + +//4. 利用這些參數決定位置與大小,繪製矩形 +ctx.fillRect(0,0, 200, 200) // x,y,width, height +``` + +✅ Canvas API 主要是處理 2D 圖形,但你也可以在網頁中繪製 3D 圖形。要完成這個需求,你可以使用 [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)。 + +你可以使用 Canvas API 繪製出這些物件: + +- **幾何圖形**,我們已經展示繪製矩形的流程,還有許多種形狀可以使用。 +- **文字**,你可以繪製文字,決定你想要的字型及顏色。 +- **圖片**,你可以依據圖片檔繪製圖案,舉例來說像是 .jpg 或是 .png 檔。 + +✅ 試試看!你知道如何繪製矩形,你能在頁面中繪製圓形嗎?看看在 CodePen 上有趣的 Canvas 塗鴉。這邊有一樣[特別令人驚豔的例子](https://codepen.io/dissimulate/pen/KrAwx)。 + +## 讀取並繪製圖片檔 + +建立 `Image` 物件並設定其 `src` 屬性,你可以讀取圖片檔。接著監聽 `load` 事件,了解圖片何時已經可以被使用。程式碼如下: + +### 讀取檔案 + +```javascript +const img = new Image(); +img.src = 'path/to/my/image.png'; +img.onload = () => { + // 圖片載入完成,準備使用 +} +``` + +### 讀取檔案之模式 + +建議上可以將上述程式打包起來,建立成完整的結構,判斷圖片是否載入完成,也方便未來的使用: + +```javascript +function loadAsset(path) { + return new Promise((resolve) => { + const img = new Image(); + img.src = path; + img.onload = () => { + // 圖片載入完成,準備使用 + resolve(img); + } + }) +} + +// 實際用法 + +async function run() { + const heroImg = await loadAsset('hero.png') + const monsterImg = await loadAsset('monster.png') +} + +``` + +要在畫面上繪製遊戲物件,你的程式碼會如下所示: + +```javascript +async function run() { + const heroImg = await loadAsset('hero.png') + const monsterImg = await loadAsset('monster.png') + + canvas = document.getElementById("myCanvas"); + ctx = canvas.getContext("2d"); + ctx.drawImage(heroImg, canvas.width/2,canvas.height/2); + ctx.drawImage(monsterImg, 0,0); +} +``` + +## 是時候來建立你的遊戲了 + +### 建立目標 + +你需要建立包含 Canvas 元素的網頁。它會是 `1024*768` 的黑色畫面。我們提供了兩張圖片: + +- 英雄艦艇 + +  + +- 5*5 隻怪物 + +  + +### 開始開發的建議步驟 + +在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括: + +```bash +-| assets + -| enemyShip.png + -| player.png +-| index.html +-| app.js +-| package.json +``` + +在 Visual Studio Code 中開啟這個資料夾的副本。你需要建立本地端的開發環境,建議為 Visual Studio Code 與安裝好的 NPM 與 Node。如果你的電腦中還沒設定好 `npm`,[這是它的設定流程]](https://www.npmjs.com/get-npm)。 + +前往 `your_work` 資料夾,開始你的專案: + +```bash +cd your-work +npm start +``` + +這會啟動 HTTP 伺服器,網址為 `http://localhost:5000`。開啟瀏覽器並輸入該網址。目前會是空白的頁面,但不久後就會不一樣了。 + +> 筆記:想觀察畫面的改變,請重新整理你的頁面。 + +### 加入程式碼 + +在 `your-work/app.js` 中加入程式碼以解決下列目標: + +1. 在 Canvas **繪製**黑色背景 + > 要點:在 `/app.js` 中,加入兩行程式在 TODO 下方:設定 `ctx` 元素為黑色,左上方座標點為 0,0 且大小與 Canvas 相等。 +2. **讀取**材質 + > 要點:使用 `await loadTexture` 導入圖片位置以新增玩家與敵軍圖片。你還沒辦法在畫面上看到它們! +3. 在畫面的正下方**繪製**英雄 + > 要點:使用 `drawImage` API 來繪製 heroImg 到畫面上,設定位置為 `canvas.width / 2 - 45` 與 `canvas.height - canvas.height / 4)`。 +4. **繪製** 5*5 隻怪物 + > 要點:現在移除註解,在畫面上繪製敵人。接著編輯函式 `createEnemies`。 + + 首先,設定幾個常數: + + ```javascript + const MONSTER_TOTAL = 5; + const MONSTER_WIDTH = MONSTER_TOTAL * 98; + const START_X = (canvas.width - MONSTER_WIDTH) / 2; + const STOP_X = START_X + MONSTER_WIDTH; + ``` + + 接著,利用迴圈在畫面上繪製矩陣型態的怪物: + + ```javascript + for (let x = START_X; x < STOP_X; x += 98) { + for (let y = 0; y < 50 * 5; y += 50) { + ctx.drawImage(enemyImg, x, y); + } + } + ``` + +## 結果 + +完成後的成果應該如下所示: + + + +## 解答 + +試著自己先完成程式碼,但如果你遭遇到困難,請參考[解答](../solution/app.js)。 + +--- + +## 🚀 挑戰 + +你已經學會繪製 2D 圖形的 Canvas API。看看 [WebGL API](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API),試著繪製 3D 物件。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/32?loc=zh_tw) + +## 複習與自學 + +[閱讀更多資料](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API),學習更多有關 Canvas API 的用法。 + +## 作業 + +[把玩 Canvas API](assignment.zh-tw.md) \ No newline at end of file diff --git a/6-space-game/2-drawing-to-canvas/translations/assignment.nl.md b/6-space-game/2-drawing-to-canvas/translations/assignment.nl.md new file mode 100644 index 00000000..3d9d9e0a --- /dev/null +++ b/6-space-game/2-drawing-to-canvas/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Speel met de Canvas API + +## Instructies + +Kies een element van de Canvas API en maak er iets interessants omheen. Kunt u een kleine melkweg van herhaalde sterren creëren? Kunt u een interessante textuur van gekleurde lijnen maken? U kunt CodePen bekijken voor inspiratie (maar kopieer niet) + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | --------------------------------------------------------- | ----------------------------------- | --------------------- | +| | Code wordt ingediend met een interessante textuur of vorm| Code is ingediend, maar wordt niet uitgevoerd | Code is niet verzonden | \ No newline at end of file diff --git a/6-space-game/2-drawing-to-canvas/translations/assignment.zh-tw.md b/6-space-game/2-drawing-to-canvas/translations/assignment.zh-tw.md new file mode 100644 index 00000000..28b5308f --- /dev/null +++ b/6-space-game/2-drawing-to-canvas/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 把玩 Canvas API + +## 簡介 + +挑選一款 Canvas API 上的元素,為它建立一些有趣的設定。你能利用重複的星星建立銀河嗎?你能建立有特殊材質的線條嗎?你可以觀察 CodePen 上的範本激發想法,但請不要抄襲。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------- | ---------------------------- | ------------ | +| | 程式碼呈現有趣的材質與圖案 | 有提交程式碼,但無法正常執行 | 未提交程式碼 | diff --git a/6-space-game/3-moving-elements-around/translations/README.zh-tw.md b/6-space-game/3-moving-elements-around/translations/README.zh-tw.md new file mode 100644 index 00000000..5999a49e --- /dev/null +++ b/6-space-game/3-moving-elements-around/translations/README.zh-tw.md @@ -0,0 +1,388 @@ +# 建立太空遊戲 Part 3:加入動作 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/33?loc=zh_tw) + +有外星人在移動的遊戲才會好玩!在這款遊戲中,我們會建立兩種移動模式: + +- **鍵盤滑鼠的移動**:當使用者控制鍵盤或滑鼠時,能移動畫面上的物件。 +- **遊戲內建的移動**:遊戲能自動地在一定時間內,移動其中的物件。 + +那我們該如何移動畫面上的物件呢?這都取決於笛卡爾座標系:我們改變物件的座標 (x,y),並在畫面上重新繪製出來。 + +通常你需要下列流程來*移動*畫面上的物件: + +1. **設定物件的新地點**,你才能察覺到物件有所移動。 +2. **清除畫面**,每一次的繪製間都需要將畫面清除乾淨。我們可以繪製一張背景色的矩形來覆蓋畫面。 +3. **在新地點重新繪製物件**,我們就能移動物件,從 A 點移動到 B 點。 + +合理的程式碼如下所示: + +```javascript +// 設定英雄位置 +hero.x += 5; +// 利用矩形清除英雄 +ctx.clearRect(0, 0, canvas.width, canvas.height); +// 重新繪製背景與英雄 +ctx.fillRect(0, 0, canvas.width, canvas.height) +ctx.fillStyle = "black"; +ctx.drawImage(heroImg, hero.x, hero.y); +``` + +✅ 你能了解為什麼在同一秒內多次重新繪製英雄會影響效能的原因嗎?閱讀[其他種同目的之設計模式](https://www.html5rocks.com/en/tutorials/canvas/performance/)。 + +## 處理鍵盤事件 + +連接特定事件到程式中,你就能處理遊戲事件。鍵盤事件可以在視窗被選擇時觸發,而滑鼠事件如 `click`,則要點擊特定的物件。我們會在這個專案中,使用鍵盤物件。 + +要處理一種事件,需要使用視窗的 `addEventListener()` 方法,並提供給它兩個參數。第一個參數是事件的名稱,例如: `keyup`。第二個參數是回應事件結果的被呼叫函式。 + +下列是一種例子: + +```javascript +window.addEventListener('keyup', (evt) => { + // `evt.key` = 按鍵字串 + if (evt.key === 'ArrowUp') { + // 做某事 + } +}) +``` + +鍵盤事件有兩個屬性來判別被按壓的按鍵: + +- `key`,使用字串名稱表達該按鍵,例如: `ArrowUp`。 +- `keyCode`,使用數字呈現,例如 `37` 會對應到 `ArrowLeft`。 + +✅ 除了遊戲開發以外,鍵盤事件也是十分實用的功能。你能想到其他使用相同技術的應用嗎? + +### 特殊按鍵之限制 + +有許多*特殊*按鍵會影響視窗。這代表若我們正監聽著 `keyup` 事件,這個按鍵同時也會執行視窗的滾動行為。某些時候你會需要*關閉*這些瀏覽器中預設的行為,好比是建立這款遊戲時。你需要下列的程式: + +```javascript +let onKeyDown = function (e) { + console.log(e.keyCode); + switch (e.keyCode) { + case 37: + case 39: + case 38: + case 40: // 方向鍵 + case 32: + e.preventDefault(); + break; // 空白鍵 + default: + break; // 不阻止其他按鍵 + } +}; + +window.addEventListener('keydown', onKeyDown); +``` + +上述的程式碼能確保方向鍵與空白鍵關閉*預設*的行為。這個*關閉*機制會在我們呼叫 `e.preventDefault()` 時觸發。 + +## 遊戲內建的移動 + +我們可以讓物件自己移動,利用計時器如 `setTimeout()` 或是 `setInterval()` 這兩個函式,隨著秒數間隔更新物件的位置。如下方呈現: + +```javascript +let id = setInterval(() => { + // 在 y 軸上移動敵人 + enemy.y += 10; +}) +``` + +## 遊戲迴圈 + +遊戲迴圈是個重要概念,定期地呼叫必須執行的函式。之所以被稱作遊戲迴圈也是基於所有東西會在一個迴圈中呈現給玩家。遊戲迴圈會利用到所有的遊戲物件,並依據各個情況與理由決定是否要繪製出它們。舉例來說,當一個敵人被雷射擊中,爆炸了。他就不應該存在於現在的遊戲迴圈中。你會在後續的課程學到更多此概念。 + +這是一個遊戲迴圈的基本格式,以程式碼表達如下: + +```javascript +let gameLoopId = setInterval(() => + function gameLoop() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + drawHero(); + drawEnemies(); + drawStaticObjects(); +}, 200); +``` + +上述的迴圈會每 `200` 毫秒重新繪製 Canvas。你能自由地判斷哪種時長更適合套用在你的遊戲中。 + +## 繼續我們的太空遊戲 + +你會利用現有的程式碼來擴增我們的專案。你可以使用你在 Part I 完成的程式,或是使用 [Part II - Starter](../your-work) 這包程式。 + +- **移動英雄**:你需要加入程式,確保你可以使用方向鍵來移動主角。 +- **移動敵人**:你也需要加入程式,確保敵人能定期地由上往下移動。 + +## 建議步驟 + +在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括: + +```bash +-| assets + -| enemyShip.png + -| player.png +-| index.html +-| app.js +-| package.json +``` + +開始 `your_work` 資料夾中的專案,輸入: + +```bash +cd your-work +npm start +``` + +這會啟動 HTTP 伺服器並發布網址 `http://localhost:5000`。開啟瀏覽器並輸入該網址,現在它能呈現英雄以及所有的敵人,但它們還沒辦法移動! + +### 加入程式碼 + +1. **加入特定物件** `hero`、`enemy` 和 `game object`,它們皆有 `x` 與 `y` 位置屬性。(記得課程[繼承與組合](../../README.zh-tw.md)中的片段)。 + + *提示* `game object` 要有 `x` 和 `y`,以及繪製到畫布上的能力。 + + >要點:開始建立 GameObject class ,結構如下所示,再繪製到畫布上: + + ```javascript + + class GameObject { + constructor(x, y) { + this.x = x; + this.y = y; + this.dead = false; + this.type = ""; + this.width = 0; + this.height = 0; + this.img = undefined; + } + + draw(ctx) { + ctx.drawImage(this.img, this.x, this.y, this.width, this.height); + } + } + ``` + + 現在,延伸 GameObject 來建立英雄與敵人。 + + ```javascript + class Hero extends GameObject { + constructor(x, y) { + ...it needs an x, y, type, and speed + } + } + ``` + + ```javascript + class Enemy extends GameObject { + constructor(x, y) { + super(x, y); + (this.width = 98), (this.height = 50); + this.type = "Enemy"; + let id = setInterval(() => { + if (this.y < canvas.height - this.height) { + this.y += 5; + } else { + console.log('Stopped at', this.y) + clearInterval(id); + } + }, 300) + } + } + ``` + +2. **加入鍵盤事件處理器**以處理鍵盤輸入(移動英雄的上下左右) + + *記住* 這是笛卡爾座標系,左上方為 `0,0`。也請記得關閉鍵盤的*預設行為* + + >要點:建立函式 onKeyDown 並連接到視窗中: + + ```javascript + let onKeyDown = function (e) { + console.log(e.keyCode); + ...add the code from the lesson above to stop default behavior + } + }; + + window.addEventListener("keydown", onKeyDown); + ``` + + 這時候檢查你的瀏覽器命令欄,看看是否能偵測到鍵盤輸入。 + +3. **建立**[發布訂閱模式](../../README.zh-tw.md),這能讓剩下的程式段落保持乾淨。 + + 要做到此步驟,你可以: + + 1. **建立視窗的事件監聽者**: + + ```javascript + window.addEventListener("keyup", (evt) => { + if (evt.key === "ArrowUp") { + eventEmitter.emit(Messages.KEY_EVENT_UP); + } else if (evt.key === "ArrowDown") { + eventEmitter.emit(Messages.KEY_EVENT_DOWN); + } else if (evt.key === "ArrowLeft") { + eventEmitter.emit(Messages.KEY_EVENT_LEFT); + } else if (evt.key === "ArrowRight") { + eventEmitter.emit(Messages.KEY_EVENT_RIGHT); + } + }); + ``` + + 1. **建立 EventEmitter class** 以發布及訂閱訊息: + + ```javascript + class EventEmitter { + constructor() { + this.listeners = {}; + } + + on(message, listener) { + if (!this.listeners[message]) { + this.listeners[message] = []; + } + this.listeners[message].push(listener); + } + + emit(message, payload = null) { + if (this.listeners[message]) { + this.listeners[message].forEach((l) => l(message, payload)); + } + } + } + ``` + + 1. **建立常數**並設定 EventEmitter: + + ```javascript + const Messages = { + KEY_EVENT_UP: "KEY_EVENT_UP", + KEY_EVENT_DOWN: "KEY_EVENT_DOWN", + KEY_EVENT_LEFT: "KEY_EVENT_LEFT", + KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT", + }; + + let heroImg, + enemyImg, + laserImg, + canvas, ctx, + gameObjects = [], + hero, + eventEmitter = new EventEmitter(); + ``` + + 1. **初始化遊戲** + + ```javascript + function initGame() { + gameObjects = []; + createEnemies(); + createHero(); + + eventEmitter.on(Messages.KEY_EVENT_UP, () => { + hero.y -=5 ; + }) + + eventEmitter.on(Messages.KEY_EVENT_DOWN, () => { + hero.y += 5; + }); + + eventEmitter.on(Messages.KEY_EVENT_LEFT, () => { + hero.x -= 5; + }); + + eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => { + hero.x += 5; + }); + } + ``` + +1. **設定遊戲迴圈** + + 重構函式 window.onload 來初始化遊戲,設定遊戲迴圈的定時間隔。你還需要加入雷射光: + + ```javascript + window.onload = async () => { + canvas = document.getElementById("canvas"); + ctx = canvas.getContext("2d"); + heroImg = await loadTexture("assets/player.png"); + enemyImg = await loadTexture("assets/enemyShip.png"); + laserImg = await loadTexture("assets/laserRed.png"); + + initGame(); + let gameLoopId = setInterval(() => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + drawGameObjects(ctx); + }, 100) + + }; + ``` + +5. **加入程式**來定期地移動敵人 + + 重構函式 `createEnemies()` 以建立敵人們,接到 gameObjects 中: + + ```javascript + function createEnemies() { + const MONSTER_TOTAL = 5; + const MONSTER_WIDTH = MONSTER_TOTAL * 98; + const START_X = (canvas.width - MONSTER_WIDTH) / 2; + const STOP_X = START_X + MONSTER_WIDTH; + + for (let x = START_X; x < STOP_X; x += 98) { + for (let y = 0; y < 50 * 5; y += 50) { + const enemy = new Enemy(x, y); + enemy.img = enemyImg; + gameObjects.push(enemy); + } + } + } + ``` + + 新增函式 `createHero()` 來為英雄做相同的事情。 + + ```javascript + function createHero() { + hero = new Hero( + canvas.width / 2 - 45, + canvas.height - canvas.height / 4 + ); + hero.img = heroImg; + gameObjects.push(hero); + } + ``` + + 最後,建立函式 `drawGameObjects()` 以開始繪製: + + ```javascript + function drawGameObjects(ctx) { + gameObjects.forEach(go => go.draw(ctx)); + } + ``` + + 你的敵人開始會朝你的英雄艦艇前進! + +--- + +## 🚀 挑戰 + +如你所見,在加入零零總總的函式、變數與 class 後,你的程式變成了「麵條式代碼(spaghetti code)」。你能有效的編排你的程式,讓它更容易被閱讀?勾劃出一個系統來組織你的程式碼,即使所有東西都在一個檔案中。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/34?loc=zh_tw) + +## 複習與自學 + +我們並沒有使用框架(frameworks)來編寫我們的遊戲,現在有許多 JavaScript 基底的 Canvas 框架,提供給遊戲開發使用。花點時間[閱讀這些框架](https://github.com/collections/javascript-game-engines)。 + +## 作業 + +[為你的程式做註解](assignment.zh-tw.md) diff --git a/6-space-game/3-moving-elements-around/translations/assignment.nl.md b/6-space-game/3-moving-elements-around/translations/assignment.nl.md new file mode 100644 index 00000000..3ec64f30 --- /dev/null +++ b/6-space-game/3-moving-elements-around/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Becommentarieer uw code + +## Instructies + +Bekijk uw huidige /app.js-bestand in uw gamemap en zoek manieren om er commentaar op te geven en het op te ruimen. Het is heel gemakkelijk dat code uit de hand loopt, en dit is een goede kans om opmerkingen toe te voegen om ervoor te zorgen dat u leesbare code heeft, zodat u deze later kunt gebruiken. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------------------------------------------------ | ------------------------------------- | -------------------------------------------------------------- | +| | `app.js` code is volledig becommentarieerd en georganiseerd in logische blokken | `app.js` code is voldoende becommentarieerd | De code `app.js` is enigszins ongeorganiseerd en er ontbreken goede commentaren | \ No newline at end of file diff --git a/6-space-game/3-moving-elements-around/translations/assignment.zh-tw.md b/6-space-game/3-moving-elements-around/translations/assignment.zh-tw.md new file mode 100644 index 00000000..06add13e --- /dev/null +++ b/6-space-game/3-moving-elements-around/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 為你的程式做註解 + +## 簡介 + +打開遊戲資料夾中目前的 /app.js 檔案,試著幫它做上註解並整理乾淨。程式碼很容易脫離掌控,現在是個好機會來確保你的程式是容易去閱讀的,在未來還可以被使用。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ----------------------------- | ----------------------- | ----------------------- | +| | `app.js` 完整地註解且分塊整理 | `app.js` 有做充分的註解 | `app.js` 凌亂且缺乏註解 | \ No newline at end of file diff --git a/6-space-game/4-collision-detection/assignment.md b/6-space-game/4-collision-detection/assignment.md index a8d6b383..1c3ea3a7 100644 --- a/6-space-game/4-collision-detection/assignment.md +++ b/6-space-game/4-collision-detection/assignment.md @@ -2,10 +2,10 @@ ## Instructions -## Rubric - To better understand how collisions work, build a very small game with a few items that collide. Make them move via keypresses or mouse clicks, and make something happen to one of the items when it is hit. It could be something like a meteor hitting the earth, or bumper-cars. Get creative! +## Rubric + | Criteria | Exemplary | Adequate | Needs Improvement | | -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------- | | | Complete working code sample is produced, with items drawn to canvas, basic collision happening, and reactions occurring | Code is incomplete in some way | Code malfunctions | \ No newline at end of file diff --git a/6-space-game/4-collision-detection/translations/README.zh-tw.md b/6-space-game/4-collision-detection/translations/README.zh-tw.md new file mode 100644 index 00000000..08da0d66 --- /dev/null +++ b/6-space-game/4-collision-detection/translations/README.zh-tw.md @@ -0,0 +1,297 @@ +# 建立太空遊戲 Part 4:加入雷射與碰撞偵測 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/35?loc=zh_tw) + +這堂課中,你會學會如何在 JavaScript 上發射雷射光!我們需要在遊戲中新增兩項東西: + +- **雷射光**:這束雷射會從英雄艦艇垂直往上移動 +- **碰撞偵測**,除了完成*射擊*這項能力,我們還會新增幾項遊戲規則: + - **雷射擊中敵人**:被雷射擊中的敵人會死亡 + - **雷射擊中畫面最上方**:雷射擊中到畫面最上方會消失 + - **敵人碰觸到英雄**:敵人與英雄在互相碰觸時皆會被摧毀 + - **敵人碰觸到畫面最下方**:敵人碰觸到畫面最下方時,該敵人與英雄會被摧毀 + +簡單來說,你這位*英雄*需要在敵人到達畫面最下方之前,使用雷射擊毀它們。 + +✅ 做點關於第一款電腦遊戲的研究。它有哪些功能? + +讓我們成為英雄吧! + +## 碰撞偵測 + +我們該如何進行碰撞偵測呢?我們需要將遊戲物件視為移動中的矩形。你或許會問為什麼?這是因為,繪製遊戲物件的圖片皆為矩形:它有一組 `x` 與 `y`、`width` 與 `height`。 + +若兩個矩形,舉例來說:英雄與敵人*相交*了,這就是一次碰撞。至於會發生什麼事取決於遊戲規則。要製作碰撞偵測,你需要這些步驟: + +1. 取得表達遊戲物件為矩形的方法,好比是: + + ```javascript + rectFromGameObject() { + return { + top: this.y, + left: this.x, + bottom: this.y + this.height, + right: this.x + this.width + } + } + ``` + +2. 一個比較函式,這個函式可以如下: + + ```javascript + function intersectRect(r1, r2) { + return !(r2.left > r1.right || + r2.right < r1.left || + r2.top > r1.bottom || + r2.bottom < r1.top); + } + ``` + +## 我們該如何摧毀物件 + +要摧毀遊戲物件,你需要讓遊戲知道,它不再需要在定期的遊戲迴圈中繪製該物件。一種方法是在情況發生時,我們可以標記遊戲物件為*死亡*,例如: + +```javascript +// 碰撞發生 +enemy.dead = true +``` + +接著,你在重新繪製畫面前,排除掉這些*死亡*的物件,例如: + +```javascript +gameObjects = gameObject.filter(go => !go.dead); +``` + +## 我們該如何發射雷射 + +發射雷射可以被視作回應一件鍵盤事件,並建立往特定方向移動的物件。因此我們需要列出下列步驟: + +1. **建立雷射物件**:從英雄艦艇的正上方,建立往畫面上方移動的物件。 +2. **連接該程式到鍵盤事件**:我們需要在鍵盤中挑選一個按鍵,表達玩家發射雷射光。 +3. 在按鍵按壓時,**建立看起來像雷射光的遊戲物件**。 + +## 雷射的冷卻時間 + +在每次按壓按鍵時,好比說*空白鍵*,雷射光都需要被發射出來。為了讓遊戲不要在短時間內發射太多組雷射光,我們需要修正它。修法為建立*冷卻時間* ── 一個計時器確保雷射在一定期間內只能被發射一次。你可以藉由下列方式建立: + +```javascript +class Cooldown { + constructor(time) { + this.cool = false; + setTimeout(() => { + this.cool = true; + }, time) + } +} + +class Weapon { + constructor { + } + fire() { + if (!this.cooldown || this.cooldown.cool) { + // 產生雷射光 + this.cooldown = new Cooldown(500); + } else { + // 什麼事都不做,冷卻中。 + } + } +} +``` + +✅ 根據太空遊戲系列課程的第一章,回想關於*冷卻時間*。 + +## 建立目標 + +你會利用上一堂課中現成的程式碼(你應該有整理並重構過)做延伸。使用來自 Part II 的檔案或是使用 [Part III - Starter](../your-work)。 + +> 要點:你需要使用的雷射光已經在資料夾中,並已匯入到程式碼中。 + +- **加入碰撞偵測**,建立下列規則給各個雷射碰觸到東西的情況: + 1. **雷射擊中敵人**:被雷射擊中的敵人會死亡 + 2. **雷射擊中畫面最上方**:雷射擊中到畫面最上方會消失 + 3. **敵人碰觸到英雄**:敵人與英雄在互相碰觸時皆會被摧毀 + 4. **敵人碰觸到畫面最下方**:敵人碰觸到畫面最下方時,該敵人與英雄會被摧毀 + +## 建議步驟 + +在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括: + +```bash +-| assets + -| enemyShip.png + -| player.png + -| laserRed.png +-| index.html +-| app.js +-| package.json +``` + +開始 `your_work` 資料夾中的專案,輸入: + +```bash +cd your-work +npm start +``` + +這會啟動 HTTP 伺服器並發布網址 `http://localhost:5000`。開啟瀏覽器並輸入該網址,現在它能呈現英雄以及所有的敵人,但它們還沒辦法移動! + +### 建立程式碼 + +1. **設定表達遊戲物件為矩形的方法,以處理碰撞狀況** 下列的程式表達 `GameObject` 的矩形呈現方式。編輯你的 GameObject class: + + ```javascript + rectFromGameObject() { + return { + top: this.y, + left: this.x, + bottom: this.y + this.height, + right: this.x + this.width, + }; + } + ``` + +2. **加入程式碼來檢查碰撞** 這會是新函式來測試兩矩形是否相交: + + ```javascript + function intersectRect(r1, r2) { + return !( + r2.left > r1.right || + r2.right < r1.left || + r2.top > r1.bottom || + r2.bottom < r1.top + ); + } + ``` + +3. **加入雷射發射功能** + 1. **加入鍵盤事件訊息**。 *空白鍵*要能在英雄艦艇上方建立雷射光。加入三個常數到 Messages 物件中: + + ```javascript + KEY_EVENT_SPACE: "KEY_EVENT_SPACE", + COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", + COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO", + ``` + + 1. **處理空白鍵**。 編輯 `window.addEventListener` 的 keyup 函式來處理空白鍵: + + ```javascript + } else if(evt.keyCode === 32) { + eventEmitter.emit(Messages.KEY_EVENT_SPACE); + } + ``` + + 1. **加入監聽者**。 編輯函式 `initGame()` 來確保英雄可以在空白鍵按壓時,發射雷射光: + + ```javascript + eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { + if (hero.canFire()) { + hero.fire(); + } + ``` + + 建立新的函式 `eventEmitter.on()` 確保敵人碰觸到雷射光時,能更新死亡狀態: + + ```javascript + eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { + first.dead = true; + second.dead = true; + }) + ``` + + 1. **移動物件**。 確保雷射逐步地向畫面上方移動。建立新的 class Laser 延伸自 `GameObject`,你應該有做過: + + ```javascript + class Laser extends GameObject { + constructor(x, y) { + super(x,y); + (this.width = 9), (this.height = 33); + this.type = 'Laser'; + this.img = laserImg; + let id = setInterval(() => { + if (this.y > 0) { + this.y -= 15; + } else { + this.dead = true; + clearInterval(id); + } + }, 100) + } + } + ``` + + 1. **處理碰撞**。 建立雷射的碰撞規則。加入函式 `updateGameObjects()` 來確認被碰撞的物件。 + + ```javascript + function updateGameObjects() { + const enemies = gameObjects.filter(go => go.type === 'Enemy'); + const lasers = gameObjects.filter((go) => go.type === "Laser"); + // 雷射擊中某物 + lasers.forEach((l) => { + enemies.forEach((m) => { + if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) { + eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, { + first: l, + second: m, + }); + } + }); + }); + + gameObjects = gameObjects.filter(go => !go.dead); + } + ``` + + 記得在 `window.onload` 裡的遊戲迴圈中加入 `updateGameObjects()`。 + + 4. **設定雷射的冷卻時間**,它只能在定期內發射一次。 + + 最後,編輯 Hero class 來允許冷卻: + + ```javascript + class Hero extends GameObject { + constructor(x, y) { + super(x, y); + (this.width = 99), (this.height = 75); + this.type = "Hero"; + this.speed = { x: 0, y: 0 }; + this.cooldown = 0; + } + fire() { + gameObjects.push(new Laser(this.x + 45, this.y - 10)); + this.cooldown = 500; + + let id = setInterval(() => { + if (this.cooldown > 0) { + this.cooldown -= 100; + } else { + clearInterval(id); + } + }, 200); + } + canFire() { + return this.cooldown === 0; + } + } + ``` + +到這裡,你的遊戲有了些功能!你可以測試方向鍵,使用空白鍵發射雷射。當你擊中敵人時它們會消失。幹得漂亮! + +--- + +## 🚀 挑戰 + +加入爆炸特效! 看看 [Space Art Repo](../solution/spaceArt/readme.txt) 中的檔案,試著在雷射擊中外星人時,加入爆炸畫面。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/36?loc=zh_tw) + +## 複習與自學 + +對遊戲中的迴圈定時做點實驗。當你改變數值時,發生了什麼事?閱讀更多關於 [JavaScript 計時事件](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/)。 + +## 作業 + +[探索碰撞](assignment.zh-tw.md) diff --git a/6-space-game/4-collision-detection/translations/assignment.es.md b/6-space-game/4-collision-detection/translations/assignment.es.md index 68616307..8e3f8ed4 100644 --- a/6-space-game/4-collision-detection/translations/assignment.es.md +++ b/6-space-game/4-collision-detection/translations/assignment.es.md @@ -2,10 +2,10 @@ ## Instrucciones -## Rúbrica - Para comprender mejor cómo funcionan las colisiones, cree un juego muy pequeño con algunos elementos que chocan. Haz que se muevan presionando las teclas o haciendo clic con el mouse, y haz que algo le suceda a uno de los elementos cuando se golpea. Podría ser algo como un meteoro golpeando la tierra o autos chocadores. ¡Se creativo! +## Rúbrica + | Criterios | Ejemplar | Adecuado | Necesita mejorar | | -------- | -------------------------------------------------- -------------------------------------------------- -------------------- | ------------------------------ | ----------------- | | | Se produce una muestra de código de trabajo completa, con elementos dibujados en el lienzo, ocurriendo una colisión básica y ocurriendo reacciones | El código está incompleto de alguna manera | Fallos del código | diff --git a/6-space-game/4-collision-detection/translations/assignment.hi.md b/6-space-game/4-collision-detection/translations/assignment.hi.md index 1f25cffa..d03a8ee8 100644 --- a/6-space-game/4-collision-detection/translations/assignment.hi.md +++ b/6-space-game/4-collision-detection/translations/assignment.hi.md @@ -2,10 +2,10 @@ ## अनुदेश -## शीर्ष - बेहतर ढंग से समझने के लिए कि टकराव कैसे काम करता है, कुछ वस्तुओं के साथ बहुत छोटे खेल का निर्माण करें जो टकराते हैं. उन्हें कीप्रेसेस या माउस क्लिक के माध्यम से ले जाएँ, और यह हिट होने पर आइटम में से किसी एक के साथ कुछ करें . यह कुछ ऐसा हो सकता है जैसे उल्का पिंड पृथ्वी से टकराता है, या बम्पर-कार। रचनात्मक बनो! +## शीर्ष + | मानदंड | उदाहरणात्मक | पर्याप्त | सुधार की जरूरत | | ------ | --------------------------------------------------------------------------------------------------------------- | ------------------------ | -------------- | | | पूरा वर्किंग कोड सैंपल उत्पादित होता है, जिसमें कैनवस को खींची गई चीजें, बेसिक टक्कर, और प्रतिक्रियाएँ होती हैं | कोड किसी तरह से अधूरा है | कोड की खराबी | diff --git a/6-space-game/4-collision-detection/translations/assignment.ko.md b/6-space-game/4-collision-detection/translations/assignment.ko.md index 9ed9aee4..aa274c19 100644 --- a/6-space-game/4-collision-detection/translations/assignment.ko.md +++ b/6-space-game/4-collision-detection/translations/assignment.ko.md @@ -2,10 +2,10 @@ ## 설명 -## 평가 기준 - 충돌이 어떻게 작용하는지 더 잘 이해하기 위해 충돌하는 몇 가지 항목으로 아주 작은 게임을 만들어 봅시다. 키를 누르거나 마우스 클릭으로 이동하게 하고, 부딪혔을 때는 아이템들 중 하나에 무슨 일이 일어나게 해보세요. 부딪히는 것은 지구를 강타하는 유성이거나, 범퍼카 같은 것일 수도 있습니다. 창의력을 보여주세요! +## 평가 기준 + 기준 | 모범 답안 | 적당한 답안 | 개선이 필요한 답안 --- | --- | --- | --- | 항목을 캔버스에 끌어다 놓거나, 기본 충돌이 발생하고, 반응이 있는 샘플 코드를 만든 경우 | 코드가 일부 미완성인 경우 | 코드에 오류가 있는 경우 diff --git a/6-space-game/4-collision-detection/translations/assignment.ms.md b/6-space-game/4-collision-detection/translations/assignment.ms.md index a2485c4e..0a98525b 100644 --- a/6-space-game/4-collision-detection/translations/assignment.ms.md +++ b/6-space-game/4-collision-detection/translations/assignment.ms.md @@ -2,10 +2,10 @@ ## Arahan -## Rubrik - Untuk lebih memahami bagaimana perlanggaran berfungsi, bina permainan yang sangat kecil dengan beberapa item yang bertembung. Buat mereka bergerak melalui menekan kekunci atau klik tetikus, dan membuat sesuatu berlaku pada salah satu item ketika dipukul. Ini mungkin seperti meteor yang menghantam bumi, atau kereta bumper. Dapatkan kreatif! +## Rubrik + | Kriteria | Contoh | Mencukupi | Usaha Lagi | | -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------- | | | Sampel kod kerja lengkap dihasilkan, dengan item dilukis ke kanvas, perlanggaran asas berlaku, dan reaksi berlaku | Kod tidak lengkap dalam beberapa cara | Kod Tidak Berfungsi | \ No newline at end of file diff --git a/6-space-game/4-collision-detection/translations/assignment.nl.md b/6-space-game/4-collision-detection/translations/assignment.nl.md new file mode 100644 index 00000000..deb59616 --- /dev/null +++ b/6-space-game/4-collision-detection/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Ontdek botsingen + +## Instructies + +Om beter te begrijpen hoe botsingen werken, bouwt u een heel klein spel met een paar items die botsen. Laat ze bewegen door middel van toetsaanslagen of muisklikken, en zorg dat er iets gebeurt met een van de items wanneer deze wordt geraakt. Het kan zoiets zijn als een meteoor die de aarde raakt, of botsauto's. Wees creatief! + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden vebeterd | +| -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------- | +| | Er wordt een volledig werkend codevoorbeeld geproduceerd, met items op het canvas getekend, er vindt een fundamentele botsing plaats en er vinden reacties plaats | Code is op de een of andere manier onvolledig | Code storingen | \ No newline at end of file diff --git a/6-space-game/4-collision-detection/translations/assignment.zh-tw.md b/6-space-game/4-collision-detection/translations/assignment.zh-tw.md new file mode 100644 index 00000000..e0e8ad93 --- /dev/null +++ b/6-space-game/4-collision-detection/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 探索碰撞 + +## 簡介 + +為了更了解碰撞是如何運作的,建立一款小遊戲包含物件的碰撞。利用鍵盤或是滑鼠來移動物件,當物件碰撞時執行某些行為。它可以像是彗星撞地球,或是碰碰車。發揮你的創意! + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------------------------------------------- | ------------------ | ---------- | +| | 建立出完整的程式:有在畫面上繪製物件、有基本的碰撞與對應的行為 | 程式有部分尚未完成 | 程式有瑕疵 | diff --git a/6-space-game/5-keeping-score/README.md b/6-space-game/5-keeping-score/README.md index e4460b29..1350bf3e 100644 --- a/6-space-game/5-keeping-score/README.md +++ b/6-space-game/5-keeping-score/README.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ Read more about [how to add text to a canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text), and feel free to make yours look fancier! +✅ Read more about [how to add text to a canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), and feel free to make yours look fancier! ## Life, as a game concept diff --git a/6-space-game/5-keeping-score/translations/README.es.md b/6-space-game/5-keeping-score/translations/README.es.md index f9537510..44da53c7 100644 --- a/6-space-game/5-keeping-score/translations/README.es.md +++ b/6-space-game/5-keeping-score/translations/README.es.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ Lea más sobre [cómo agregar texto a un lienzo](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text), ¡y siéntase libre de hacer que el suyo se vea más elegante! +✅ Lea más sobre [cómo agregar texto a un lienzo](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), ¡y siéntase libre de hacer que el suyo se vea más elegante! ## La vida, como concepto de juego diff --git a/6-space-game/5-keeping-score/translations/README.hi.md b/6-space-game/5-keeping-score/translations/README.hi.md index 837c1369..2d38aa19 100644 --- a/6-space-game/5-keeping-score/translations/README.hi.md +++ b/6-space-game/5-keeping-score/translations/README.hi.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ [एक कैनवास में पाठ कैसे जोड़ें](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text) इसके बारे में और पढ़ें और बेझिझक अपने को आकर्षक बनाने के लिए! +✅ [एक कैनवास में पाठ कैसे जोड़ें](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) इसके बारे में और पढ़ें और बेझिझक अपने को आकर्षक बनाने के लिए! ## जीवन, एक खेल अवधारणा के रूप में diff --git a/6-space-game/5-keeping-score/translations/README.it.md b/6-space-game/5-keeping-score/translations/README.it.md index 616246e2..e34ec2f5 100644 --- a/6-space-game/5-keeping-score/translations/README.it.md +++ b/6-space-game/5-keeping-score/translations/README.it.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ Si legga di più su [come aggiungere testo a un oggetto canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text), ci si senta liberi di far sembrare il proprio più elaborato! +✅ Si legga di più su [come aggiungere testo a un oggetto canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), ci si senta liberi di far sembrare il proprio più elaborato! ## La vita, come concetto di gioco diff --git a/6-space-game/5-keeping-score/translations/README.ko.md b/6-space-game/5-keeping-score/translations/README.ko.md index 139b7672..2319fcf2 100644 --- a/6-space-game/5-keeping-score/translations/README.ko.md +++ b/6-space-game/5-keeping-score/translations/README.ko.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ [how to add text to a canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text)에 대하여 더 읽어보세요, 그리고 더 멋지게 보이도록 자유롭게 느껴보세요! +✅ [how to add text to a canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text)에 대하여 더 읽어보세요, 그리고 더 멋지게 보이도록 자유롭게 느껴보세요! ## 게임 컨셉에서 생명 diff --git a/6-space-game/5-keeping-score/translations/README.ms.md b/6-space-game/5-keeping-score/translations/README.ms.md index 40f225d2..01bbcc27 100644 --- a/6-space-game/5-keeping-score/translations/README.ms.md +++ b/6-space-game/5-keeping-score/translations/README.ms.md @@ -17,7 +17,7 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ Baca lebih lanjut mengenai [cara menambahkan teks ke kanvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text), dan jangan ragu untuk menjadikan teks anda kelihatan lebih menarik! +✅ Baca lebih lanjut mengenai [cara menambahkan teks ke kanvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), dan jangan ragu untuk menjadikan teks anda kelihatan lebih menarik! ## Hidup, sebagai konsep permainan diff --git a/6-space-game/5-keeping-score/translations/README.zh-tw.md b/6-space-game/5-keeping-score/translations/README.zh-tw.md new file mode 100644 index 00000000..9fb35637 --- /dev/null +++ b/6-space-game/5-keeping-score/translations/README.zh-tw.md @@ -0,0 +1,189 @@ +# 建立太空遊戲 Part 5:分數與生命數 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/37?loc=zh_tw) + +在這堂課中,你會學習如何為遊戲加入計分功能與計算性命數。 + +## 在畫面上繪製文字 + +為了在畫面上顯示遊戲分數,你需要了解如何配置文字。答案是在 Canvas 物件上使用方法 `fillText()`。你也可以控制其他特徵,例如文字字型、文字顏色甚至文字對齊方向(左、右、置中)。下面是在畫面中繪製一些文字。 + +```javascript +ctx.font = "30px Arial"; +ctx.fillStyle = "red"; +ctx.textAlign = "right"; +ctx.fillText("show this on the screen", 0, 0); +``` + +✅ 閱讀更多關於[在畫布上建立文字](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text),你可以自由地豐富你的文字! + +## 性命,一個遊戲概念 + +遊戲中的生命概念只是一個數字。在太空遊戲中,在你的船艦受到攻擊時,扣除生命值是一種常見的方式。如果能以圖像的方式顯示生命值也是很好的方式,例如船艦圖示、心臟圖像,而非單純使用數字。 + +## 建立目標 + +我們在遊戲中新增下列功能: + +- **遊戲分數**:當每一艘敵軍艦艇被摧毀時,英雄應該取得一些獎勵分數,我們建議一艘敵艦一百分。遊戲總分應該顯示在畫面的左下角。 +- **生命值**:你的船艦有三條性命。在每一次敵軍艦艇撞擊你時,你會損失一條性命。生命數應該顯示在畫面的右下角,以下列圖像顯示出來。  + +## 建議步驟 + +在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括: + +```bash +-| assets + -| enemyShip.png + -| player.png + -| laserRed.png +-| index.html +-| app.js +-| package.json +``` + +開始 `your_work` 資料夾中的專案,輸入: + +```bash +cd your-work +npm start +``` + +這會啟動 HTTP 伺服器並發布網址 `http://localhost:5000`。開啟瀏覽器並輸入該網址,現在它能顯示出英雄與所有的敵人,在你操作方向鍵後,英雄能移動並擊落敵人。 + +### 加入程式碼 + +1. 從資料夾 `solution/assets/` **複製你需要的檔案** 到資料夾 `your-work` 中。你會加入檔案 `life.png`。在函式 window.onload 中加入 lifeImg : + + ```javascript + lifeImg = await loadTexture("assets/life.png"); + ``` + +1. 在檔案清單中加入 `lifeImg`: + + ```javascript + let heroImg, + ... + lifeImg, + ... + eventEmitter = new EventEmitter(); + ``` + +2. **新增變數**。 加入程式碼表達你的遊戲總分(0)和剩餘性命(3),並顯示在畫面上。 + +3. **擴增函式 `updateGameObjects()`**。 擴增函式 `updateGameObjects()` 來處理敵軍碰撞: + + ```javascript + enemies.forEach(enemy => { + const heroRect = hero.rectFromGameObject(); + if (intersectRect(heroRect, enemy.rectFromGameObject())) { + eventEmitter.emit(Messages.COLLISION_ENEMY_HERO, { enemy }); + } + }) + ``` + +4. **加入 `life` 與 `points`**. + 1. **初始化變數**。 在 `Hero` class 的 `this.cooldown = 0` 下方,設定性命與分數: + + ```javascript + this.life = 3; + this.points = 0; + ``` + + 1. **在畫面上顯示變數內容**。 在畫面上繪製這些數值: + + ```javascript + function drawLife() { + // TODO, 35, 27 + const START_POS = canvas.width - 180; + for(let i=0; i < hero.life; i++ ) { + ctx.drawImage( + lifeImg, + START_POS + (45 * (i+1) ), + canvas.height - 37); + } + } + + function drawPoints() { + ctx.font = "30px Arial"; + ctx.fillStyle = "red"; + ctx.textAlign = "left"; + drawText("Points: " + hero.points, 10, canvas.height-20); + } + + function drawText(message, x, y) { + ctx.fillText(message, x, y); + } + + ``` + + 1. **在遊戲迴圈中加入呼叫**。 請確保你加入這些函式到 `updateGameObjects()` 下方的 window.onload 內: + + ```javascript + drawPoints(); + drawLife(); + ``` + +1. **制定遊戲規則**。 制定下列的遊戲規則: + + 1. **在英雄與敵人發生碰撞時**,扣除一條生命。 + + 擴增 `Hero` class 來執行這段減法: + + ```javascript + decrementLife() { + this.life--; + if (this.life === 0) { + this.dead = true; + } + } + ``` + + 2. **當雷射擊中敵人時**,增加遊戲總分一百分。 + + 擴增 Hero class 來執行這段加法: + + ```javascript + incrementPoints() { + this.points += 100; + } + ``` + + 加入這些函式到碰撞事件發送器中: + + ```javascript + eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { + first.dead = true; + second.dead = true; + hero.incrementPoints(); + }) + + eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { + enemy.dead = true; + hero.decrementLife(); + }); + ``` + +✅ 做點研究,探索其他使用到 JavaScript 與 Canvas 的遊戲。他們有什麼共同特徵? + +在這個工作的尾聲,你應該能在右下方看到「性命」小船;左下方看到遊戲總分。當你碰撞到敵人時會扣除生命;當你擊落敵人時會增加分數。做得好!你的遊戲就快完成了。 + +--- + +## 🚀 挑戰 + +你的程式就快完成了。你能預測到下一步嗎? + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/38?loc=zh_tw) + +## 複習與自學 + +研究其他種增加與減少分數與生命數的方法。這邊有一些有趣的遊戲引擎,例如:[PlayFab](https://playfab.com)。使用這些引擎能如何增進你的遊戲? + +## 作業 + +[建立計分遊戲](assignment.zh-tw.md) diff --git a/6-space-game/5-keeping-score/translations/assignment.nl.md b/6-space-game/5-keeping-score/translations/assignment.nl.md new file mode 100644 index 00000000..545f74fc --- /dev/null +++ b/6-space-game/5-keeping-score/translations/assignment.nl.md @@ -0,0 +1,11 @@ +# Bouw een scorespel + +## Instructies + +Creëer een spel waarin u leven en punten op een creatieve manier weergeeft. Een suggestie is om het leven te laten zien als harten en de punten als een groot getal in het midden onderaan het scherm. Kijk hier voor [gratis spelbronnen](https://www.kenney.nl/) + +# Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ---------------------- | --------------------------- | -------------------------- | +| | volledige game wordt gepresenteerd | game wordt gedeeltelijk gepresenteerd | gedeeltelijke game bevat bugs | \ No newline at end of file diff --git a/6-space-game/5-keeping-score/translations/assignment.zh-tw.md b/6-space-game/5-keeping-score/translations/assignment.zh-tw.md new file mode 100644 index 00000000..b4dac6bf --- /dev/null +++ b/6-space-game/5-keeping-score/translations/assignment.zh-tw.md @@ -0,0 +1,11 @@ +# 建立計分遊戲 + +## 簡介 + +建立一款遊戲,能有創意地顯示生命值與分數。建議上能在畫面的正下方,以心型圖示顯示生命值,或是斗大的數字顯示分數。看看這些[免費的遊戲資源](https://www.kenney.nl/)。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------- | ---------------- | ------------ | +| | 呈現出完整的遊戲 | 遊戲提供部分內容 | 遊戲存在問題 | diff --git a/6-space-game/6-end-condition/translations/README.zh-tw.md b/6-space-game/6-end-condition/translations/README.zh-tw.md new file mode 100644 index 00000000..a36e2b36 --- /dev/null +++ b/6-space-game/6-end-condition/translations/README.zh-tw.md @@ -0,0 +1,222 @@ +# 建立太空遊戲 Part 6:結束與重來 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/39?loc=zh_tw) + +有許多方式可以表達遊戲中的*結束狀態*。這都取決於你這位遊戲開發者,定義遊戲結束的理由。假設我們討論這款已經開發許久的太空遊戲,以下是遊戲結束的理由: + +- **`N` 艘敵軍艦艇被擊毀**:如果你想將遊戲分成許多關卡,一種常見的方式是將每一關的破關門檻,定為擊毀 `N` 艘敵軍艦艇。 +- **你的船艦已被擊毀**:一定有遊戲,只要你的船艦被擊毀一次時,便判定你輸了這場遊戲。另一種可行概念是加入生命值系統。每次你的船艦被擊毀時,會扣除一條生命。一但你損失了所有性命,你便輸了這場遊戲。 +- **你已經取得 `N` 點分數**:另一種常見的結束狀態為分數門檻。取得分數的機制取決在你,常見的條件為摧毀敵艦、或是收集敵艦所*掉落*的道具。 +- **完成關卡**:這或許會涉及到許多種狀態,好比說: `X` 艘艦艇已被擊毀、已取得 `Y` 點分數或是收集特定的道具。 + +## 重新遊戲 + +如果玩家很享受你的遊戲,他們會想再重新遊玩一次。一旦因任何原因結束遊戲時,你應該要提供重新遊戲的方法。 + +✅ 想想看,什麼條件下會結束一款遊戲,而它們又是如何提示你重新遊玩。 + +## 建立目標 + +你需要為你的遊戲新增這些規則: + +1. **贏得遊戲**。 一旦所有敵軍艦艇被擊毀時,你便贏得這場遊戲。請額外地顯示勝利訊息。 +1. **重新開始**。 一旦你損失了所有性命,或是贏得了勝利,你應該提供方法來重新遊戲。記住!你需要重新初始化你的遊戲,所有遊戲的歷史紀錄會被移除。 + +## 建議步驟 + +在你的 `your-work` 子資料夾中,確認檔案是否建立完成。它應該包括: + +```bash +-| assets + -| enemyShip.png + -| player.png + -| laserRed.png + -| life.png +-| index.html +-| app.js +-| package.json +``` + +開始 `your_work` 資料夾中的專案,輸入: + +```bash +cd your-work +npm start +``` + +這會啟動 HTTP 伺服器並發布網址 `http://localhost:5000`。開啟瀏覽器並輸入該網址。你的遊戲應該能被遊玩。 + +> 要點: 要避免在 Visual Studio Code 裡出現警告訊息,編輯函式 `window.onload` 以 is,而非 let 的方式呼叫 `gameLoopId`;並在檔案正上方獨立地宣告 gameLoopId: `let gameLoopId;`。 + +### 加入程式碼 + +1. **追蹤結束狀態**。 新增程式碼來追蹤敵人的數量,利用下列函式判斷英雄艦艇是否被擊毀: + + ```javascript + function isHeroDead() { + return hero.life <= 0; + } + + function isEnemiesDead() { + const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); + return enemies.length === 0; + } + ``` + +1. **加入訊息處理器**。 編輯 `eventEmitter` 以處理這些狀態: + + ```javascript + eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { + first.dead = true; + second.dead = true; + hero.incrementPoints(); + + if (isEnemiesDead()) { + eventEmitter.emit(Messages.GAME_END_WIN); + } + }); + + eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { + enemy.dead = true; + hero.decrementLife(); + if (isHeroDead()) { + eventEmitter.emit(Messages.GAME_END_LOSS); + return; // 遊戲失敗,提前結束 + } + if (isEnemiesDead()) { + eventEmitter.emit(Messages.GAME_END_WIN); + } + }); + + eventEmitter.on(Messages.GAME_END_WIN, () => { + endGame(true); + }); + + eventEmitter.on(Messages.GAME_END_LOSS, () => { + endGame(false); + }); + ``` + +1. **加入新的訊息**。 新增這些訊息到 Messages 常數中: + + ```javascript + GAME_END_LOSS: "GAME_END_LOSS", + GAME_END_WIN: "GAME_END_WIN", + ``` + +2. **加入重新開始的功能** 在按下特定按鈕後,程式會重新開始遊戲。 + + 1. **監聽 `Enter` 按鈕之按壓**。 編輯視窗的 eventListener ,監聽按鍵的按壓: + + ```javascript + else if(evt.key === "Enter") { + eventEmitter.emit(Messages.KEY_EVENT_ENTER); + } + ``` + + 1. **加入重新遊戲的訊息**。 加入這段訊息到 Messages 常數中: + + ```javascript + KEY_EVENT_ENTER: "KEY_EVENT_ENTER", + ``` + +1. **制定遊戲規則**。 編制下列的遊戲規則: + + 1. **玩家勝利條件**。 當所有敵軍艦艇被擊毀時,顯示勝利訊息。 + + 1. 首先,建立函式 `displayMessage()`: + + ```javascript + function displayMessage(message, color = "red") { + ctx.font = "30px Arial"; + ctx.fillStyle = color; + ctx.textAlign = "center"; + ctx.fillText(message, canvas.width / 2, canvas.height / 2); + } + ``` + + 1. 建立函式 `endGame()`: + + ```javascript + function endGame(win) { + clearInterval(gameLoopId); + + // 設定延遲以確保所有圖像皆繪製完成 + setTimeout(() => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + if (win) { + displayMessage( + "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew", + "green" + ); + } else { + displayMessage( + "You died !!! Press [Enter] to start a new game Captain Pew Pew" + ); + } + }, 200) + } + ``` + + 1. **重新遊戲的邏輯**。 當玩家損失所有的性命,或是贏下這場遊戲,顯示遊戲重來的提示。此外,在*重新遊玩*按鍵被按壓時,重新遊戲(你可以自己決定任一個鍵盤按鍵)。 + + 1. 建立函式 `resetGame()`: + + ```javascript + function resetGame() { + if (gameLoopId) { + clearInterval(gameLoopId); + eventEmitter.clear(); + initGame(); + gameLoopId = setInterval(() => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + drawPoints(); + drawLife(); + updateGameObjects(); + drawGameObjects(ctx); + }, 100); + } + } + ``` + + 1. 在 `initGame()` 內呼叫 `eventEmitter` 來重新設定遊戲: + + ```javascript + eventEmitter.on(Messages.KEY_EVENT_ENTER, () => { + resetGame(); + }); + ``` + + 1. 在 EventEmitter 加入函式 `clear()`: + + ```javascript + clear() { + this.listeners = {}; + } + ``` + +👽 💥 🚀 恭喜你,艦長!你的遊戲已經完成了!幹得好! 🚀 💥 👽 + +--- + +## 🚀 挑戰 + +加入遊戲音效!你能加入音效來提升遊戲品質嗎?或許在雷射擊中敵人,或是在英雄死亡、勝利時發出音效。看看這套[沙盒](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play),了解如何使用 JavaScript 播放音效。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/40?loc=zh_tw) + +## 複習與自學 + +你的功課是建立一款新的小遊戲。去探索一些有趣的遊戲,決定你想建造的遊戲類型。 + +## 作業 + +[建立一款遊戲](assignment.zh-tw.md) diff --git a/6-space-game/6-end-condition/translations/assignment.nl.md b/6-space-game/6-end-condition/translations/assignment.nl.md new file mode 100644 index 00000000..bbc70b0d --- /dev/null +++ b/6-space-game/6-end-condition/translations/assignment.nl.md @@ -0,0 +1,19 @@ +# Bouw een voorbeeldspel + +## Instructies + +Probeer een klein spel te bouwen waarin u oefent op verschillende eindcondities. Varieer tussen het behalen van een aantal punten, de held verliest alle levens of alle monsters zijn verslagen. Bouw iets eenvoudigs, zoals een console-gebaseerd avonturenspel. Gebruik de onderstaande spelstroom als inspiratie: + +``` +Held> slaat aan met slagzwaard - orc krijgt 3p schade +Orc> Slaat met club - held krijgt 2p schade +Held> Schopt - orc krijgt 1p schade +Game> Orc is verslagen - Held verzamelt 2 munten +Game> ****Geen monsters meer, u heeft het kwaadaardige fort veroverd**** +``` + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ---------------------- | --------------------------- | -------------------------- | +| | volledige game wordt gepresenteerd | game wordt gedeeltelijk gepresenteerd | gedeeltelijke game bevat bugs | \ No newline at end of file diff --git a/6-space-game/6-end-condition/translations/assignment.zh-tw.md b/6-space-game/6-end-condition/translations/assignment.zh-tw.md new file mode 100644 index 00000000..ba7b6106 --- /dev/null +++ b/6-space-game/6-end-condition/translations/assignment.zh-tw.md @@ -0,0 +1,19 @@ +# 建立一款遊戲 + +## 簡介 + +試著建立一款小遊戲,實際應用不同的終止狀態。做一些變化,如取得的分數、英雄血量或是被擊敗的怪物。可以是很簡單的類型,例如文字冒險遊戲。請參考下列的遊戲流程作為啟發: + +``` +英雄> 使用寶劍攻擊 - 獸人受到了 3 點傷害 +獸人> 使用棍棒攻擊 - 英雄受到了 2 點傷害 +英雄> 踢擊 - 獸人受到了 1 點傷害 +遊戲訊息> 獸人已被擊敗 - 英雄取得 2 枚硬幣 +遊戲訊息> ****已殲滅所有怪獸,你已佔領了邪惡堡壘**** +``` + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ---------------- | ---------------- | ------------ | +| | 呈現出完整的遊戲 | 遊戲提供部分內容 | 遊戲存在問題 | diff --git a/6-space-game/translations/README.nl.md b/6-space-game/translations/README.nl.md new file mode 100644 index 00000000..b884533b --- /dev/null +++ b/6-space-game/translations/README.nl.md @@ -0,0 +1,31 @@ +# Bouw een Ruimtegame + +Een ruimtegame om meer geavanceerde JavaScript-basisprincipes te leren + +In deze les leert u hoe u uw eigen ruimtegame kunt bouwen. Als u ooit het spel "Space Invaders" hebt gespeeld, heeft dit spel hetzelfde idee: een ruimteschip besturen en schieten op monsters die van boven naar beneden komen. Hier is hoe het voltooide spel eruit zal zien: + + + +In deze zes lessen leert u het volgende: + +- **Werk** met het Canvas-element om dingen op een scherm te tekenen +- **Begrijp** het cartesische coördinatensysteem +- **Leer** het Pub-Sub-patroon om een degelijke game-architectuur te creëren die gemakkelijker te onderhouden en uit te breiden is +- **Maak gebruik van** Async/Await om gamebronnen te laden +- **Behandel** toetsenbordgebeurtenissen + +## Overzicht + +- Theorie + - [Inleiding tot het bouwen van spellen met JavaScript](../1-introduction/translations/README.md) +- Praktijk + - [Tekenen op canvas](../2-drawing-to-canvas/translations/README.md) + - [Elementen over het scherm laten bewegen](../3-moving-elements-around/translations/README.md) + - [Botsingsdetectie](../4-collision-detection/translations/README.md) + - [Score bijhouden](../5-keeping-score/translations/README.md) + - [Het spel beëindigen en opnieuw starten](../6-end-condition/translations/README.md) + +## Credits + +De middelen die hiervoor zijn gebruikt, waren afkomstig van https://www.kenney.nl/. +Als u van het bouwen van games houdt, zijn dit enkele zeer goede activa, veel is gratis en sommige worden betaald. diff --git a/6-space-game/translations/README.zh-tw.md b/6-space-game/translations/README.zh-tw.md new file mode 100644 index 00000000..4f4d9aab --- /dev/null +++ b/6-space-game/translations/README.zh-tw.md @@ -0,0 +1,31 @@ +# 建立一款太空遊戲 + +一款太空遊戲能教會你更多 JavaScript 的進階概念 + +這系列課程中,你會學習如何建立屬於自己的太空遊戲。如果你遊玩過遊戲「太空侵略者」,這款遊戲有相同的套路:操控太空船並擊落由上接近的怪物。這是遊戲完成後的模樣: + + + +這六堂課程中,你會學習: + +- **使用** Canvas 元素來在畫面上繪製物件 +- **了解**笛卡爾座標系 +- **學習**發布與訂閱設計模式,建立容易維護及擴增的遊戲結構 +- **利用** Async/Await 來讀取遊戲資源 +- **處理**鍵盤事件 + +## 總覽 + +- 理論 + - [利用 JavaScript 設計遊戲](../1-introduction/translations/README.zh-tw.md) +- 實作 + - [在畫布上繪製](../2-drawing-to-canvas/translations/README.zh-tw.md) + - [移動畫面上之物件](../3-moving-elements-around/translations/README.zh-tw.md) + - [碰撞偵測](../4-collision-detection/translations/README.zh-tw.md) + - [持續得分](../5-keeping-score/translations/README.zh-tw.md) + - [結束與重新遊戲](../6-end-condition/translations/README.zh-tw.md) + +## 參與人員 + +遊戲資源皆來自於 https://www.kenney.nl/。 +如果你熱愛設計遊戲,這邊有許多實用的資源,許多資源是免費的,有些則是付費內容。 diff --git a/7-bank-project/1-template-route/README.md b/7-bank-project/1-template-route/README.md index d7a89c5c..b01a52db 100644 --- a/7-bank-project/1-template-route/README.md +++ b/7-bank-project/1-template-route/README.md @@ -41,7 +41,7 @@ If you want to create multiples screens for a web page, one solution would be to - You have to reload the entire HTML when switching screen, which can be slow. - It's difficult to share data between the different screens. -Another approach is have only one HTML file, and define multiple [HTML templates](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) using the `<template>` element. A template is a reusable HTML block that is not displayed by the browser, and needs to be instantiated at runtime using JavaScript. +Another approach is have only one HTML file, and define multiple [HTML templates](https://developer.mozilla.org/docs/Web/HTML/Element/template) using the `<template>` element. A template is a reusable HTML block that is not displayed by the browser, and needs to be instantiated at runtime using JavaScript. ### Task @@ -107,9 +107,9 @@ If you try your current HTML file in a browser, you'll see that it get stuck dis Instantiating a template is usually done in 3 steps: -1. Retrieve the template element in the DOM, for example using [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). -2. Clone the template element, using [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode). -3. Attach it to the DOM under a visible element, for example using [`appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild). +1. Retrieve the template element in the DOM, for example using [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById). +2. Clone the template element, using [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode). +3. Attach it to the DOM under a visible element, for example using [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild). ✅ Why do we need to clone the template before attaching it to the DOM? What do you think would happen if we skipped this step? @@ -174,7 +174,7 @@ const routes = { }; ``` -Now let's modify a bit the `updateRoute` function. Instead of passing directly the `templateId` as an argument, we want to retrieve it by first looking at the current URL, and then use our map to get the corresponding template ID value. We can use [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) to get only the path section from the URL. +Now let's modify a bit the `updateRoute` function. Instead of passing directly the `templateId` as an argument, we want to retrieve it by first looking at the current URL, and then use our map to get the corresponding template ID value. We can use [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) to get only the path section from the URL. ```js function updateRoute() { @@ -202,9 +202,9 @@ The next step for our app is to add the possibility to navigate between pages wi We already took care of the second part with the `updateRoute` function, so we have to figure out how to update the current URL. -We'll have to use JavaScript and more specifically the [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) that allows to update the URL and create a new entry in the browsing history, without reloading the HTML. +We'll have to use JavaScript and more specifically the [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) that allows to update the URL and create a new entry in the browsing history, without reloading the HTML. -> Note: While the HTML anchor element [`<a href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) can be used on its own to create hyperlinks to different URLs, it will make the browser reload the HTML by default. It is necessary to prevent this behavior when handling routing with custom javascript, using the preventDefault() function on the click event. +> Note: While the HTML anchor element [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) can be used on its own to create hyperlinks to different URLs, it will make the browser reload the HTML by default. It is necessary to prevent this behavior when handling routing with custom javascript, using the preventDefault() function on the click event. ### Task @@ -252,7 +252,7 @@ Let's complete the navigation system by adding bindings to our *Login* and *Logo <a href="/login" onclick="onLinkClick()">Logout</a> ``` -Using the [`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) attribute bind the `click` event to JavaScript code, here the call to the `navigate()` function. +Using the [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) attribute bind the `click` event to JavaScript code, here the call to the `navigate()` function. Try clicking on these links, you should be now able to navigate between the different screens of your app. @@ -266,7 +266,7 @@ Using the `history.pushState` creates new entries in the browser's navigation hi If you try clicking on the back button a few times, you'll see that the current URL changes and the history is updated, but the same template keeps being displayed. -That's because don't know that we need to call `updateRoute()` every time the history changes. If you take a look at the [`history.pushState` documentation](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState), you can see that if the state changes - meaning that we moved to a different URL - the [`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event) event is triggered. We'll use that to fix that issue. +That's because don't know that we need to call `updateRoute()` every time the history changes. If you take a look at the [`history.pushState` documentation](https://developer.mozilla.org/docs/Web/API/History/pushState), you can see that if the state changes - meaning that we moved to a different URL - the [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) event is triggered. We'll use that to fix that issue. ### Task @@ -277,7 +277,7 @@ window.onpopstate = () => updateRoute(); updateRoute(); ``` -> Note: we used an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) here to declare our `popstate` event handler for conciseness, but a regular function would work the same. +> Note: we used an [arrow function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) here to declare our `popstate` event handler for conciseness, but a regular function would work the same. Here's a refresher video on arrow functions: @@ -299,7 +299,7 @@ Add a new template and route for a third page that shows the credits for this ap ## Review & Self Study -Routing is one of the surprisingly tricky parts of web development, especially as the web moves from page refresh behaviors to Single Page Application page refreshes. Read a little about [how the Azure Static Web App service](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa) handles routing. Can you explain why some of the decisions described on that document are necessary? +Routing is one of the surprisingly tricky parts of web development, especially as the web moves from page refresh behaviors to Single Page Application page refreshes. Read a little about [how the Azure Static Web App service](https://docs.microsoft.com/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa) handles routing. Can you explain why some of the decisions described on that document are necessary? ## Assignment diff --git a/7-bank-project/1-template-route/translations/README.es.md b/7-bank-project/1-template-route/translations/README.es.md index 2ac4cf9a..ccb82bf1 100644 --- a/7-bank-project/1-template-route/translations/README.es.md +++ b/7-bank-project/1-template-route/translations/README.es.md @@ -40,7 +40,7 @@ Si desea crear varias pantallas para una página web, una solución sería crear - Tienes que volver a cargar todo el HTML al cambiar de pantalla, lo que puede ser lento. - Es difícil compartir datos entre las diferentes pantallas. -Otro enfoque es tener un solo archivo HTML y definir múltiples [plantillas HTML](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) usando el elemento `<template>`. Una plantilla es un bloque HTML reutilizable que el navegador no muestra y debe instanciarse en tiempo de ejecución mediante JavaScript. +Otro enfoque es tener un solo archivo HTML y definir múltiples [plantillas HTML](https://developer.mozilla.org/docs/Web/HTML/Element/template) usando el elemento `<template>`. Una plantilla es un bloque HTML reutilizable que el navegador no muestra y debe instanciarse en tiempo de ejecución mediante JavaScript. ### Tarea: @@ -105,9 +105,9 @@ Si prueba su archivo HTML actual en un navegador, verá que se atasca mostrando La instanciación de una plantilla se suele realizar en 3 pasos: -1. Recupere el elemento de plantilla en el DOM, por ejemplo, usando [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). -2. Clone el elemento de plantilla, usando [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode). -3. Adjúntelo al DOM bajo un elemento visible, por ejemplo usando [ʻappendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild). +1. Recupere el elemento de plantilla en el DOM, por ejemplo, usando [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById). +2. Clone el elemento de plantilla, usando [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode). +3. Adjúntelo al DOM bajo un elemento visible, por ejemplo usando [ʻappendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild). ✅ ¿Por qué necesitamos clonar la plantilla antes de adjuntarla al DOM? ¿Qué crees que pasaría si nos salteáramos este paso? @@ -172,7 +172,7 @@ const routes = { }; ``` -Ahora modifiquemos un poco la función `updateRoute`. En lugar de pasar directamente el `templateId` como argumento, queremos recuperarlo mirando primero la URL actual y luego usar nuestro mapa para obtener el valor de ID de plantilla correspondiente. Podemos usar [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) para obtener solo la sección de ruta de la URL. +Ahora modifiquemos un poco la función `updateRoute`. En lugar de pasar directamente el `templateId` como argumento, queremos recuperarlo mirando primero la URL actual y luego usar nuestro mapa para obtener el valor de ID de plantilla correspondiente. Podemos usar [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) para obtener solo la sección de ruta de la URL. ```js function updateRoute() { @@ -199,9 +199,9 @@ El siguiente paso para nuestra aplicación es agregar la posibilidad de navegar Ya nos ocupamos de la segunda parte con la función `updateRoute`, así que tenemos que averiguar cómo actualizar la URL actual. -Si bien el elemento de anclaje HTML [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) se puede utilizar para crear hipervínculos a diferentes URL, podemos ' No use eso aquí, ya que hará que el navegador vuelva a cargar el HTML. +Si bien el elemento de anclaje HTML [`<a>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) se puede utilizar para crear hipervínculos a diferentes URL, podemos ' No use eso aquí, ya que hará que el navegador vuelva a cargar el HTML. -En su lugar, tendremos que usar JavaScript y más específicamente el [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) que permite actualizar la URL y cree una nueva entrada en el historial de navegación, sin volver a cargar el HTML. +En su lugar, tendremos que usar JavaScript y más específicamente el [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) que permite actualizar la URL y cree una nueva entrada en el historial de navegación, sin volver a cargar el HTML. ### Tarea @@ -241,7 +241,7 @@ Completemos el sistema de navegación agregando enlaces a nuestros botones *logi <button onclick="navigate('/login')">Logout</button> ``` -Usando el atributo [`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) enlaza el evento `click` al código JavaScript, aquí la llamada al` navigate()`función. +Usando el atributo [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) enlaza el evento `click` al código JavaScript, aquí la llamada al` navigate()`función. Intente hacer clic en estos botones, ahora debería poder navegar entre las diferentes pantallas de su aplicación. @@ -255,7 +255,7 @@ El uso de `history.pushState` crea nuevas entradas en el historial de navegació Si intenta hacer clic en el botón Atrás varias veces, verá que la URL actual cambia y el historial se actualiza, pero se sigue mostrando la misma plantilla. -Eso es porque no sabemos que necesitamos llamar a `updateRoute()` cada vez que cambia el historial. Si echas un vistazo a la [`history.pushState` documentation](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState), puedes ver que si el estado cambia - lo que significa que nos mudamos a una URL diferente - se activa el evento [`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event). Lo usaremos para solucionar ese problema. +Eso es porque no sabemos que necesitamos llamar a `updateRoute()` cada vez que cambia el historial. Si echas un vistazo a la [`history.pushState` documentation](https://developer.mozilla.org/docs/Web/API/History/pushState), puedes ver que si el estado cambia - lo que significa que nos mudamos a una URL diferente - se activa el evento [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event). Lo usaremos para solucionar ese problema. ### Tarea @@ -267,7 +267,7 @@ window.onpopstate = () => updateRoute(); updateRoute(); ``` -> Nota: utilizamos una [función de flecha](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) aquí para declarar nuestro controlador de eventos `popstate` por concisión, pero un la función regular funcionaría igual. +> Nota: utilizamos una [función de flecha](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) aquí para declarar nuestro controlador de eventos `popstate` por concisión, pero un la función regular funcionaría igual. Ahora intente utilizar los botones de avance y retroceso de sus navegadores y compruebe que esta vez lo que se muestra está actualizado correctamente. diff --git a/7-bank-project/1-template-route/translations/README.it.md b/7-bank-project/1-template-route/translations/README.it.md index 7c45b6ba..fbf92f7e 100644 --- a/7-bank-project/1-template-route/translations/README.it.md +++ b/7-bank-project/1-template-route/translations/README.it.md @@ -41,7 +41,7 @@ Se si desidera creare più schermate per una pagina Web, una soluzione potrebbe - È necessario ricaricare l'intero HTML quando si cambia schermata, il che può essere lento. - È difficile condividere i dati tra le diverse schermate. -Un altro approccio consiste nell'avere un solo file HTML e definire più [modelli HTML](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) utilizzando l'elemento `<template>`. Un modello è un blocco HTML riutilizzabile che non viene visualizzato dal browser e deve essere istanziato in fase di esecuzione utilizzando JavaScript. +Un altro approccio consiste nell'avere un solo file HTML e definire più [modelli HTML](https://developer.mozilla.org/docs/Web/HTML/Element/template) utilizzando l'elemento `<template>`. Un modello è un blocco HTML riutilizzabile che non viene visualizzato dal browser e deve essere istanziato in fase di esecuzione utilizzando JavaScript. ### Attività @@ -108,7 +108,7 @@ Se si prova il proprio file HTML corrente in un browser, si vedrà che si blocca L'istanza di un modello viene solitamente eseguita in 3 passaggi: 1. Recuperare l'elemento del modello nel DOM, ad esempio utilizzando [`document.getElementById`](https://developer.mozilla.org/it/docs/Web/API/Document/getElementById). -2. Clonare l'elemento template, usando [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode). +2. Clonare l'elemento template, usando [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode). 3. Collegarlo al DOM sotto un elemento visibile, ad esempio utilizzando [`appendChild`](https://developer.mozilla.org/it/docs/Web/API/Node/appendChild). ✅ Perché è necessario clonare il modello prima di collegarlo al DOM? Cosa si pensa che accadrebbe se venisse saltato questo passaggio? @@ -174,7 +174,7 @@ const routes = { }; ``` -Ora modificare un po' la funzione `updateRoute`. Invece di passare direttamente il `templateId` come argomento, lo si vuole recuperare guardando prima l'URL corrente, quindi utilizzndo la mappa per ottenere il valore dell'ID del modello corrispondente. Si può usare [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) per ottenere solo la sezione del percorso dall'URL. +Ora modificare un po' la funzione `updateRoute`. Invece di passare direttamente il `templateId` come argomento, lo si vuole recuperare guardando prima l'URL corrente, quindi utilizzndo la mappa per ottenere il valore dell'ID del modello corrispondente. Si può usare [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) per ottenere solo la sezione del percorso dall'URL. ```js function updateRoute() { @@ -202,7 +202,7 @@ Il prossimo passo per la costruzione dell'app è aggiungere la possibilità di n E' già stata trattata la seconda parte con la funzione `updateRoute`, quindi occorre capire come aggiornare l'URL corrente. -Si dovrà utilizzare JavaScript e più precisamente [history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) che permette di aggiornare l'URL e creare una nuova voce nella cronologia di navigazione, senza ricaricare l'HTML. +Si dovrà utilizzare JavaScript e più precisamente [history.pushState](https://developer.mozilla.org/docs/Web/API/History/pushState) che permette di aggiornare l'URL e creare una nuova voce nella cronologia di navigazione, senza ricaricare l'HTML. > Nota: Sebbene l'elemento HTML ancora [`<a href>`](https://developer.mozilla.org/it/docs/Web/HTML/Element/a) possa essere usato da solo per creare collegamenti ipertestuali a diversi URL, è anche in grado di fare ricaricare al browser l'HTML nella modalità predefinita. È necessario prevenire questo comportamento quando si gestisce il routing con javascript personalizzato, utilizzando la funzione preventDefault() sull'evento click. @@ -252,7 +252,7 @@ Si completa il sistema di navigazione aggiungendo collegamenti ai link di access <a href="/login" onclick="onLinkClick()">Logout</a> ``` -Utilizzando l 'attributo [`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) associare l'evento `click` al codice JavaScript, in questo caso la chiamata alla funzione `navigate()` . +Utilizzando l 'attributo [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) associare l'evento `click` al codice JavaScript, in questo caso la chiamata alla funzione `navigate()` . Provare a fare clic su questi collegamenti, ora si dovrebbe essere in grado di navigare tra le diverse schermate dell'app. @@ -266,7 +266,7 @@ L'utilizzo di `history.pushState` crea nuove voci nella cronologia di navigazion Se si prova a fare clic sul pulsante Indietro alcune volte, si vedrà che l'URL corrente cambia e la cronologia viene aggiornata, ma lo stesso modello continua a essere visualizzato. -Questo perché il browser non sa che si deve chiamare `updateRoute()` ogni volta che cambia la cronologia. Se si dà un'occhiata alla documentazione di [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) si può vedere che se lo stato cambia, vale a dire che si è passati a un URL diverso, viene attivato l'[evento](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event) `popstate`. Verrà usato per risolvere quel problema. +Questo perché il browser non sa che si deve chiamare `updateRoute()` ogni volta che cambia la cronologia. Se si dà un'occhiata alla documentazione di [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) si può vedere che se lo stato cambia, vale a dire che si è passati a un URL diverso, viene attivato l'[evento](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) `popstate`. Verrà usato per risolvere quel problema. ### Attività @@ -277,7 +277,7 @@ window.onpopstate = () => updateRoute(); updateRoute(); ``` -> Nota: è stata usata una [funzione freccia](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) qui per dichiarare il gestore di eventi `popstate` per concisione, ma una funzione normale andrebbe bene allo stesso modo. +> Nota: è stata usata una [funzione freccia](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) qui per dichiarare il gestore di eventi `popstate` per concisione, ma una funzione normale andrebbe bene allo stesso modo. Ecco un video di aggiornamento sulle funzioni freccia: @@ -299,7 +299,7 @@ Aggiungere un nuovo modello e instradare per una terza pagina che mostra i credi ## Revisione e Auto Apprendimento -Il routing (instradamento) è una delle parti sorprendentemente complicate dello sviluppo web, soprattutto perché il web passa dai comportamenti di aggiornamento della pagina all'aggiornamento della pagina dell'applicazione a pagina singola. Leggere alcune informazioni su [come il servizio App Web Static di Azure](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=academic-4621-cxa) gestisce il routing. Si può spiegare perché alcune delle decisioni descritte in quel documento sono necessarie? +Il routing (instradamento) è una delle parti sorprendentemente complicate dello sviluppo web, soprattutto perché il web passa dai comportamenti di aggiornamento della pagina all'aggiornamento della pagina dell'applicazione a pagina singola. Leggere alcune informazioni su [come il servizio App Web Static di Azure](https://docs.microsoft.com/azure/static-web-apps/routes?WT.mc_id=academic-4621-cxa) gestisce il routing. Si può spiegare perché alcune delle decisioni descritte in quel documento sono necessarie? ## Compito diff --git a/7-bank-project/1-template-route/translations/README.ja.md b/7-bank-project/1-template-route/translations/README.ja.md index 61447857..376f7d00 100644 --- a/7-bank-project/1-template-route/translations/README.ja.md +++ b/7-bank-project/1-template-route/translations/README.ja.md @@ -174,7 +174,7 @@ const routes = { }; ``` -では、`updateRoute` 関数を少し修正してみましょう。引数に `templateId` を直接渡すのではなく、まず現在の URL を見て、map を使って対応するテンプレート ID の値を取得したいと思います。URL からパス部分だけを取得するには、[`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname)を使うことができます。 +では、`updateRoute` 関数を少し修正してみましょう。引数に `templateId` を直接渡すのではなく、まず現在の URL を見て、map を使って対応するテンプレート ID の値を取得したいと思います。URL からパス部分だけを取得するには、[`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname)を使うことができます。 ```js function updateRoute() { @@ -266,7 +266,7 @@ HTML の *Login* と *Logout* リンクにバインディングを追加して 何度か戻るボタンをクリックしてみると、現在の URL が変わって履歴が更新されていますが、同じテンプレートが表示され続けています。 -これは、履歴が変わるたびに `updateRoute()` を呼び出す必要があることを知らないからです。[`history.pushState` のドキュメント](https://developer.mozilla.org/ja/docs/Web/API/History/pushState)を見てみると、状態が変化した場合、つまり別の URL に移動した場合には、[`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event)イベントが発生することがわかります。これを使ってこの問題を解決しましょう。 +これは、履歴が変わるたびに `updateRoute()` を呼び出す必要があることを知らないからです。[`history.pushState` のドキュメント](https://developer.mozilla.org/ja/docs/Web/API/History/pushState)を見てみると、状態が変化した場合、つまり別の URL に移動した場合には、[`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event)イベントが発生することがわかります。これを使ってこの問題を解決しましょう。 ### タスク diff --git a/7-bank-project/1-template-route/translations/README.ko.md b/7-bank-project/1-template-route/translations/README.ko.md index f3932621..854d09af 100644 --- a/7-bank-project/1-template-route/translations/README.ko.md +++ b/7-bank-project/1-template-route/translations/README.ko.md @@ -41,7 +41,7 @@ - 화면 전환 시 전체 HTML을 다시 불러와야 하므로, 속도가 느릴 수 있습니다. - 서로 다른 화면 간 데이터 공유가 어렵습니다. -또 다른 방법은 HTML 파일이 하나일 때, `<template>` 요소로 여러 [HTML templates](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)을 정의하는 것입니다. 템플릿은 브라우저에 보이지 않는 재사용 가능한 HTML 블록이면서, JavaScript를 사용해서 런타임에 인스턴스화합니다. +또 다른 방법은 HTML 파일이 하나일 때, `<template>` 요소로 여러 [HTML templates](https://developer.mozilla.org/docs/Web/HTML/Element/template)을 정의하는 것입니다. 템플릿은 브라우저에 보이지 않는 재사용 가능한 HTML 블록이면서, JavaScript를 사용해서 런타임에 인스턴스화합니다. ### 작업 @@ -107,9 +107,9 @@ 템플릿 인스턴스화는 일반적으로 3 단계로 진행됩니다: -1. [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)를 사용한 예시로, DOM에서 템플릿 요소 검색합니다. -2. [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode)로, 템플릿 요소를 복제합니다. -3. [`appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)를 사용한 예시로, 보이는 요소 아래의 DOM에 붙입니다. +1. [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById)를 사용한 예시로, DOM에서 템플릿 요소 검색합니다. +2. [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode)로, 템플릿 요소를 복제합니다. +3. [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild)를 사용한 예시로, 보이는 요소 아래의 DOM에 붙입니다. ✅ DOM에 붙이기 전에 템플릿을 복제해야하는 이유는 무엇일까요? 이 단계를 넘기면 어떻게 될까요? @@ -174,7 +174,7 @@ const routes = { }; ``` -이제 `updateRoute` 함수를 약간 수정합니다. `templateId`를 인수로 직접 주는 대신, 먼저 현재 URL을 보고 찾은 다음, 맵을 사용하여 해당 템플릿 ID 값을 가져오려 합니다. [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname)으로 URL에서 경로 섹션만 가져올 수 있습니다. +이제 `updateRoute` 함수를 약간 수정합니다. `templateId`를 인수로 직접 주는 대신, 먼저 현재 URL을 보고 찾은 다음, 맵을 사용하여 해당 템플릿 ID 값을 가져오려 합니다. [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname)으로 URL에서 경로 섹션만 가져올 수 있습니다. ```js function updateRoute() { @@ -202,9 +202,9 @@ function updateRoute() { 두 번째 부분은 `updateRoute` 함수로 이미 처리했으므로, 현재 URL로 갱신하는 방법을 알아냅니다. -HTML 앵커 요소 [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)를 사용하여 다른 URL에 대한 하이퍼링크를 만들 수 있지만, 여기에서 사용하면 브라우저가 HTML을 다시 불러오게 됩니다. +HTML 앵커 요소 [`<a>`](https://developer.mozilla.org/docs/Web/HTML/Element/a)를 사용하여 다른 URL에 대한 하이퍼링크를 만들 수 있지만, 여기에서 사용하면 브라우저가 HTML을 다시 불러오게 됩니다. -대신 URL을 업데이트 할 수 있는 JavaScript와 더 구체적으로 [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)를 사용해야합니다. HTML을 다시 불러오지 않고 검색 기록에 새로운 항목을 만듭니다. +대신 URL을 업데이트 할 수 있는 JavaScript와 더 구체적으로 [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState)를 사용해야합니다. HTML을 다시 불러오지 않고 검색 기록에 새로운 항목을 만듭니다. ### 작업 @@ -243,7 +243,7 @@ HTML의 *Login*과 *Logout* 버튼에 바인딩을 추가하여 내비게이션 <button onclick="navigate('/login')">Logout</button> ``` -[`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) 속성을 사용하여 `click` 이벤트를 JavaScript 코드로 바인딩합니다, 여기에서 `navigate()` 함수를 호출합니다. +[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) 속성을 사용하여 `click` 이벤트를 JavaScript 코드로 바인딩합니다, 여기에서 `navigate()` 함수를 호출합니다. 이 버튼들을 클릭해보세요, 이제 앱의 여러 화면들을 이동할 수 있습니다. @@ -257,7 +257,7 @@ HTML의 *Login*과 *Logout* 버튼에 바인딩을 추가하여 내비게이션 뒤로가기 버튼을 몇 번 클릭하면, 현재 URL이 변경되며 히스토리가 갱신되지만 동일한 템플릿이 계속 출력되는 것을 볼 수 있습니다. -히스토리가 바뀔 때마다 `updateRoute()`를 호출해야 한다는 사실을 모르기 때문입니다. [`history.pushState` documentation](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)을 살펴보면, 상태가 바뀌는 지 확인할 수 있습니다 - 다른 URL로 이동했다고 의미합니다. - [`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event) 이벤트가 연결됩니다. 이 이슈를 해결하는 데 사용할 것입니다. +히스토리가 바뀔 때마다 `updateRoute()`를 호출해야 한다는 사실을 모르기 때문입니다. [`history.pushState` documentation](https://developer.mozilla.org/docs/Web/API/History/pushState)을 살펴보면, 상태가 바뀌는 지 확인할 수 있습니다 - 다른 URL로 이동했다고 의미합니다. - [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) 이벤트가 연결됩니다. 이 이슈를 해결하는 데 사용할 것입니다. ### 작업 @@ -268,7 +268,7 @@ window.onpopstate = () => updateRoute(); updateRoute(); ``` -> Note: 여기서는 간결함을 위해 [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)을 사용하여 `popstate` 이벤트 핸들러를 선언했지만, 일반적인 함수와 동일하게 작동합니다. +> Note: 여기서는 간결함을 위해 [arrow function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)을 사용하여 `popstate` 이벤트 핸들러를 선언했지만, 일반적인 함수와 동일하게 작동합니다. 다음은 화살표 함수에 대한 복습 동영상입니다: @@ -288,7 +288,7 @@ updateRoute(); ## 리뷰 & 자기주도 학습 -라우팅은 웹 개발의 놀랍고 까다로운 부분 중 하나입니다, 특히 웹의 페이지 새로고침 동작에서 단일 페이지 애플리케이션 페이지 새로고침으로 이동함에 따라 더욱 더 그렇습니다. [how the Azure Static Web App service](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa)의 라우터 제어에 대해 약간 봅니다. 그 문서에 기술된 몇 가지 결정이 필요한 이유를 설명할 수 있나요? +라우팅은 웹 개발의 놀랍고 까다로운 부분 중 하나입니다, 특히 웹의 페이지 새로고침 동작에서 단일 페이지 애플리케이션 페이지 새로고침으로 이동함에 따라 더욱 더 그렇습니다. [how the Azure Static Web App service](https://docs.microsoft.com/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa)의 라우터 제어에 대해 약간 봅니다. 그 문서에 기술된 몇 가지 결정이 필요한 이유를 설명할 수 있나요? ## 과제 diff --git a/7-bank-project/1-template-route/translations/README.ms.md b/7-bank-project/1-template-route/translations/README.ms.md index 23405ee4..f3b469ef 100644 --- a/7-bank-project/1-template-route/translations/README.ms.md +++ b/7-bank-project/1-template-route/translations/README.ms.md @@ -41,7 +41,7 @@ Jika anda ingin membuat beberapa layar untuk halaman web, satu penyelesaiannya a - Anda harus memuat semula keseluruhan HTML ketika menukar skrin, yang boleh menjadi lambat. - Sukar untuk berkongsi data antara skrin yang berbeza. -Pendekatan lain hanya mempunyai satu fail HTML, dan menentukan beberapa [templat HTML](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) menggunakan elemen `<template>`. Templat adalah blok HTML yang dapat digunakan kembali yang tidak ditampilkan oleh penyemak imbas, dan perlu dibuat pada waktu berjalan menggunakan JavaScript. +Pendekatan lain hanya mempunyai satu fail HTML, dan menentukan beberapa [templat HTML](https://developer.mozilla.org/docs/Web/HTML/Element/template) menggunakan elemen `<template>`. Templat adalah blok HTML yang dapat digunakan kembali yang tidak ditampilkan oleh penyemak imbas, dan perlu dibuat pada waktu berjalan menggunakan JavaScript. ### Tugas @@ -107,9 +107,9 @@ Sekiranya anda mencuba fail HTML semasa anda dalam penyemak imbas, anda akan mel Membuat templat biasanya dilakukan dalam 3 langkah: -1. Dapatkan semula elemen templat di DOM, misalnya menggunakan [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). -2. Klon elemen templat, menggunakan [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode). -3. Lampirkan ke DOM di bawah elemen yang kelihatan, misalnya menggunakan [`appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild). +1. Dapatkan semula elemen templat di DOM, misalnya menggunakan [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById). +2. Klon elemen templat, menggunakan [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode). +3. Lampirkan ke DOM di bawah elemen yang kelihatan, misalnya menggunakan [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild). ✅ Mengapa kita perlu mengklon templat sebelum melampirkannya ke DOM? Apa yang anda fikir akan berlaku sekiranya kita melangkau langkah ini? @@ -174,7 +174,7 @@ const routes = { }; ``` -Sekarang mari kita ubah sedikit fungsi `updateRoute`. Daripada meneruskan secara langsung `templateId` sebagai argumen, kami ingin mendapatkannya dengan terlebih dahulu melihat URL semasa, dan kemudian menggunakan peta kami untuk mendapatkan nilai ID templat yang sesuai. Kita boleh menggunakan [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) untuk mendapatkan hanya bahagian jalan dari URL. +Sekarang mari kita ubah sedikit fungsi `updateRoute`. Daripada meneruskan secara langsung `templateId` sebagai argumen, kami ingin mendapatkannya dengan terlebih dahulu melihat URL semasa, dan kemudian menggunakan peta kami untuk mendapatkan nilai ID templat yang sesuai. Kita boleh menggunakan [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) untuk mendapatkan hanya bahagian jalan dari URL. ```js function updateRoute() { @@ -202,9 +202,9 @@ Langkah seterusnya untuk aplikasi kita adalah menambahkan kemungkinan untuk mena Kami sudah mengurus bahagian kedua dengan fungsi `updateRoute`, jadi kami harus memikirkan cara mengemas kini URL semasa. -Kita mesti menggunakan JavaScript dan lebih khusus lagi [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) yang memungkinkan untuk mengemas kini URL dan buat entri baru dalam sejarah penyemakan imbas, tanpa memuatkan semula HTML. +Kita mesti menggunakan JavaScript dan lebih khusus lagi [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) yang memungkinkan untuk mengemas kini URL dan buat entri baru dalam sejarah penyemakan imbas, tanpa memuatkan semula HTML. -> Catatan: Walaupun elemen anchor HTML [`<a href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) dapat digunakan sendiri untuk membuat hyperlink ke URL yang berbeza, ini akan menjadikan penyemak imbas memuat semula HTML secara lalai. Adalah perlu untuk mencegah tingkah laku ini ketika menangani routing dengan javascript khusus, menggunakan fungsi preventDefault () pada peristiwa klik. +> Catatan: Walaupun elemen anchor HTML [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) dapat digunakan sendiri untuk membuat hyperlink ke URL yang berbeza, ini akan menjadikan penyemak imbas memuat semula HTML secara lalai. Adalah perlu untuk mencegah tingkah laku ini ketika menangani routing dengan javascript khusus, menggunakan fungsi preventDefault () pada peristiwa klik. ### Tugas @@ -252,7 +252,7 @@ Mari lengkapkan sistem navigasi dengan menambahkan pengikatan pada pautan *Login <a href="/login" onclick="onLinkClick()">Logout</a> ``` -Menggunakan atribut [`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) mengikat peristiwa`klik` ke kod JavaScript, di sini panggilan ke `navigasi() `fungsi. +Menggunakan atribut [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) mengikat peristiwa`klik` ke kod JavaScript, di sini panggilan ke `navigasi() `fungsi. Cuba klik pada pautan-pautan ini, kini anda seharusnya dapat menavigasi antara pelbagai skrin aplikasi anda. @@ -266,7 +266,7 @@ Menggunakan `history.pushState` membuat entri baru dalam sejarah navigasi penyem Sekiranya anda cuba mengklik butang kembali beberapa kali, anda akan melihat bahawa URL semasa berubah dan sejarahnya dikemas kini, tetapi templat yang sama terus dipaparkan. -Ini kerana tidak tahu bahawa kita perlu memanggil `updateRoute()` setiap kali sejarah berubah. Sekiranya anda melihat dokumentasi [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState), anda dapat melihat bahawa jika keadaan berubah - yang bermaksud bahawa kami berpindah ke URL yang berbeza - peristiwa [`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event) dicetuskan. Kami akan menggunakannya untuk menyelesaikan masalah itu. +Ini kerana tidak tahu bahawa kita perlu memanggil `updateRoute()` setiap kali sejarah berubah. Sekiranya anda melihat dokumentasi [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), anda dapat melihat bahawa jika keadaan berubah - yang bermaksud bahawa kami berpindah ke URL yang berbeza - peristiwa [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) dicetuskan. Kami akan menggunakannya untuk menyelesaikan masalah itu. ### Tugas @@ -277,7 +277,7 @@ window.onpopstate = () => updateRoute(); updateRoute(); ``` -> Catatan: kami menggunakan [fungsi panah](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) di sini untuk menyatakan pengendali acara `popstate` kami untuk kesimpulan, fungsi biasa akan berfungsi sama. +> Catatan: kami menggunakan [fungsi panah](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) di sini untuk menyatakan pengendali acara `popstate` kami untuk kesimpulan, fungsi biasa akan berfungsi sama. Berikut adalah video penyegaran mengenai fungsi anak panah: @@ -299,7 +299,7 @@ Tambahkan templat dan laluan baru untuk halaman ketiga yang menunjukkan kredit u ## Mengkaji & Belajar Sendiri -Perutean adalah salah satu bahagian pengembangan web yang sangat mengejutkan, terutama ketika web beralih dari tingkah laku penyegaran halaman ke penyegaran halaman Aplikasi Halaman Tunggal. Baca sedikit mengenai [bagaimana perkhidmatan Aplikasi Web Statik Azure](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa) menangani penghalaan . Bolehkah anda menjelaskan mengapa beberapa keputusan yang dijelaskan pada dokumen itu diperlukan? +Perutean adalah salah satu bahagian pengembangan web yang sangat mengejutkan, terutama ketika web beralih dari tingkah laku penyegaran halaman ke penyegaran halaman Aplikasi Halaman Tunggal. Baca sedikit mengenai [bagaimana perkhidmatan Aplikasi Web Statik Azure](https://docs.microsoft.com/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa) menangani penghalaan . Bolehkah anda menjelaskan mengapa beberapa keputusan yang dijelaskan pada dokumen itu diperlukan? ## Tugasan diff --git a/7-bank-project/1-template-route/translations/README.zh-tw.md b/7-bank-project/1-template-route/translations/README.zh-tw.md new file mode 100644 index 00000000..b69a485f --- /dev/null +++ b/7-bank-project/1-template-route/translations/README.zh-tw.md @@ -0,0 +1,307 @@ +# 建立銀行網頁應用程式 Part 1:HTML 模板與網頁路由 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/41?loc=zh_tw) + +### 大綱 + +自從 JavaScript 出現在瀏覽器後,網頁開始變得更複雜、更多互動。網頁技術已經普遍地用於建立功能齊全的應用程式,執行在瀏覽器上,我們稱之為[網頁應用程式](https://zh.wikipedia.org/zh-tw/%E7%BD%91%E7%BB%9C%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F)。基於網頁應用程式的高互動性,使用者不會想在互動後做所有頁面載入所需的等待。這也是為什麼 JavaScript 使用 DOM 來更新 HTML,提供使用者更流暢的網頁體驗。 + +在這堂課程中,我們會譜出銀行網頁應用程式的基礎,使用 HTML 模板建立不同的畫面,各自顯示並更新內容,而不必每次都需要載入整個 HTML 頁面。 + +### 開始之前 + +你需要一個網頁伺服器來測試我們要建的專案。如果你還沒有,你可以安裝 [Node.js](https://nodejs.org) 並在你的專案資料夾中使用指令 `npx lite-server`。這會建立一個本地端的網頁伺服器,在瀏覽器上開啟你的網頁程式。 + +### 準備 + +在你的電腦上,建立資料夾 `bank`,並在裡面建立檔案 `index.html`。我們以這個 HTML [樣板](https://en.wikipedia.org/wiki/Boilerplate_code)來開始: + +```html +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Bank App</title> + </head> + <body> + <!-- This is where you'll work --> + </body> +</html> +``` + +--- + +## HTML 模板(templates) + +如果你想在同一個網頁上建立不同的畫面,其中一種方法是各自建立一個 HTML 檔給每一個你想呈現的子畫面。然而,這個方式有許多不便之處: + +- 你需要在切換頁面時,重新載入整個網頁。這會很花時間。 +- 在不同子頁面上共享數據會是一大難題。 + +另一個解決方案是只有一個 HTML 檔案,並使用 `<template>` 元素定義多個 [HTML 模板](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)。 +一個模板提供可重複利用的 HTML 區塊,它不會顯示在瀏覽器上,而在需要之時由 JavaScript 以呈現出來。 + +### 課題 + +我們會建立一個銀行網頁應用程式,其中包含兩個子畫面:登入頁面與儀表板頁面。首先,我們在網頁應用程式的 HTML body 上,建立放置區來放置模板的子頁面。 + +```html +<div id="app">Loading...</div> +``` + +我們給它 `id`,以利後續 JavaScript 對它的追蹤。 + +> 提示:因為它裡面元素的內容會被置換,我們可以建立載入中訊息或提示,在應用程式載入時顯示出來。 + +接下來,我們加入下列的 HTML 模板,給登入畫面使用。現在我們只加入一行標題與一個有連結的區塊,進行簡單的功能。 + +```html +<template id="login"> + <h1>Bank App</h1> + <section> + <a href="/dashboard">Login</a> + </section> +</template> +``` + +接著,加入另一個 HTML 模板給儀表板頁面。這個頁面就會包含不同的區塊: + +- 包含標題與登出連結的網頁標頭 +- 現在的銀行帳戶餘額 +- 一個歷史交易清單的表格 + +```html +<template id="dashboard"> + <header> + <h1>Bank App</h1> + <a href="/login">Logout</a> + </header> + <section> + Balance: 100$ + </section> + <section> + <h2>Transactions</h2> + <table> + <thead> + <tr> + <th>Date</th> + <th>Object</th> + <th>Amount</th> + </tr> + </thead> + <tbody></tbody> + </table> + </section> +</template> +``` + +> 提示:在建立 HTML 模板時,如果你想知道它的呈現樣子為何,你可以註解掉 `<template>` 與 `</template>`。使用 `<!-- -->` 來註解它們。 + +✅ 你知道為什麼我們需要使用模板的 `id` 屬性嗎?我們可以使用別的屬性,例如 classes 嗎? + +## 利用 JavaScript 顯示模板 + +現在,如果你使用瀏覽器打開你的應用程式,你會看到畫面卡在 `Loading...` 的畫面。那是因為我們需要為它新增一些 JavaScript 的程式碼來顯示出這些 HTML 模板。 + +展現模板通常需要三個步驟: + +1. 在 DOM 內接收模板元素,舉例來說,使用 [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)。 +2. 複製模板元素,使用 [`cloneNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode)。 +3. 將複製元素接到 DOM 的顯示元素上,例如使用 [`appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)。 + +✅ 我們為什麼需要在接到 DOM 前,複製一份模板?你能想像如果我們省略了此步驟後,會發生什麼事嗎? + +### 課題 + +在資料夾中建立新檔案 `app.js`,並在你的 HTML 檔案的 `<head>` 區塊中中匯入這個新檔案: + +```html +<script src="app.js" defer></script> +``` + +在 `app.js` 中,我們建立新函式 `updateRoute`: + +```js +function updateRoute(templateId) { + const template = document.getElementById(templateId); + const view = template.content.cloneNode(true); + const app = document.getElementById('app'); + app.innerHTML = ''; + app.appendChild(view); +} +``` + +這裡做的事情就是我們上述提及過的三個步驟。我們使用 `templateId` 展現了模板,並將複製的內容接在我們的放置區中。注意我們需要使用 `cloneNode(true)` 來複製整個模板的子樹。 + +現在我們呼叫這個函式,指定特定的模板並觀察結果。 + +```js +updateRoute('login'); +``` + +✅ 程式碼中 `app.innerHTML = '';` 的目的為何?如果刪去它會發生什麼事? + +## 建立網頁路由(Routing) + +當提及網頁應用程式時,我們稱呼 *路由(Routing)* 來連接**網址(URLs)**到特定的畫面上,呈現相關內容。一個含有多個 HTML 檔的網頁,網址又象徵著檔案路徑,這能自動地完成網址與檔案的轉換。舉例來說,專案資料夾內有這些檔案: + +``` +mywebsite/index.html +mywebsite/login.html +mywebsite/admin/index.html +``` + +若我們建立網路伺服器,根目錄為 `mywebsite`,則 URL 路由為: + +``` +https://site.com --> mywebsite/index.html +https://site.com/login.html --> mywebsite/login.html +https://site.com/admin/ --> mywebsite/admin/index.html +``` + +然而,在我們的網頁應用中,我們使用單一個 HTML 檔包含所有的子畫面到其中,所以預設的路由行為並不能幫助到本次專案。我們需要手動進行連接,使用 JavaScript 更新該被顯示出來的模板。 + +### 課題 + +我們使用簡單的物件來達成 URL 網址與模板的[關聯實體關係](https://en.wikipedia.org/wiki/Associative_array)。加入這個物件到 `app.js` 檔案的最上方。 + +```js +const routes = { + '/login': { templateId: 'login' }, + '/dashboard': { templateId: 'dashboard' }, +}; +``` + +現在,我們對函式 `updateRoute` 做一些更動。我們不直接將 `templateId` 作為參數傳遞,而是接收現在的 URL 網址,在使用關聯表來取得相對應的模板 ID 數值。我們可以使用 [`window.location.pathname`](https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname) 來取得網址的部分路徑。 + +```js +function updateRoute() { + const path = window.location.pathname; + const route = routes[path]; + + const template = document.getElementById(route.templateId); + const view = template.content.cloneNode(true); + const app = document.getElementById('app'); + app.innerHTML = ''; + app.appendChild(view); +} +``` + +這邊我們建立了模板的路由關係。你可以藉由修改網址,來測試你的網頁是否正確的轉移。 + +✅ 如果你輸入了不存在的網址,它會發生什麼事?我們該如何解決呢? + +## 加入網頁訪問 + +下一個步驟為在不更改網址的情況下,新增網頁訪問的途徑。這會做出兩件事情: + + 1. 更新現在的網址 + 2. 更新要被顯示的模板到新的網址中 + +我們已經完成了第二點,藉由使用函式 `updateRoute` 來完成,所以我們需要釐清該如何更新現在的網址。 + +我們需要使用 JavaScript,詳細來看為 [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState),更新網址位置並建立瀏覽紀錄,同時不更新整個 HTML 頁面。 + +> 筆記:網頁超連結元素 [`<a href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) 可以建立不同網址的連接,但它預設上會讓瀏覽器重新載入 HTML 檔。我們需要手動新增 JavaScript 處理路由以避免此行為發生,在點擊事件中使用函式 preventDefault() 。 + +### 課題 + +我們來建立新的函式,讓應用程式得以做網頁的訪問: + +```js +function navigate(path) { + window.history.pushState({}, path, window.location.origin + path); + updateRoute(); +} +``` + +這個方法根據導入的路徑位置,更新了現在的網址位置,再更新模板上去。`window.location.origin` 回傳了網址的根路徑,允許我們重新構築完整的網址。 + +現在,藉由上述的函式,我們可以解決找不到網頁路徑的問題。我們修改函式 `updateRoute`,在找不到該網頁時強制轉移到一個存在的網頁。 + +```js +function updateRoute() { + const path = window.location.pathname; + const route = routes[path]; + + if (!route) { + return navigate('/login'); + } + + ... +``` + +如果找不到網頁路由時,我們會導往 `login` 的頁面。 + +現在,我們建立新的函式,在連結被點擊時取得網址位置,並避免瀏覽器進行預設上的重新載入: + +```js +function onLinkClick(event) { + event.preventDefault(); + navigate(event.target.href); +} +``` + +現在我們完成應用程式的網頁訪問系統,在 HTML 檔的 *Login* 與 *Logout* 連結加入此函式。 + +```html +<a href="/dashboard" onclick="onLinkClick()">Login</a> +... +<a href="/login" onclick="onLinkClick()">Logout</a> +``` + +使用 [`onclick`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick) 屬性會將 `click` 事件連接到 JavaScript 程式碼中,這邊會再呼叫函式 `navigate()`。 + +試著點擊這些連結,你應該能造訪網頁中不同的的畫面了。 + +✅ `history.pushState` 這個方法是 HTML5 標準的一部份,支援在[所有當代的瀏覽器](https://caniuse.com/?search=pushState)上。如果你要為舊款的瀏覽器設計網頁應用程式的話,這邊有一個技巧來加在這個 API 上:在路徑前面加上 [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment),你可以完成網頁路由與不須重載網頁的功能,它的目的就是在同一個網頁中做內部連結的切換。 + +## 處理瀏覽器的「上一頁」與「下一頁」 + +使用 `history.pushState` 會建立瀏覽器的瀏覽紀錄。你可以使用瀏覽器的*上一頁*來確認,它應該要能呈現像這樣的畫面: + + + +點擊上一頁數次,你會看到網址會改變且歷史紀錄也更新上去了,但同一個模板還是被顯示出來。 + +這是因為網頁不知道該如何依據歷史紀錄來呼叫 `updateRoute()`。如果你閱讀了 [`history.pushState` 技術文件](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState),你會發現如果狀態改變 ── 同時代表著網址改變 ── [`popstate`](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event) 事件就會被觸發。我們會利用此特徵來修復這個問題。 + +### 課題 + +為了在瀏覽器歷史改變時更新該被顯示的模板,我們會以新函式來呼叫 `updateRoute()`。我們在 `app.js` 檔最下方加入: + +```js +window.onpopstate = () => updateRoute(); +updateRoute(); +``` + +> 筆記:我們在這裡使用[箭頭函式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions),簡短地宣告 `popstate` 事件處理器。它與正規的函式的功能是一樣的。 + +這是關於箭頭函式的回想影片: + +[](https://youtube.com/watch?v=OP6eEbOj2sc "箭頭函式") + +> 點擊上方圖片以觀看關於箭頭函式的影片。 + +現在,試著點擊瀏覽器上的上一頁與下一頁,檢查這次模板是否正確地更新出來。 + +--- + +## 🚀 挑戰 + +加入新的模板與對應的關聯表,顯示出本應用程式第三頁的功能 ── 帳戶餘額。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/42?loc=zh_tw) + +## 複習與自學 + +網頁路由是網頁開發中很棘手的部分,特別是將網頁切換轉變為單一頁面應用程式(Single Page Application)。閱讀關於[Azure Static Web App 提供服務的方式](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=academic-13441-cxa)以處理網頁路由。你能解釋為什麼文件上的某些決定會如此重要呢? + +## 作業 + +[增進網頁路由](assignment.zh-tw.md) diff --git a/7-bank-project/1-template-route/translations/assignment.nl.md b/7-bank-project/1-template-route/translations/assignment.nl.md new file mode 100644 index 00000000..6706bfdf --- /dev/null +++ b/7-bank-project/1-template-route/translations/assignment.nl.md @@ -0,0 +1,14 @@ +# Verbeter de routing + +## Instructies + +De routes-declaratie bevat momenteel alleen de te gebruiken sjabloon-ID. Maar bij het tonen van een nieuwe pagina is soms iets meer nodig. Laten we onze routeringsimplementatie verbeteren met twee extra functies: + +- Geef elk sjabloon een titel en werk de venstertitel bij met deze nieuwe titel wanneer de sjabloon verandert. +- Voeg een optie toe om wat code uit te voeren nadat de sjabloon is gewijzigd. Elke keer dat de dashboardpagina wordt weergegeven willen we `'Dashboard wordt weergegeven'` in de ontwikkelaarsconsole afdrukken. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| | De twee functies zijn geïmplementeerd en werken. Titel en codetoevoeging werken ook voor een nieuwe route die is toegevoegd in de `routes`-aangifte. | De twee functies werken, maar het gedrag is hard gecodeerd en kan niet worden geconfigureerd via de `routes`-aangifte. Het toevoegen van een derde route met toevoeging van titel en code werkt niet of gedeeltelijk. | Een van de functies ontbreekt of werkt niet goed. | \ No newline at end of file diff --git a/7-bank-project/1-template-route/translations/assignment.zh-tw.md b/7-bank-project/1-template-route/translations/assignment.zh-tw.md new file mode 100644 index 00000000..d9eb3b26 --- /dev/null +++ b/7-bank-project/1-template-route/translations/assignment.zh-tw.md @@ -0,0 +1,14 @@ +# 增進網頁路由 + +## 簡介 + +我們的網頁路由的定義只包含模板的 ID。但當顯示新的網頁頁面時,我們或許會用到更多東西。讓我們來增進我們的網頁路由方式,新增兩項功能: + +- 給各個模板標題,在模板切換後同時更新網頁視窗的標題。 +- 加入額外選項,在模板切換後執行特定程式。我們希望在切換到儀表板頁面時,在開發者命令欄顯示 `'Dashboard is shown'`。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------ | +| | 兩個新功能運作正常,標題與程式也能執行新的 `routes` 規則 | 兩個新功能運作正常,但行為是 hardcoded 上去而非使用 `routes` 規則。新的路由規則無法完整地運作 | 新功能不完全或不正常運行 | diff --git a/7-bank-project/2-forms/README.md b/7-bank-project/2-forms/README.md index cde754ea..44faf61b 100644 --- a/7-bank-project/2-forms/README.md +++ b/7-bank-project/2-forms/README.md @@ -27,7 +27,7 @@ curl http://localhost:5000/api The `<form>` element encapsulates a section of an HTML document where the user can input and submit data with interactive controls. There are all sorts of user interface (UI) controls that can be used within a form, the most common one being the `<input>` and the `<button>` elements. -There are a lot of different [types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) of `<input>`, for example to create a field where the user can enter its username you can use: +There are a lot of different [types](https://developer.mozilla.org/docs/Web/HTML/Element/input) of `<input>`, for example to create a field where the user can enter its username you can use: ```html <input id="username" name="username" type="text"> @@ -35,9 +35,9 @@ There are a lot of different [types](https://developer.mozilla.org/en-US/docs/We The `name` attribute will be used as the property name when the form data will be sent over. The `id` attribute is used to associate a `<label>` with the form control. -> Take a look at the whole list of [`<input>` types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) and [other form controls](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls) to get an idea of all the native UI elements you can use when building your UI. +> Take a look at the whole list of [`<input>` types](https://developer.mozilla.org/docs/Web/HTML/Element/input) and [other form controls](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) to get an idea of all the native UI elements you can use when building your UI. -✅ Note that `<input>` is an [empty element](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element) on which you should *not* add a matching closing tag. You can however use the self-closing `<input/>` notation, but it's not required. +✅ Note that `<input>` is an [empty element](https://developer.mozilla.org/docs/Glossary/Empty_element) on which you should *not* add a matching closing tag. You can however use the self-closing `<input/>` notation, but it's not required. The `<button>` element within a form is a bit special. If you do not specify its `type` attribute, it will automatically submit the form data to the server when pressed. Here are the possible `type` values: @@ -68,7 +68,7 @@ If you take a closer look, you can notice that we also added a `<label>` element - By associating a label to a form control, it helps users using assistive technologies (like a screen reader) to understand what data they're expected to provide. - You can click on the label to directly put focus on the associated input, making it easier to reach on touch-screen based devices. -> [Accessibility](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility) on the web is a very important topic that's often overlooked. Thanks to [semantic HTML elements](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) it's not difficult to create accessible content if you use them properly. You can [read more about accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility) to avoid common mistakes and become a responsible developer. +> [Accessibility](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) on the web is a very important topic that's often overlooked. Thanks to [semantic HTML elements](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) it's not difficult to create accessible content if you use them properly. You can [read more about accessibility](https://developer.mozilla.org/docs/Web/Accessibility) to avoid common mistakes and become a responsible developer. Now we'll add a second form for the registration, just below the previous one: @@ -156,7 +156,7 @@ function register() { } ``` -Here we retrieve the form element using `getElementById()` and use the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) helper to extract the values from form controls as a set of key/value pairs. Then we convert the data to a regular object using [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) and finally serialize the data to [JSON](https://www.json.org/json-en.html), a format commonly used for exchanging data on the web. +Here we retrieve the form element using `getElementById()` and use the [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) helper to extract the values from form controls as a set of key/value pairs. Then we convert the data to a regular object using [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) and finally serialize the data to [JSON](https://www.json.org/json-en.html), a format commonly used for exchanging data on the web. The data is now ready to be sent to the server. Create a new function named `createAccount`: @@ -175,7 +175,7 @@ async function createAccount(account) { } ``` -What's this function doing? First, notice the `async` keyword here. This means that the function contains code that will execute [**asynchronously**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). When used along the `await` keyword, it allows waiting for asynchronous code to execute - like waiting for the server response here - before continuing. +What's this function doing? First, notice the `async` keyword here. This means that the function contains code that will execute [**asynchronously**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). When used along the `await` keyword, it allows waiting for asynchronous code to execute - like waiting for the server response here - before continuing. Here's a quick video about `async/await` usage: @@ -219,7 +219,7 @@ async function register() { } ``` -That was a bit long but we got there! If you open your [browser developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools), and try registering a new account, you should not see any change on the web page but a message will appear in the console confirming that everything works. +That was a bit long but we got there! If you open your [browser developer tools](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools), and try registering a new account, you should not see any change on the web page but a message will appear in the console confirming that everything works.  @@ -227,15 +227,15 @@ That was a bit long but we got there! If you open your [browser developer tools] ## Data validation -If you try to register a new account without setting an username first, you can see that the server returns an error with status code [400 (Bad Request)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). +If you try to register a new account without setting an username first, you can see that the server returns an error with status code [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). -Before sending data to a server it's a good practice to [validate the form data](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) beforehand when possible, to make sure you send a valid request. HTML5 forms controls provides built-in validation using various attributes: +Before sending data to a server it's a good practice to [validate the form data](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) beforehand when possible, to make sure you send a valid request. HTML5 forms controls provides built-in validation using various attributes: - `required`: the field needs to be filled otherwise the form cannot be submitted. - `minlength` and `maxlength`: defines the minimum and maximum number of characters in text fields. - `min` and `max`: defines the minimum and maximum value of a numerical field. -- `type`: defines the kind of data expected, like `number`, `email`, `file` or [other built-in types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). This attribute may also change the visual rendering of the form control. -- `pattern`: allows to define a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) pattern to test if the entered data is valid or not. +- `type`: defines the kind of data expected, like `number`, `email`, `file` or [other built-in types](https://developer.mozilla.org/docs/Web/HTML/Element/input). This attribute may also change the visual rendering of the form control. +- `pattern`: allows to define a [regular expression](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) pattern to test if the entered data is valid or not. > Tip: you can customize the look of your form controls depending if they're valid or not using the `:valid` and `:invalid` CSS pseudo-classes. diff --git a/7-bank-project/2-forms/translations/README.es.md b/7-bank-project/2-forms/translations/README.es.md index c251ceb7..7e9f7c39 100644 --- a/7-bank-project/2-forms/translations/README.es.md +++ b/7-bank-project/2-forms/translations/README.es.md @@ -25,7 +25,7 @@ curl http://localhost:5000/api El elemento `<form>` encapsula una sección de un documento HTML donde el usuario puede ingresar y enviar datos con controles interactivos. Hay todo tipo de controles de interfaz de usuario (UI) que se pueden usar dentro de un formulario, siendo el más común los elementos `<input>` y `<button>`. -Hay muchos [types diferentes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) de `<input>`, por ejemplo, para crear un campo donde el usuario puede ingresar su nombre de usuario que puede usar: +Hay muchos [types diferentes](https://developer.mozilla.org/docs/Web/HTML/Element/input) de `<input>`, por ejemplo, para crear un campo donde el usuario puede ingresar su nombre de usuario que puede usar: ```html @@ -34,9 +34,9 @@ Hay muchos [types diferentes](https://developer.mozilla.org/en-US/docs/Web/HTML/ El atributo `name` se usa para identificar el control y se usará como el nombre de la propiedad cuando se envíen los datos del formulario. -> Eche un vistazo a la lista completa de [`<input>` tipos](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) y [otros controles de formulario](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls) para tener una idea de todos los elementos nativos de la interfaz de usuario que puede utilizar al crear su interfaz de usuario. +> Eche un vistazo a la lista completa de [`<input>` tipos](https://developer.mozilla.org/docs/Web/HTML/Element/input) y [otros controles de formulario](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) para tener una idea de todos los elementos nativos de la interfaz de usuario que puede utilizar al crear su interfaz de usuario. -✅ Tenga en cuenta que `<input>` es un [elemento vacío](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element) en el que *no* debe agregar una etiqueta de cierre coincidente. Sin embargo, puede usar la notación de cierre automático `<input/>`, pero no es necesaria. +✅ Tenga en cuenta que `<input>` es un [elemento vacío](https://developer.mozilla.org/docs/Glossary/Empty_element) en el que *no* debe agregar una etiqueta de cierre coincidente. Sin embargo, puede usar la notación de cierre automático `<input/>`, pero no es necesaria. El elemento `<button>` dentro de un formulario es un poco especial. Si no especifica su atributo `type`, automáticamente enviará los datos del formulario al servidor cuando se presione. Estos son los posibles valores de tipo: @@ -68,7 +68,7 @@ Si observa más de cerca, puede notar que también agregamos un elemento `<label - Al asociar una etiqueta a un control de formulario, ayuda a los usuarios que utilizan tecnologías de asistencia (como un lector de pantalla) a comprender qué datos se espera que proporcionen. - Puede hacer clic en la etiqueta para centrarse directamente en la entrada asociada, lo que facilita el acceso a los dispositivos con pantalla táctil. -> [Accesibilidad](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility) en la web es un tema muy importante que a menudo se pasa por alto. Gracias a los [elementos semánticos HTML5](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) no es difícil crear contenido accesible si los usas correctamente. Puede [leer más sobre accesibilidad](https://developer.mozilla.org/en-US/docs/Web/Accessibility) para evitar errores comunes y convertirse en un desarrollador responsable. +> [Accesibilidad](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) en la web es un tema muy importante que a menudo se pasa por alto. Gracias a los [elementos semánticos HTML5](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) no es difícil crear contenido accesible si los usas correctamente. Puede [leer más sobre accesibilidad](https://developer.mozilla.org/docs/Web/Accessibility) para evitar errores comunes y convertirse en un desarrollador responsable. Ahora agregaremos un segundo formulario para el registro, justo debajo del anterior: @@ -157,7 +157,7 @@ function register() { } ``` -Aquí recuperamos el elemento del formulario usando `getElementById()` y usamos el ayudante [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) para extraer los valores del formulario controles como un conjunto de pares clave/valor. Luego convertimos los datos a un objeto regular usando [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) y finalmente serialice los datos en [JSON](https://www.json.org/json-en.html), un formato que se utiliza comúnmente para intercambiar datos en la web. +Aquí recuperamos el elemento del formulario usando `getElementById()` y usamos el ayudante [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) para extraer los valores del formulario controles como un conjunto de pares clave/valor. Luego convertimos los datos a un objeto regular usando [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) y finalmente serialice los datos en [JSON](https://www.json.org/json-en.html), un formato que se utiliza comúnmente para intercambiar datos en la web. Los datos ahora están listos para enviarse al servidor. Cree una nueva función llamada `createAccount`: @@ -177,7 +177,7 @@ async function createAccount(account) { } ``` -¿Qué hace esta función? Primero, observe la palabra clave `async` aquí. Esto significa que la función contiene código que se ejecutará [** asincrónicamente**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Cuando se usa junto con la palabra clave `await`, permite esperar a que se ejecute el código asincrónico, como esperar la respuesta del servidor aquí, antes de continuar. +¿Qué hace esta función? Primero, observe la palabra clave `async` aquí. Esto significa que la función contiene código que se ejecutará [** asincrónicamente**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Cuando se usa junto con la palabra clave `await`, permite esperar a que se ejecute el código asincrónico, como esperar la respuesta del servidor aquí, antes de continuar. Aquí hay un video rápido sobre el uso de `async/await`: @@ -219,7 +219,7 @@ async function register() { } ``` -¡Eso fue un poco largo pero llegamos allí! Si abre sus [herramientas de desarrollo del navegador](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools) e intenta registrar una nueva cuenta, no debería ver ningún cambio en la página web pero aparecerá un mensaje en la consola confirmando que todo funciona. +¡Eso fue un poco largo pero llegamos allí! Si abre sus [herramientas de desarrollo del navegador](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) e intenta registrar una nueva cuenta, no debería ver ningún cambio en la página web pero aparecerá un mensaje en la consola confirmando que todo funciona.  @@ -227,15 +227,15 @@ async function register() { ## Validación de datos -Si intenta registrar una nueva cuenta sin establecer un nombre de usuario primero, puede ver que el servidor devuelve un error con el código de estado [400 (Solicitud incorrecta)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). +Si intenta registrar una nueva cuenta sin establecer un nombre de usuario primero, puede ver que el servidor devuelve un error con el código de estado [400 (Solicitud incorrecta)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). -Antes de enviar datos a un servidor, es una buena práctica [validar los datos del formulario](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) de antemano cuando sea posible, para asegurarse de enviar un solicitud válida. Los controles de formularios HTML5 proporcionan una validación incorporada utilizando varios atributos: +Antes de enviar datos a un servidor, es una buena práctica [validar los datos del formulario](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) de antemano cuando sea posible, para asegurarse de enviar un solicitud válida. Los controles de formularios HTML5 proporcionan una validación incorporada utilizando varios atributos: - `required`: el campo debe completarse; de lo contrario, el formulario no se podrá enviar - `minlength` y `maxlength`: define el número mínimo y máximo de caracteres en los campos de texto. - `min` y `max`: define el valor mínimo y máximo de un campo numérico. -- `type`: define el tipo de datos esperados, como `number`, `email`, `file` u [otros tipos integrados](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). Este atributo también puede cambiar la representación visual del control de formulario. -- `patrón`: permite definir un patrón [expresión regular](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) para probar si los datos ingresados son válidos o no. +- `type`: define el tipo de datos esperados, como `number`, `email`, `file` u [otros tipos integrados](https://developer.mozilla.org/docs/Web/HTML/Element/input). Este atributo también puede cambiar la representación visual del control de formulario. +- `patrón`: permite definir un patrón [expresión regular](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) para probar si los datos ingresados son válidos o no. > Consejo: puedes personalizar el aspecto de los controles de tu formulario dependiendo de si son válidos o no usando las pseudoclases CSS `:valid` y `:invalid`. diff --git a/7-bank-project/2-forms/translations/README.it.md b/7-bank-project/2-forms/translations/README.it.md index d6d85592..b97ff18d 100644 --- a/7-bank-project/2-forms/translations/README.it.md +++ b/7-bank-project/2-forms/translations/README.it.md @@ -27,7 +27,7 @@ curl http://localhost:5000/api L'elemento `<form>` incapsula una sezione di un documento HTML in cui l'utente può inserire e inviare dati con controlli interattivi. Esistono tutti i tipi di controlli dell'interfaccia utente (UI) che possono essere utilizzati all'interno di un form, i più comuni sono gli elementi `<input>` e `<button>`. -Esistono molti [tipi](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) diversi di `<input>`, ad esempio per creare un campo in cui l'utente può inserire il proprio nome utente si può utilizzare: +Esistono molti [tipi](https://developer.mozilla.org/docs/Web/HTML/Element/input) diversi di `<input>`, ad esempio per creare un campo in cui l'utente può inserire il proprio nome utente si può utilizzare: ```html <input id="username" name="username" type="text"> @@ -35,9 +35,9 @@ Esistono molti [tipi](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ L'attributo `name` verrà utilizzato come nome della proprietà quando verranno inviati i dati del form. L'attributo `id` viene utilizzato per associare un'etichetta (`<label>`) al relativo controllo nel form. -> Si dia un'occhiata all'intero elenco di [tipi di `<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) e [altri controlli del form](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls) per avere un'idea di tutti gli elementi nativi dell'interfaccia utente che si possono utilizzare durante la creazione della propria interfaccia utente. +> Si dia un'occhiata all'intero elenco di [tipi di `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) e [altri controlli del form](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) per avere un'idea di tutti gli elementi nativi dell'interfaccia utente che si possono utilizzare durante la creazione della propria interfaccia utente. -✅ Si noti che `<input>` è un [elemento vuoto](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element) su cui *non* si dovrebbe aggiungere un tag di chiusura corrispondente. È comunque possibile utilizzare la notazione a chiusura automatica `<input/>` , ma non è richiesta. +✅ Si noti che `<input>` è un [elemento vuoto](https://developer.mozilla.org/docs/Glossary/Empty_element) su cui *non* si dovrebbe aggiungere un tag di chiusura corrispondente. È comunque possibile utilizzare la notazione a chiusura automatica `<input/>` , ma non è richiesta. L'elemento `<button>` all'interno di un form è un po' speciale. Se non si specifica il suo attributo di tipo (`type`) , invierà automaticamente i dati del form al server quando viene premuto. Ecco i possibili valori di `type` : @@ -68,7 +68,7 @@ Se si guarda più attentamente, si può notare che è stato aggiunto anche un el - Associaer un'etichetta a un controllo in un form, aiuta gli utenti che utilizzano tecnologie assistite (come unlettore di schremo) a capire quali dati dovrebbero fornire. - È possibile fare clic sull'etichetta per portare direttamente il focus sull'input associato, rendendolo più facile da raggiungere su dispositivi basati su touch screen. -> [L'accessibilità](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility) sul Web è un argomento molto importante che spesso viene trascurato. Grazie agli [elementi HTML semantici](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) non è difficile creare contenuti accessibili se usati correttamente. Si può [leggere di più sull'accessibilità](https://developer.mozilla.org/en-US/docs/Web/Accessibility) per evitare errori comuni e diventare uno sviluppatore responsabile. +> [L'accessibilità](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) sul Web è un argomento molto importante che spesso viene trascurato. Grazie agli [elementi HTML semantici](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) non è difficile creare contenuti accessibili se usati correttamente. Si può [leggere di più sull'accessibilità](https://developer.mozilla.org/docs/Web/Accessibility) per evitare errori comuni e diventare uno sviluppatore responsabile. Ora si aggiungerà un secondo modulo per la registrazione, appena sotto il precedente: @@ -155,7 +155,7 @@ function register() { } ``` -Qui si recupera l'elemento form utilizzando `getElementById()` e si utilizza il [metodo di supporto FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) per estrarre i valori dai controlli del forma come un insieme di coppie chiave/valore. Quindi si convertono i dati in un oggetto normale utilizzando [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) e infine si serializzano i dati in [JSON](https://www.json.org/json-en.html), un formato comunemente utilizzato per lo scambio di dati sul web. +Qui si recupera l'elemento form utilizzando `getElementById()` e si utilizza il [metodo di supporto FormData](https://developer.mozilla.org/docs/Web/API/FormData) per estrarre i valori dai controlli del forma come un insieme di coppie chiave/valore. Quindi si convertono i dati in un oggetto normale utilizzando [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) e infine si serializzano i dati in [JSON](https://www.json.org/json-en.html), un formato comunemente utilizzato per lo scambio di dati sul web. I dati sono ora pronti per essere inviati al server. Creare una nuova funzione denominata `createAccount`: @@ -174,7 +174,7 @@ async function createAccount(account) { } ``` -Cosa fa questa funzione? Per prima cosa notare la parola chiave `async`. Ciò significa che la funzione contiene codice che verrà eseguito [**in modo asincrono**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Quando viene utilizzato insieme alla parola chiave `await`, consente di attendere l'esecuzione del codice asincrono, come l'attesa della risposta del server qui, prima di continuare. +Cosa fa questa funzione? Per prima cosa notare la parola chiave `async`. Ciò significa che la funzione contiene codice che verrà eseguito [**in modo asincrono**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Quando viene utilizzato insieme alla parola chiave `await`, consente di attendere l'esecuzione del codice asincrono, come l'attesa della risposta del server qui, prima di continuare. Ecco un breve video sull'utilizzo di `async/await`: @@ -218,7 +218,7 @@ async function register() { } ``` -È stato un po' lungo ma si è arrivati! Se si apre [strumenti di sviluppo del browser](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools) e si prava a registrare un nuovo account, non si dovrebbe vedere alcun cambiamento nella pagina web ma apparirà un messaggio nella console che conferma che tutto funziona. +È stato un po' lungo ma si è arrivati! Se si apre [strumenti di sviluppo del browser](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) e si prava a registrare un nuovo account, non si dovrebbe vedere alcun cambiamento nella pagina web ma apparirà un messaggio nella console che conferma che tutto funziona.  @@ -226,15 +226,15 @@ async function register() { ## Convalida dati -Se si prova a registrare un nuovo account senza prima impostare un nome utente, si può vedere che il server restituisce un errore con codice di stato [400 Bad Request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).), (richiesta non valida) +Se si prova a registrare un nuovo account senza prima impostare un nome utente, si può vedere che il server restituisce un errore con codice di stato [400 Bad Request](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).), (richiesta non valida) -Prima di inviare i dati a un server è buona norma [convalidare i dati del modulo](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) in anticipo quando possibile, per assicurarsi di inviare una richiesta valida. I controlli dei form HTML5 forniscono la convalida incorporata utilizzando vari attributi: +Prima di inviare i dati a un server è buona norma [convalidare i dati del modulo](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) in anticipo quando possibile, per assicurarsi di inviare una richiesta valida. I controlli dei form HTML5 forniscono la convalida incorporata utilizzando vari attributi: - `requested`: il campo deve essere compilato altrimenti il modulo non può essere inviato. - `minlength` e `maxlength`: definisce il numero minimo e massimo di caratteri nei campi di testo. - `min` e `max`: definisce il valore minimo e massimo di un campo numerico. -- `type`: definisce il tipo di dati attesi, come `number`, `email`, `file` o [altri tipi incorporati](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). Questo attributo può anche modificare il rendering visivo del form. -- `pattern`: permette di definire un modello di [espressione regolare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) per verificare se i dati inseriti sono validi o meno. +- `type`: definisce il tipo di dati attesi, come `number`, `email`, `file` o [altri tipi incorporati](https://developer.mozilla.org/docs/Web/HTML/Element/input). Questo attributo può anche modificare il rendering visivo del form. +- `pattern`: permette di definire un modello di [espressione regolare](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) per verificare se i dati inseriti sono validi o meno. > Suggerimento: si può personalizzare l'aspetto dei controlli del form a seconda che siano validi o meno utilizzando le pseudo-classi CSS `:valid` e `:invalid` . diff --git a/7-bank-project/2-forms/translations/README.ko.md b/7-bank-project/2-forms/translations/README.ko.md index 7288e01f..b927ee6b 100644 --- a/7-bank-project/2-forms/translations/README.ko.md +++ b/7-bank-project/2-forms/translations/README.ko.md @@ -27,7 +27,7 @@ curl http://localhost:5000/api `<form>` 요소는 사용자가 대화형 컨트롤을 사용하여 데이터를 입력하고 제출할 수 있는 HTML 문서의 섹션을 캡슐화합니다. 폼 내에서 쓸 수 있는 모든 종류의 사용자 인터페이스(UI) 컨트롤이 있으며, 가장 일반적인 컨트롤은 `<input>`과 `<button>` 요소입니다. -`<input>`에는 다양한 [types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)이 많이 있습니다, 예를 들어 사용자 이름으로 입력 가능한 필드를 만들려면 다음과 같이 사용할 수 있습니다: +`<input>`에는 다양한 [types](https://developer.mozilla.org/docs/Web/HTML/Element/input)이 많이 있습니다, 예를 들어 사용자 이름으로 입력 가능한 필드를 만들려면 다음과 같이 사용할 수 있습니다: ```html <input name="username" type="text"> @@ -35,9 +35,9 @@ curl http://localhost:5000/api `name` 속성은 컨트롤을 식별하는 데 사용되고 폼 데이터를 전송할 때 속성 이름으로 사용됩니다. -> UI를 작성할 때 쓸 수 있는 모든 네이티브 UI 요소에 대한 아이디어를 얻으려면 [`<input>` types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)과 [other form controls](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls)의 전체 목록을 찾아봅시다. +> UI를 작성할 때 쓸 수 있는 모든 네이티브 UI 요소에 대한 아이디어를 얻으려면 [`<input>` types](https://developer.mozilla.org/docs/Web/HTML/Element/input)과 [other form controls](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls)의 전체 목록을 찾아봅시다. -✅ `<input>`은 닫는 태그를 맞추지 *않는* [empty element](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element)입니다. 자동으로-닫는 `<input/>` 표기법을 사용할 수 있지만, 필수는 아닙니다. +✅ `<input>`은 닫는 태그를 맞추지 *않는* [empty element](https://developer.mozilla.org/docs/Glossary/Empty_element)입니다. 자동으로-닫는 `<input/>` 표기법을 사용할 수 있지만, 필수는 아닙니다. 폼 내의 `<button>` 요소는 약간 특별합니다. `type` 속성을 지정하지 않으면, 눌렀을 때 폼 데이터가 자동으로 서버에 제출됩니다. 가능한 `type` 값은 다음과 같습니다: @@ -68,7 +68,7 @@ curl http://localhost:5000/api - 라벨을 폼 컨트롤에 연결하면, (화면 판독기와 같은) 보조 기술을 사용하는 사용자가 받는 것으로 예상되는 데이터를 이해하는 데 도움이 됩니다. - 라벨을 클릭하여 연결된 입력에 직접 맞출 수 있으므로, 터치-스크린 기반 장치에서 더 쉽게 접근할 수 있습니다. -> 웹에서의 [Accessibility](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility)은 종종 간과되는 매우 중요한 주제입니다. [HTML5 semantic elements](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) 덕분에 이를 적절하게 사용한다면 접근성 콘텐츠로 만드는 것은 어렵지 않습니다. 일반적인 실수를 피하고 책임있는 개발자가 되기 위해 [accessibility에 대하여 읽을 수](https://developer.mozilla.org/en-US/docs/Web/Accessibility) 있습니다. +> 웹에서의 [Accessibility](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility)은 종종 간과되는 매우 중요한 주제입니다. [HTML5 semantic elements](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) 덕분에 이를 적절하게 사용한다면 접근성 콘텐츠로 만드는 것은 어렵지 않습니다. 일반적인 실수를 피하고 책임있는 개발자가 되기 위해 [accessibility에 대하여 읽을 수](https://developer.mozilla.org/docs/Web/Accessibility) 있습니다. 이제 이전 항목의 바로 아래에, 가입을 위한 두번째 폼을 추가합니다: @@ -156,7 +156,7 @@ function register() { } ``` -여기서는 `getElementById()`를 사용하여 폼 요소를 검색하고, [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) 헬퍼를 사용하여 키/값 쌍 집합으로 폼 컨트롤에서 값을 추출합니다. 그러고 [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)를 사용하여 데이터를 일반 객체로 변환하여 최종적으로 웹에서 데이터를 교환할 때, 일반적으로 사용되는 포맷인 [JSON](https://www.json.org/json-en.html)으로 데이터를 직렬화합니다. +여기서는 `getElementById()`를 사용하여 폼 요소를 검색하고, [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) 헬퍼를 사용하여 키/값 쌍 집합으로 폼 컨트롤에서 값을 추출합니다. 그러고 [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)를 사용하여 데이터를 일반 객체로 변환하여 최종적으로 웹에서 데이터를 교환할 때, 일반적으로 사용되는 포맷인 [JSON](https://www.json.org/json-en.html)으로 데이터를 직렬화합니다. 데이터는 이제 서버에 보낼 준비가 되었습니다. `createAccount`라고 지은 새로운 함수를 만듭니다: @@ -175,7 +175,7 @@ async function createAccount(account) { } ``` -이 함수는 어떤 일을 할까요? 먼저, 여기있는 `async` 키워드를 확인하세요. 이 함수는 [**asynchronously**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)하게 실행하는 코드가 포함되어 있다는 것을 의미합니다. `await` 키워드와 함께 사용하면, 비동기 코드가 실행될 때까지 기다릴 수 있습니다 - 여기에서 서버의 응답을 기다리는 것과 같습니다 - 계속하기 전에. +이 함수는 어떤 일을 할까요? 먼저, 여기있는 `async` 키워드를 확인하세요. 이 함수는 [**asynchronously**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function)하게 실행하는 코드가 포함되어 있다는 것을 의미합니다. `await` 키워드와 함께 사용하면, 비동기 코드가 실행될 때까지 기다릴 수 있습니다 - 여기에서 서버의 응답을 기다리는 것과 같습니다 - 계속하기 전에. 여기는 ``async/await` 사용 방식에 대한 간단한 영상입니다: @@ -217,7 +217,7 @@ async function register() { } ``` -조금 길지만 도착했습니다! [browser developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools)를 열고, 새 계정을 가입하면, 웹 페이지에 변경 사항이 표시되지 않으면서 콘솔에 작동을 확인할 메시지가 나타납니다. +조금 길지만 도착했습니다! [browser developer tools](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools)를 열고, 새 계정을 가입하면, 웹 페이지에 변경 사항이 표시되지 않으면서 콘솔에 작동을 확인할 메시지가 나타납니다.  @@ -225,15 +225,15 @@ async function register() { ## Data 검증하기 -사용자 이름을 먼저 설정하지 않고 새 계정을 가입하려하면, 서버에서 상태 코드 [400 (Bad Request)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) 오류를 반환하는 것으로 볼 수 있습니다. +사용자 이름을 먼저 설정하지 않고 새 계정을 가입하려하면, 서버에서 상태 코드 [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) 오류를 반환하는 것으로 볼 수 있습니다. -데이터를 서버로 보내기 전에 할 수 있다면, 유요한 요청을 보낼 수 있도록, 미리 [validate the form data](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation)를 실습하는 것이 좋습니다. HTML5 포맷 컨트롤은 다양한 속성을 사용하여 빌트인 유효성 검사를 제공합니다: +데이터를 서버로 보내기 전에 할 수 있다면, 유요한 요청을 보낼 수 있도록, 미리 [validate the form data](https://developer.mozilla.org/docs/Learn/Forms/Form_validation)를 실습하는 것이 좋습니다. HTML5 포맷 컨트롤은 다양한 속성을 사용하여 빌트인 유효성 검사를 제공합니다: - `required`: 필드를 채워야하며 안 채운다면 폼을 제출할 수 없습니다. - `minlength`와 `maxlength`: 텍스트 입력의 최소 및 최대 문자 수를 정의합니다. - `min`과 `max`: 숫자 필드의 최소값과 최대값을 정의합니다. -- `type`: `number`, `email`, `file` 또는 [other built-in types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)처럼, 예상되는 데이터의 종류를 정의합니다. 이 속성은 폼 컨트롤의 비주얼 렌더링을 바꿀 수도 있습니다. -- `pattern`: 입력된 데이터가 유효한지 테스트하기 위해 [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) 패턴을 정의할 수 있습니다. +- `type`: `number`, `email`, `file` 또는 [other built-in types](https://developer.mozilla.org/docs/Web/HTML/Element/input)처럼, 예상되는 데이터의 종류를 정의합니다. 이 속성은 폼 컨트롤의 비주얼 렌더링을 바꿀 수도 있습니다. +- `pattern`: 입력된 데이터가 유효한지 테스트하기 위해 [regular expression](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) 패턴을 정의할 수 있습니다. > Tip: 유효하거나 `:valid`와 `:invalid` CSS pseudo-classes를 사용하지 않는 여부에 따라 폼 컨트롤의 모양을 커스텀할 수 있습니다. diff --git a/7-bank-project/2-forms/translations/README.ms.md b/7-bank-project/2-forms/translations/README.ms.md index f1498eb1..8899d0f6 100644 --- a/7-bank-project/2-forms/translations/README.ms.md +++ b/7-bank-project/2-forms/translations/README.ms.md @@ -27,7 +27,7 @@ curl http://localhost:5000/api Elemen `<form>` merangkumi bahagian dokumen HTML di mana pengguna dapat memasukkan dan menyerahkan data dengan kawalan interaktif. Terdapat pelbagai jenis kawalan antara muka pengguna (UI) yang dapat digunakan dalam bentuk, yang paling umum adalah elemen `<input>` dan elemen `<button>`. -Terdapat banyak [jenis yang berbeza](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) dari `<input>`, misalnya untuk membuat bidang di mana pengguna boleh memasukkan nama penggunanya yang boleh anda gunakan: +Terdapat banyak [jenis yang berbeza](https://developer.mozilla.org/docs/Web/HTML/Element/input) dari `<input>`, misalnya untuk membuat bidang di mana pengguna boleh memasukkan nama penggunanya yang boleh anda gunakan: ```html <input id="username" name="username" type="text"> @@ -35,9 +35,9 @@ Terdapat banyak [jenis yang berbeza](https://developer.mozilla.org/en-US/docs/We Atribut `name` akan digunakan sebagai nama harta ketika data borang akan dihantar. Atribut `id` digunakan untuk mengaitkan` <label>` dengan kawalan bentuk. -> Lihat keseluruhan senarai [`<input>` types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) dan [kawalan bentuk lain](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls) untuk mendapatkan idea tentang semua elemen UI asli yang boleh anda gunakan semasa membina UI anda. +> Lihat keseluruhan senarai [`<input>` types](https://developer.mozilla.org/docs/Web/HTML/Element/input) dan [kawalan bentuk lain](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) untuk mendapatkan idea tentang semua elemen UI asli yang boleh anda gunakan semasa membina UI anda. -✅ Perhatikan bahawa `<input>` adalah [elemen kosong](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element) di mana anda seharusnya *tidak* menambahkan tag penutup yang sepadan. Anda bagaimanapun boleh menggunakan notasi `<input/>` tutup sendiri, tetapi tidak diperlukan. +✅ Perhatikan bahawa `<input>` adalah [elemen kosong](https://developer.mozilla.org/docs/Glossary/Empty_element) di mana anda seharusnya *tidak* menambahkan tag penutup yang sepadan. Anda bagaimanapun boleh menggunakan notasi `<input/>` tutup sendiri, tetapi tidak diperlukan. Elemen `<button>` dalam bentuk agak istimewa. Sekiranya anda tidak menentukan atribut `type`, ia akan secara automatik mengirimkan data borang ke pelayan ketika ditekan. Berikut adalah nilai `type` yang mungkin: @@ -68,7 +68,7 @@ Sekiranya anda melihat lebih dekat, anda dapat melihat bahawa kami juga menambah - Dengan mengaitkan label dengan kawalan bentuk, ia membantu pengguna menggunakan teknologi bantu (seperti pembaca skrin) untuk memahami data apa yang diharapkan dapat mereka berikan. - Anda dapat mengklik label untuk memberi fokus langsung pada input yang berkaitan, sehingga lebih mudah dijangkau pada peranti berdasarkan layar sentuh. -> [Kebolehcapaian](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility) di web adalah topik yang sangat penting yang sering diabaikan. Terima kasih kepada [elemen HTML semantik](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML) tidak sukar untuk membuat kandungan yang boleh diakses jika anda menggunakannya dengan betul. Anda boleh [baca lebih lanjut mengenai kebolehaksesan](https://developer.mozilla.org/en-US/docs/Web/Accessibility) untuk mengelakkan kesilapan biasa dan menjadi pembangun yang bertanggungjawab. +> [Kebolehcapaian](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) di web adalah topik yang sangat penting yang sering diabaikan. Terima kasih kepada [elemen HTML semantik](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) tidak sukar untuk membuat kandungan yang boleh diakses jika anda menggunakannya dengan betul. Anda boleh [baca lebih lanjut mengenai kebolehaksesan](https://developer.mozilla.org/docs/Web/Accessibility) untuk mengelakkan kesilapan biasa dan menjadi pembangun yang bertanggungjawab. Sekarang kita akan menambah borang kedua untuk pendaftaran, tepat di bawah yang sebelumnya: @@ -156,7 +156,7 @@ function register() { } ``` -Di sini kita mengambil elemen borang menggunakan `getElementById()` dan menggunakan pembantu [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) untuk mengekstrak nilai dari borang kawalan sebagai satu set pasangan kunci / nilai. Kemudian kami menukar data ke objek biasa menggunakan [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) dan akhirnya bersiri data ke [JSON](https://www.json.org/json-en.html), format yang biasa digunakan untuk pertukaran data di web. +Di sini kita mengambil elemen borang menggunakan `getElementById()` dan menggunakan pembantu [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) untuk mengekstrak nilai dari borang kawalan sebagai satu set pasangan kunci / nilai. Kemudian kami menukar data ke objek biasa menggunakan [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) dan akhirnya bersiri data ke [JSON](https://www.json.org/json-en.html), format yang biasa digunakan untuk pertukaran data di web. Data kini siap dihantar ke pelayan. Buat fungsi baru bernama `createAccount`: @@ -175,7 +175,7 @@ async function createAccount(account) { } ``` -Apakah fungsi ini? Pertama, perhatikan kata kunci `async` di sini. Ini bermaksud bahawa fungsi tersebut mengandungi kod yang akan menjalankan [**asynchronously**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). Apabila digunakan di sepanjang kata kunci `await`, ia membolehkan menunggu kod tak segerak untuk dilaksanakan - seperti menunggu tindak balas pelayan di sini - sebelum meneruskan. +Apakah fungsi ini? Pertama, perhatikan kata kunci `async` di sini. Ini bermaksud bahawa fungsi tersebut mengandungi kod yang akan menjalankan [**asynchronously**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Apabila digunakan di sepanjang kata kunci `await`, ia membolehkan menunggu kod tak segerak untuk dilaksanakan - seperti menunggu tindak balas pelayan di sini - sebelum meneruskan. Berikut adalah video ringkas mengenai penggunaan `async/await`: @@ -219,7 +219,7 @@ async function register() { } ``` -Itu agak lama tetapi kami sampai di sana! Sekiranya anda membuka [alat pembangun penyemak imbas](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools), dan cuba mendaftarkan akaun baru, anda tidak akan melihat perubahan di laman web tetapi mesej akan muncul di konsol yang mengesahkan bahawa semuanya berfungsi. +Itu agak lama tetapi kami sampai di sana! Sekiranya anda membuka [alat pembangun penyemak imbas](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools), dan cuba mendaftarkan akaun baru, anda tidak akan melihat perubahan di laman web tetapi mesej akan muncul di konsol yang mengesahkan bahawa semuanya berfungsi.  @@ -227,15 +227,15 @@ Itu agak lama tetapi kami sampai di sana! Sekiranya anda membuka [alat pembangun ## Pengesahan data -Sekiranya anda cuba mendaftarkan akaun baru tanpa menetapkan nama pengguna terlebih dahulu, anda dapat melihat bahawa pelayan mengembalikan ralat dengan kod status [400 (Bad Request)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). +Sekiranya anda cuba mendaftarkan akaun baru tanpa menetapkan nama pengguna terlebih dahulu, anda dapat melihat bahawa pelayan mengembalikan ralat dengan kod status [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).). -Sebelum menghantar data ke pelayan, adalah amalan yang baik untuk [mengesahkan data borang](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) terlebih dahulu apabila mungkin, untuk memastikan anda menghantar permintaan yang sah. Kawalan borang HTML5 memberikan pengesahan terbina dalam menggunakan pelbagai atribut: +Sebelum menghantar data ke pelayan, adalah amalan yang baik untuk [mengesahkan data borang](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) terlebih dahulu apabila mungkin, untuk memastikan anda menghantar permintaan yang sah. Kawalan borang HTML5 memberikan pengesahan terbina dalam menggunakan pelbagai atribut: - `diperlukan`: bidang perlu diisi jika tidak, borang tidak dapat dihantar. - `minlength` dan` maxlength`: menentukan bilangan aksara minimum dan maksimum dalam bidang teks. - `min` dan `max`: menentukan nilai minimum dan maksimum medan angka. -- `type`: mentakrifkan jenis data yang diharapkan, seperti `number`, `email`, `file` atau [other built-in types](https://developer.mozilla.org/en-US/docs/Web/HTML/Elemen/input). Atribut ini juga dapat mengubah rendering visual kawalan bentuk. -- `pattern`: memungkinkan untuk menentukan [ungkapan biasa](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) untuk menguji sama ada data yang dimasukkan sah atau tidak. +- `type`: mentakrifkan jenis data yang diharapkan, seperti `number`, `email`, `file` atau [other built-in types](https://developer.mozilla.org/docs/Web/HTML/Elemen/input). Atribut ini juga dapat mengubah rendering visual kawalan bentuk. +- `pattern`: memungkinkan untuk menentukan [ungkapan biasa](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) untuk menguji sama ada data yang dimasukkan sah atau tidak. > Petua: anda boleh menyesuaikan rupa kawalan borang anda bergantung pada apakah itu sah atau tidak menggunakan kelas pseudo CSS `:invalid` dan`:valid`. diff --git a/7-bank-project/2-forms/translations/README.zh-tw.md b/7-bank-project/2-forms/translations/README.zh-tw.md new file mode 100644 index 00000000..086594de --- /dev/null +++ b/7-bank-project/2-forms/translations/README.zh-tw.md @@ -0,0 +1,297 @@ +# 建立銀行網頁應用程式 Part 2:登入與註冊表單 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/43?loc=zh_tw) + +### 大綱 + +在大多數當代網頁應用程式中,你可以建立自己的帳戶來擁有自己的私人空間。許多用戶在同一時間可以存取同一個網頁應用程式,你就必須有一套機制分開儲存不同用戶的資料並顯示適當的資訊。我們不會涉及到如何管理[用戶個資的安全](https://zh.wikipedia.org/wiki/%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81),它是個相當廣泛的主題,我們僅會確保每個用戶能在這款銀行應用上建立一到多個數位帳戶。 + +在這單元中,我們會使用 HTML 表單來新增登入與註冊的功能。我們會看到如何使用伺服器 API 傳遞資料,定義基本的用戶字串輸入之檢查機制。 + +### 開始之前 + +你需要完成第一單元 [HTML 模板與網頁路由](../../1-template-route/translations/README.zh-tw.md)的應用程式。你還需要安裝 [Node.js](https://nodejs.org) 與在本地端[運行伺服器 API](../../api/translations/README.zh-tw.md)以傳輸建立帳戶所需的資料。 + +你可以測試伺服器是否運作正常,在終端機內輸入指令: + +```sh +curl http://localhost:5000/api +# -> 會回傳結果 "Bank API v1.0.0" +``` + +--- + +## 表單與其控制 + +`<form>` 元素打包了 HTML 文件中使用者輸入與提交資料的地方。有許多種使用者介面(UI)以表單的方式呈現,最常見的內容會包含 `<input>` 與 `<button>` 元素。 + +有許多種 `<input>` 的[種類](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input),舉例來說,若要建立使用者輸入使用者名稱的地方,你可以: + +```html +<input id="username" name="username" type="text"> +``` + +`name` 屬性同時亦是表單傳輸資料的名稱。`id` 屬性是用來與 `<label>` 做表單控制(form control)的連接。 + +> 花點時間看看 [`<input>` 種類](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)的清單與[其他表單控制](https://developer.mozilla.org/en-US/docs/Learn/Forms/Other_form_controls),讓你在建立使用者介面時,有全部供你使用的原生 UI 元素可以參考。 + +✅ 紀錄一下 `<input>` 是種[空元素](https://developer.mozilla.org/en-US/docs/Glossary/Empty_element),你*不應該*在它後面加上對應的結束標籤。然而,你仍然可以在它的後面使用 `<input/>`,這沒有強制規定。 + +表單中的 `<button>` 元素是有些特別。如果你沒有指定它的 `type` 屬性,它會在你輸入文字時,自動地提交表單內容給伺服器。這邊有一些你可以設定的 `type` 內容: + +- `submit`: `<form>` 內的預設型態,按鈕會觸發表單提交這項行為。 +- `reset`: 按鈕會重置所有表單控制回初始狀態。 +- `button`: 在按鈕按下時不執行預設行為。你可以藉由 JavaScript 自由定義之後的動作。 + +### 課題 + +在 `login` 模板內加入表單。我們需要*使用者名稱(username)*的輸入框與*登入(Login)*的按鈕。 + +```html +<template id="login"> + <h1>Bank App</h1> + <section> + <h2>Login</h2> + <form id="loginForm"> + <label for="username">Username</label> + <input id="username" name="user" type="text"> + <button>Login</button> + </form> + </section> +</template> +``` + +如果你仔細地看,你會注意到我們在這裡還加了 `<label>` 元素。`<label>` 元素被用來新增文字到 UI 上,譬如說我們的使用者名稱。為了讓表單得以被閱讀,標籤是很重要的,此外它還有額外的優點: + +- 連結標籤到表單控制上,它能幫助使用者的額外工具,好比說螢幕報讀器,理解接下來該提供何種資料。 +- 你可以點擊標籤,它會跳轉到相對應的輸入框,讓使用觸控型裝置的用戶更容易操作。 + +> [網頁親和力](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility)是非常重要但常被忽視的主題。感謝[語義化 HTML 元素](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)的幫助,建立無障礙的網頁內容變得更加容易。你可以[閱讀更多有關網頁親和力的文章](https://developer.mozilla.org/en-US/docs/Web/Accessibility),避免觸犯到常見的錯誤並成為負責任的開發者。 + +現在,我們加入第二張表單給用戶註冊使用,就像前一張一樣: + +```html +<hr/> +<h2>Register</h2> +<form id="registerForm"> + <label for="user">Username</label> + <input id="user" name="user" type="text"> + <label for="currency">Currency</label> + <input id="currency" name="currency" type="text" value="$"> + <label for="description">Description</label> + <input id="description" name="description" type="text"> + <label for="balance">Current balance</label> + <input id="balance" name="balance" type="number" value="0"> + <button>Register</button> +</form> +``` + +藉由 `value` 屬性,我們可以定義輸入框內的預設值。 +注意一下 `balance` 的輸入類型為 `number`。它看起來與其他輸入框不一樣嗎?試著與它互動看看。 + +✅ 你能只利用鍵盤造訪表格,與表格互動嗎?你是如何做到的? + +## 提交資料給伺服器 + +現在我們有可以使用的 UI 了,下一個步驟要將資料送給我們的伺服器。讓我們來快速地測試一下程式:在點擊 *Login* 或 *Register* 按鈕後,發生了什麼事? + +你有注意到瀏覽器的網址列改變了嗎? + + + +`<form>` 預設的行為:使用 [GET 方法](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)提交表格,將表格資料接在網址後面,傳送給目前網址的伺服器。然而這個方法有一些缺點: + +- 資料大小有上限限制(大約 2000 字元) +- 可以直接在網址內看到資料(對密碼而言,這並不恰當) +- 它不能做檔案的上傳 + +這也是為什麼你需要將它轉換為 [POST 方法](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5),將表單資料存在 HTTP 請求的內容中。這樣就不會遇到上述的限制。 + +> POST 是常見的資料傳輸方法,[在一些特別的情況下](https://www.w3.org/2001/tag/doc/whenToUseGet.html),使用 GET 方法相對起來比較恰當。例如進行搜尋的時候。 + +### 課題 + +加入 `action` 與 `method` 屬性到註冊表單之中: + +```html +<form id="registerForm" action="//localhost:5000/api/accounts" method="POST"> +``` + +現在,試著以你的名字申請新的帳戶。在點擊 *Register* 按鈕後,你應該能看到像這樣的畫面: + + + +若所有事情都運作正常,伺服器應該會回應你的請求,附帶 [JSON](https://www.json.org/json-en.html) 包含著你剛建立的帳戶資料。 + +✅ 試著以相同名字再註冊一次。發生了什麼事? + +## 不重新載入地提交資料 + +你可能會注意到,這些行動間出現了一個小問題:在提交表單時,我們離開了網頁應用,瀏覽器又重新導回到伺服器的網址。我們試著避免網頁應用重新載入所有的頁面,做出[單一頁面應用程式 (SPA)](https://zh.wikipedia.org/zh-tw/%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8)。 + +為了讓傳遞資料給伺服器時,不發生頁面重新載入的情況,我們需要使用 JavaScript。 + +比起直接在 `<form>` 元素的 `action` 屬性加入網址,你可以使用 `javascript:` 字串接在程式語句前頭來執行自訂的行為。使用這方法也意味著你需要額外修改一些原本瀏覽器會做的行為。 + +- 接收表單資料 +- 轉換並編碼表單資料成合適的格式 +- 建立 HTTP 請求並傳遞給伺服器 + +### 課題 + +將註冊表單的 `action` 替換為: + +```html +<form id="registerForm" action="javascript:register()"> +``` + +開啟 `app.js`,加入新的函式 `register`: + +```js +function register() { + const registerForm = document.getElementById('registerForm'); + const formData = new FormData(registerForm); + const data = Object.fromEntries(formData); + const jsonData = JSON.stringify(data); +} +``` + +我們使用 `getElementById()` 蒐集表單的元素,使用 [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) 協助從表單控制中取出 key/value 的數據對。 +之後,利用 [`Object.fromEntries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) 轉換資料成正規物件,最後再將檔案轉成 [JSON](https://www.json.org/json-en.html) ── 一個在網路上常見的資料交換格式。 + +現在資料已經準備提交給伺服器了。建立新函式 `createAccount`: + +```js +async function createAccount(account) { + try { + const response = await fetch('//localhost:5000/api/accounts', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: account + }); + return await response.json(); + } catch (error) { + return { error: error.message || 'Unknown error' }; + } +} +``` + +這個函式做了什麼?首先,注意關鍵字 `async`,代表著函式包含了[**非同步化程式**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)。在與關鍵字 `await` 一起使用時,它會在繼續運行程式前,等待非同步的程式被執行,就像等待伺服器回應一樣。 + +這邊有關於使用 `async/await` 的影片: + +[](https://youtube.com/watch?v=YwmlRkrxvkk "Async 與 Await 管理 promises") + +> 點擊上方圖片以觀看關於 async/await 的影片。 + +我們使用 API `fetch()` 來傳送 JSON 資料給伺服器。這個方法需要使用兩個參數: + +- 伺服器的網址,在此使用 `//localhost:5000/api/accounts`。 +- 網頁請求的設定,就是我們定義 `POST` 方法與提供請求的 `body`。當我們傳輸 JSON 資料給伺服器,我們還需要在標頭的 `Content-Type` 定為 `application/json`,伺服器才知道該如何解讀裡面的內容。 + +當伺服器以 JSON 回應請求後,我們可以使用 `await response.json()` 來取得 JSON 的內容並回傳結果。注意在此為非同步程式的方法,我們使用關鍵字 `await` 回傳任何在解讀封包時產生的錯誤訊息。 + +現在,在函式 `register` 中呼叫 `createAccount()`: + +```js +const result = await createAccount(jsonData); +``` + +因為我們在這此使用了關鍵字 `await`,我們需要在註冊函式前新增關鍵字 `async`: + +```js +async function register() { +``` + +最後,我們儲存一些紀錄來檢查結果。最後的函式應該會如下方格式: + +```js +async function register() { + const registerForm = document.getElementById('registerForm'); + const formData = new FormData(registerForm); + const jsonData = JSON.stringify(Object.fromEntries(formData)); + const result = await createAccount(jsonData); + + if (result.error) { + return console.log('An error occured:', result.error); + } + + console.log('Account created!', result); +} +``` + +過程有些冗長,但我們達成了!當你開啟[瀏覽器開發者工具](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools),試著註冊新的帳戶,你應該能看到網頁並沒有改變,但命令欄中會顯示帳戶成功註冊的訊息。 + + + +✅ 你覺得傳給伺服器的資料是安全的嗎?其他人有辦法攔截網頁請求嗎?你可以閱讀 [HTTPS](https://en.wikipedia.org/wiki/HTTPS),了解更多關於安全的資料傳輸。 + +## 資料驗證 + +試著在註冊新帳戶時,不輸入你的使用者名稱,你會發現伺服器回傳了錯誤狀態訊息:[400 (Bad Request)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).)。 + +在傳輸資料給伺服器之前,最好先[驗證表單資料](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation),以確保我們傳送合法的網頁請求。 HTML5 表單控制內建包含了驗證方法,使用了多樣的屬性: controls provides built-in validation using various attributes: + +- `required`: 輸入框必須被填寫,否則表單不能被提交。 +- `minlength` 和 `maxlength`: 定義輸入框的文字下限與文字上限。 +- `min` 和 `max`: 定義輸入框的數字下限與數字上限。 +- `type`: 定義輸入框內的資料格式,例如`數字`、`email`、`檔案`或是[其他內建的格式](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)。這個屬性可能會改變表單控制的表現方法。 +- `pattern`: 允許定義[正規表示法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)的字串,測試輸入的內容是否滿足它。 + +> 提示:你可以自定義表單控制的呈現方法,利用 CSS pseudo-classes `:valid` 和 `:invalid` 判斷內容是否合理。 + +### 課題 + +在建立新的合法帳戶時,有兩個必須被填寫的輸入框:使用者名稱與資產狀態,而其他選項則是可有可無。現在更新表單的 HTML 語法,使用 `required` 屬性並標記提示在標籤中: + +```html +<label for="user">Username (required)</label> +<input id="user" name="user" type="text" required> +... +<label for="currency">Currency (required)</label> +<input id="currency" name="currency" type="text" value="$" required> +``` + +伺服器並沒設定輸入框的文字上限,定義合理的文字輸入上限是必要的。 + +在文字框內加入 `maxlength` 屬性: + +```html +<input id="user" name="user" type="text" maxlength="20" required> +... +<input id="currency" name="currency" type="text" value="$" maxlength="5" required> +... +<input id="description" name="description" type="text" maxlength="100"> +``` + +現在,如果文字框並沒有滿足我們所定義的規則時,在點擊了 *Register* 按鈕後,你會看到: + + + +這類在傳輸資料給伺服器*之前*的驗證系統稱之為**用戶端(client-side)**驗證。但注意有些資料是沒有辦法在傳輸前被驗證的。舉例來說,我們沒辦法在發出請求前,確認是否已經存在著一組相同姓名的帳戶。伺服器上額外的驗證措施就稱之為**伺服器端(server-side)**驗證。 + +通常這兩個驗證都需要去編寫,用戶端驗證能及時回饋給用戶,提升使用者體驗;伺服器端驗證確保你要處理的用戶資料是合理且安全的。 + +--- + +## 🚀 挑戰 + +當相同使用者名稱的帳戶已經存在時,在 HTML 上顯示錯誤訊息。 + +這邊有做過一些造型的最終登入頁面範本。 + + + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/44?loc=zh_tw) + +## 複習與自學 + +開發者在建立表單時需要發揮他們的創意,尤其是策畫資料驗證的規則。在 [CodePen](https://codepen.com) 上學習不同表單流程,你能發現什麼有趣且令人發想的表單嗎? + +## 作業 + +[造型化你的銀行程式](assignment.zh-tw.md) diff --git a/7-bank-project/2-forms/translations/assignment.nl.md b/7-bank-project/2-forms/translations/assignment.nl.md new file mode 100644 index 00000000..16ea959e --- /dev/null +++ b/7-bank-project/2-forms/translations/assignment.nl.md @@ -0,0 +1,13 @@ +# Style uw bank-app + +## Instructies + +Maak een nieuw `styles.css`-bestand en voeg er een link naar toe in uw huidige `index.html`-bestand. Voeg in het CSS-bestand dat u zojuist hebt gemaakt wat stijl toe om de pagina *Login* en *Dashboard* er netjes en opgeruimd uit te laten zien. Probeer een kleurenthema te maken om uw app een eigen branding te geven. + +> Tip: u kunt de HTML aanpassen en indien nodig nieuwe elementen en class toevoegen. + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- | +| | Alle pagina's zien er schoon en leesbaar uit, met een consistent kleurenthema en de verschillende secties vallen goed op. | Pagina's zijn opgemaakt maar zonder thema of met secties die niet duidelijk zijn afgebakend.| Pagina's missen stijl, de secties zien er ongeorganiseerd uit en de informatie is moeilijk te lezen. | \ No newline at end of file diff --git a/7-bank-project/2-forms/translations/assignment.zh-tw.md b/7-bank-project/2-forms/translations/assignment.zh-tw.md new file mode 100644 index 00000000..baa62cfd --- /dev/null +++ b/7-bank-project/2-forms/translations/assignment.zh-tw.md @@ -0,0 +1,13 @@ +# 造型化你的銀行程式 + +## 簡介 + +建立新的檔案 `styles.css`,匯入到你的 `index.html` 檔案中。藉由 CSS 檔,你能讓*登入*與*儀表板*頁面看起來更漂亮且整潔。試著為你的程式加入主題色彩,對應到你的品牌。 + +> 提示:你可以修改 HTML 檔,在必要時新增元素與 classes。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | -------------------------------------------------- | ------------------------------------ | ---------------------------------------- | +| | 所有的頁面整潔且易讀:統一的主題色彩且排版顯示正常 | 頁面有調整過,但缺乏主題且排版有瑕疵 | 頁面缺乏造型,排版凌亂且頁面資訊難以理解 | diff --git a/7-bank-project/3-data/README.md b/7-bank-project/3-data/README.md index 044ed8ae..76573c1f 100644 --- a/7-bank-project/3-data/README.md +++ b/7-bank-project/3-data/README.md @@ -29,11 +29,11 @@ Traditional web sites update the content displayed when the user selects a link  -When web applications started to become more complex and interactive, a new technique called [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) emerged. This technique allows web apps to send and retrieve data from a server asynchronously using JavaScript, without having to reload the HTML page, resulting in faster updates and smoother user interactions. When new data is received from the server, the current HTML page can also be updated with JavaScript using the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) API. Over time, this approach has evolved into what is now called a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application). +When web applications started to become more complex and interactive, a new technique called [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) emerged. This technique allows web apps to send and retrieve data from a server asynchronously using JavaScript, without having to reload the HTML page, resulting in faster updates and smoother user interactions. When new data is received from the server, the current HTML page can also be updated with JavaScript using the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. Over time, this approach has evolved into what is now called a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  -When AJAX was first introduced, the only API available to fetch data asynchronously was [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). But modern browsers now also implement the more convenient and powerful [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), which uses promises and is better suited to manipulate JSON data. +When AJAX was first introduced, the only API available to fetch data asynchronously was [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). But modern browsers now also implement the more convenient and powerful [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), which uses promises and is better suited to manipulate JSON data. > While all modern browsers support the `Fetch API`, if you want your web application to work on legacy or old browsers it's always a good idea to check the [compatibility table on caniuse.com](https://caniuse.com/fetch) first. @@ -63,7 +63,7 @@ async function getAccount(user) { } ``` -We use the `fetch` API to request the data asynchronously from the server, but this time we don't need any extra parameters other than the URL to call, as we're only querying data. By default, `fetch` creates a [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) HTTP request, which is what we are seeking here. +We use the `fetch` API to request the data asynchronously from the server, but this time we don't need any extra parameters other than the URL to call, as we're only querying data. By default, `fetch` creates a [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP request, which is what we are seeking here. ✅ `encodeURIComponent()` is a function that escapes special characters for URL. What issues could we possibly have if we do not call this function and use directly the `user` value in the URL? @@ -109,19 +109,19 @@ account = result; navigate('/dashboard'); ``` -✅ Did you know that by default, you can only call server APIs from the *same domain and port* than the web page you are viewing? This is security mechanism enforced by browsers. But wait, our web app is running on `localhost:3000` whereas the server API is running on ` localhost:5000`, why does it work? By using a technique called [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), it is possible to perform cross-origin HTTP requests if the server adds special headers to the response, allowing exceptions for specific domains. +✅ Did you know that by default, you can only call server APIs from the *same domain and port* than the web page you are viewing? This is security mechanism enforced by browsers. But wait, our web app is running on `localhost:3000` whereas the server API is running on ` localhost:5000`, why does it work? By using a technique called [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), it is possible to perform cross-origin HTTP requests if the server adds special headers to the response, allowing exceptions for specific domains. -> Learn more about APIs by taking this [lesson](https://docs.microsoft.com/en-us/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-13441-cxa) +> Learn more about APIs by taking this [lesson](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-13441-cxa) ## Update HTML to display data Now that we have the user data, we have to update the existing HTML to display it. We already know how to retrieve an element from the DOM using for example `document.getElementById()`. After you have a base element, here are some APIs you can use to modify it or add child elements to it: -- Using the [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) property you can change the text of an element. Note that changing this value removes all the element's children (if there's any) and replaces it with the text provided. As such, it's also an efficient method to remove all children of a given element by assigning an empty string `''` to it. +- Using the [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) property you can change the text of an element. Note that changing this value removes all the element's children (if there's any) and replaces it with the text provided. As such, it's also an efficient method to remove all children of a given element by assigning an empty string `''` to it. -- Using [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) along with the [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) method you can create and attach one or more new child elements. +- Using [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) along with the [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) method you can create and attach one or more new child elements. -✅ Using the [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property of an element it's also possible to change its HTML contents, but this one should be avoided as it's vulnerable to [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) attacks. +✅ Using the [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) property of an element it's also possible to change its HTML contents, but this one should be avoided as it's vulnerable to [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) attacks. ### Task @@ -159,7 +159,7 @@ Now if you try to login with an invalid account, you should see something like t  -Now we have error text that shows up visually, but if you try it with a screen reader you'll notice that nothing is announced. In order for text that is dynamically added to a page to be announced by screen readers, it will need to use something called a [Live Region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Here we're going to use a specific type of live region called an alert: +Now we have error text that shows up visually, but if you try it with a screen reader you'll notice that nothing is announced. In order for text that is dynamically added to a page to be announced by screen readers, it will need to use something called a [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Here we're going to use a specific type of live region called an alert: ```html <div id="loginError" role="alert"></div> @@ -223,7 +223,7 @@ function updateDashboard() { First, we check that we have the account data we need before going further. Then we use the `updateElement()` function we created earlier to update the HTML. -> To make the balance display prettier, we use the method [`toFixed(2)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) to force displaying the value with 2 digits after the decimal point. +> To make the balance display prettier, we use the method [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) to force displaying the value with 2 digits after the decimal point. Now we need to call our `updateDashboard()` function everytime the dashboard is loaded. If you already finished the [lesson 1 assignment](../1-template-route/assignment.md) this should be straighforward, otherwise you can use the following implementation. @@ -248,7 +248,7 @@ With this change, every time the dashboard page is displayed, the function `upda ## Create table rows dynamically with HTML templates -In the [first lesson](../1-template-route/README.md) we used HTML templates along with the [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) method to implement the navigation in our app. Templates can also be smaller and used to dynamically populate repetitive parts of a page. +In the [first lesson](../1-template-route/README.md) we used HTML templates along with the [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) method to implement the navigation in our app. Templates can also be smaller and used to dynamically populate repetitive parts of a page. We'll use a similar approach to display the list of transactions in the HTML table. @@ -299,7 +299,7 @@ for (const transaction of account.transactions) { updateElement('transactions', transactionsRows); ``` -Here we use the method [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) that creates a new DOM fragment on which we can work, before finally attaching it to our HTML table. +Here we use the method [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) that creates a new DOM fragment on which we can work, before finally attaching it to our HTML table. There's still one more thing we have to do before this code can work, as our `updateElement()` function currently supports text content only. Let's change its code a bit: @@ -311,7 +311,7 @@ function updateElement(id, textOrNode) { } ``` -We use the [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) method as it allows to attach either text or [DOM Nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node) to a parent element, which is perfect for all our use cases. +We use the [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) method as it allows to attach either text or [DOM Nodes](https://developer.mozilla.org/docs/Web/API/Node) to a parent element, which is perfect for all our use cases. If you try using the `test` account to login, you should now see a transaction list on the dashboard 🎉. @@ -319,7 +319,7 @@ If you try using the `test` account to login, you should now see a transaction l ## 🚀 Challenge -Work together to make the dashboard page look like a real banking app. If you already styled your app, try to use [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries) to create a [responsive design](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) working nicely on both desktop and mobile devices. +Work together to make the dashboard page look like a real banking app. If you already styled your app, try to use [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) to create a [responsive design](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) working nicely on both desktop and mobile devices. Here's an example of a styled dashboard page: diff --git a/7-bank-project/3-data/translations/README.it.md b/7-bank-project/3-data/translations/README.it.md index b21e585f..1aec2da4 100644 --- a/7-bank-project/3-data/translations/README.it.md +++ b/7-bank-project/3-data/translations/README.it.md @@ -33,7 +33,7 @@ Quando le applicazioni web hanno iniziato a diventare più complesse e interatti  -Quando è stato introdotto per la prima volta AJAX, l'unica API disponibile per recuperare i dati in modo asincrono era [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). I browser moderni ora implementano anche l'[API Fetch](https://developer.mozilla.org/it/docs/Web/API/Fetch_API), più conveniente e potente, che utilizza le promesse ed è più adatta per manipolare i dati JSON. +Quando è stato introdotto per la prima volta AJAX, l'unica API disponibile per recuperare i dati in modo asincrono era [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). I browser moderni ora implementano anche l'[API Fetch](https://developer.mozilla.org/it/docs/Web/API/Fetch_API), più conveniente e potente, che utilizza le promesse ed è più adatta per manipolare i dati JSON. > Sebbene tutti i browser moderni supportino l'`API Fetch`, se si desidera che la propria applicazione web funzioni su browser legacy o vecchi, è sempre una buona idea controllare prima la [tabella di compatibilità su caniuse.com](https://caniuse.com/fetch). @@ -63,7 +63,7 @@ async function getAccount(user) { } ``` -Si usa l'API `fetch` per richiedere i dati in modo asincrono dal server, ma questa volta non servono parametri aggiuntivi oltre all'URL da chiamare, poiché si sta solo interrogando i dati. Per impostazione predefinita, `fetch` crea una richiesta HTTP [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET), che è ciò che serve qui. +Si usa l'API `fetch` per richiedere i dati in modo asincrono dal server, ma questa volta non servono parametri aggiuntivi oltre all'URL da chiamare, poiché si sta solo interrogando i dati. Per impostazione predefinita, `fetch` crea una richiesta HTTP [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), che è ciò che serve qui. ✅ `encodeURIComponent()` è una funzione che evita i caratteri speciali per l'URL. Quali problemi si potrebbero avere se non viene chiamata questa funzione e si utilizza direttamente il valore del campo `user` nell'URL? @@ -111,17 +111,17 @@ navigate('/dashboard'); ✅ Si sa che per impostazione predefinita, si possono chiamare solo le API di un server che ha *stesso dominio e porta* della pagina web che si sta visualizzando? Questo è un meccanismo di sicurezza applicato dai browser. Un momento, la nostra app web è in esecuzione su `localhost:3000` mentre l'API del server è in esecuzione su `localhost:5000`, come mai funziona? Utilizzando una tecnica chiamata CORS [Cross-Origin Resource Sharing](https://developer.mozilla.org/it/docs/Web/HTTP/CORS), è possibile eseguire richieste HTTP con diverse origini (cross-origin) se il server aggiunge intestazioni speciali alla risposta, consentendo eccezioni per domini specifici. -> Ulteriori informazioni sulle API sono disponibili seguendo questa [lezione](https://docs.microsoft.com/en-us/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-4621-cxa) +> Ulteriori informazioni sulle API sono disponibili seguendo questa [lezione](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-4621-cxa) ## Aggiornare HTML per visualizzare i dati Ora che si hanno i dati dell'utente, occorre aggiornare l'HTML esistente per visualizzarli. E' già noto come recuperare un elemento dal DOM utilizzando ad esempio `document.getElementById()`. Dopo aver ottenuto un elemento base, ecco alcune API che si possono utilizzare per modificarlo o aggiungervi elementi figlio: -- Usando la proprietà [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) si può cambiare il testo di un elemento. Notare che la modifica di questo valore rimuove tutti i figli dell'elemento (se presenti) e li sostituisce con il testo fornito. In quanto tale, è anche un metodo efficiente per rimuovere tutti i figli di un dato elemento assegnandogli una stringa vuota `""` . +- Usando la proprietà [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) si può cambiare il testo di un elemento. Notare che la modifica di questo valore rimuove tutti i figli dell'elemento (se presenti) e li sostituisce con il testo fornito. In quanto tale, è anche un metodo efficiente per rimuovere tutti i figli di un dato elemento assegnandogli una stringa vuota `""` . -- Usando [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) insieme al metodo [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) si può creare e allegare uno o più nuovi elementi figlio. +- Usando [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) insieme al metodo [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) si può creare e allegare uno o più nuovi elementi figlio. -✅ Utilizzando la proprietà [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) di un elemento è anche possibile modificare il suo contenuto HTML, ma questo dovrebbe essere evitato poiché è vulnerabile agli attacchi di [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) . +✅ Utilizzando la proprietà [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) di un elemento è anche possibile modificare il suo contenuto HTML, ma questo dovrebbe essere evitato poiché è vulnerabile agli attacchi di [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) . ### Attività @@ -159,7 +159,7 @@ Ora se si prova ad accedere con un account non valido, si dovrebbe vedere qualco  -Ora si ha un testo di errore che viene visualizzato, ma se si prova con un lettore di schermo si noterà che non viene annunciato nulla. Affinché il testo che viene aggiunto dinamicamente a una pagina venga annunciato dai lettori di schermo, sarà necessario utilizzare qualcosa chiamato [Live Region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Qui verrà utilizzato un tipo specifico di live region chiamato alert: +Ora si ha un testo di errore che viene visualizzato, ma se si prova con un lettore di schermo si noterà che non viene annunciato nulla. Affinché il testo che viene aggiunto dinamicamente a una pagina venga annunciato dai lettori di schermo, sarà necessario utilizzare qualcosa chiamato [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Qui verrà utilizzato un tipo specifico di live region chiamato alert: ```html <div id="loginError" role="alert"></div> @@ -223,7 +223,7 @@ function updateDashboard() { Innanzitutto, controllare di avere i dati dell'account necessari prima di andare oltre. Quindi si usa la funzione `updateElement()` creata in precedenza per aggiornare l'HTML. -> Per rendere la visualizzazione del saldo più bella, si usa il metodo [`toFixed(2)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) per forzare la visualizzazione del valore con 2 cifre per la parte decimale. +> Per rendere la visualizzazione del saldo più bella, si usa il metodo [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) per forzare la visualizzazione del valore con 2 cifre per la parte decimale. Ora occorre chiamare la funzione `updateDashboard()` ogni volta che viene caricato il cruscotto. Se si è già terminato il [compito della lezione 1](../../1-template-route/translations/assignment.it.md) , questo dovrebbe essere immediato, altrimenti si può utilizzare la seguente implementazione. @@ -248,7 +248,7 @@ Con questa modifica, ogni volta che viene visualizzata la pagina del cruscotto v ## Creare righe di tabelle dinamicamente con modelli HTML -Nella [prima lezione](../../1-template-route/translations/README.it.md) sono stati utilizzati modelli HTML insieme al metodo [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) per implementare la navigazione nell'app. I modelli possono anche essere più piccoli e utilizzati per popolare dinamicamente parti ripetitive di una pagina. +Nella [prima lezione](../../1-template-route/translations/README.it.md) sono stati utilizzati modelli HTML insieme al metodo [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) per implementare la navigazione nell'app. I modelli possono anche essere più piccoli e utilizzati per popolare dinamicamente parti ripetitive di una pagina. Verrà usato un approccio simile per visualizzare l'elenco delle transazioni nella tabella HTML. @@ -299,7 +299,7 @@ for (const transaction of account.transactions) { updateElement('transactions', transactionsRows); ``` -Qui si utilizza il metodo [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) che crea un nuovo frammento DOM su cui si può lavorare, prima di collegarlo finalmente alla tabella HTML. +Qui si utilizza il metodo [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) che crea un nuovo frammento DOM su cui si può lavorare, prima di collegarlo finalmente alla tabella HTML. C'è ancora un'altra cosa da fare prima che questo codice possa funzionare, poiché la funzione `updateElement()` attualmente supporta solo contenuto di testo. Occorre cambiare un poco il suo codice: @@ -311,7 +311,7 @@ function updateElement(id, textOrNode) { } ``` -Si usa il metodo [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) in quanto consente di allegare testo o [nodi DOM](https://developer.mozilla.org/en-US/docs/Web/API/Node) a un elemento genitore, che è perfetto per tutti i casi d'uso. +Si usa il metodo [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) in quanto consente di allegare testo o [nodi DOM](https://developer.mozilla.org/docs/Web/API/Node) a un elemento genitore, che è perfetto per tutti i casi d'uso. Se si prova a utilizzare l'account `test` per accedere, ora si dovrebbe vedere un elenco di transazioni sul cruscotto 🎉. @@ -319,7 +319,7 @@ Se si prova a utilizzare l'account `test` per accedere, ora si dovrebbe vedere u ## 🚀 Sfida -Collaborare per far sembrare la pagina del cruscotto una vera app bancaria. Se è già stato definito lo stile della propria app, provare a utilizzare le [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries) per creare una [disposizione reattiva](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) che funzioni bene sia su dispositivi desktop che mobili. +Collaborare per far sembrare la pagina del cruscotto una vera app bancaria. Se è già stato definito lo stile della propria app, provare a utilizzare le [media query](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) per creare una [disposizione reattiva](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) che funzioni bene sia su dispositivi desktop che mobili. Ecco un esempio di una pagina cruscotto con applicato uno stile: diff --git a/7-bank-project/3-data/translations/README.ja.md b/7-bank-project/3-data/translations/README.ja.md index ecec6b03..43636986 100644 --- a/7-bank-project/3-data/translations/README.ja.md +++ b/7-bank-project/3-data/translations/README.ja.md @@ -309,7 +309,7 @@ function updateElement(id, textOrNode) { } ``` -私たちは [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) メソッドを使用しています。これにより、テキストや [DOM Nodes](https://developer.mozilla.org/ja/docs/Web/API/Node) を親要素にアタッチすることができ、すべてのユースケースに最適です。 +私たちは [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) メソッドを使用しています。これにより、テキストや [DOM Nodes](https://developer.mozilla.org/ja/docs/Web/API/Node) を親要素にアタッチすることができ、すべてのユースケースに最適です。 `test` アカウントを使ってログインしてみると、ダッシュボード上にトランザクションリストが表示されるはずです 🎉。 @@ -317,7 +317,7 @@ function updateElement(id, textOrNode) { ## 🚀 チャレンジ -ダッシュボードページを実際の銀行アプリのように見せるために一緒に作業しましょう。すでにアプリのスタイルを設定している場合は、[メディアクエリ](https://developer.mozilla.org/ja/docs/Web/CSS/Media_queries)を使用して、デスクトップとモバイルデバイスの両方でうまく機能する[レスポンシブデザイン](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)を作成してみてください。 +ダッシュボードページを実際の銀行アプリのように見せるために一緒に作業しましょう。すでにアプリのスタイルを設定している場合は、[メディアクエリ](https://developer.mozilla.org/ja/docs/Web/CSS/Media_queries)を使用して、デスクトップとモバイルデバイスの両方でうまく機能する[レスポンシブデザイン](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)を作成してみてください。 ダッシュボードページのスタイリング例です。 diff --git a/7-bank-project/3-data/translations/README.ko.md b/7-bank-project/3-data/translations/README.ko.md index 3637be7f..b6e4a1de 100644 --- a/7-bank-project/3-data/translations/README.ko.md +++ b/7-bank-project/3-data/translations/README.ko.md @@ -29,11 +29,11 @@ curl http://localhost:5000/api  -웹 애플리케이션이 더 복잡해지고 상호 작용하기 시작하면서, [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming))이라는 새로운 기술이 나타났습니다. 이 기술을 쓰면 웹 앱은 HTML 페이지를 다시 불러오지 않고, JavaScript를 사용하여 비동기로 서버에서 데이터를 보내고 찾을 수 있으므로, 갱신 속도가 빨라지고 사용자 상호 작용이 부드러워집니다. 서버에서 새로운 데이터를 받으면, [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) API로 현재 HTML 페이지를 JavaScript로 갱신할 수도 있습니다. 시간이 지나면서, 이 방식은 이제 [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application)라는 것으로 발전했습니다. +웹 애플리케이션이 더 복잡해지고 상호 작용하기 시작하면서, [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming))이라는 새로운 기술이 나타났습니다. 이 기술을 쓰면 웹 앱은 HTML 페이지를 다시 불러오지 않고, JavaScript를 사용하여 비동기로 서버에서 데이터를 보내고 찾을 수 있으므로, 갱신 속도가 빨라지고 사용자 상호 작용이 부드러워집니다. 서버에서 새로운 데이터를 받으면, [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API로 현재 HTML 페이지를 JavaScript로 갱신할 수도 있습니다. 시간이 지나면서, 이 방식은 이제 [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application)라는 것으로 발전했습니다.  -AJAX가 처음 소개되었을 때, 데이터를 비동기로 가져올 유일한 API는 [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)였습니다. 그러나 모던 브라우저는 이제 promises를 사용하고 JSON 데이터를 조작할 때 적당하며, 더 편리하고 강력한 [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)도 구현합니다. +AJAX가 처음 소개되었을 때, 데이터를 비동기로 가져올 유일한 API는 [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)였습니다. 그러나 모던 브라우저는 이제 promises를 사용하고 JSON 데이터를 조작할 때 적당하며, 더 편리하고 강력한 [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API)도 구현합니다. > 모든 모던 브라우저는 `Fetch API`를 지원하지만, 웹 애플리케이션이 레거시 혹은 옛날 브라우저에서 작동하도록 하려면 항상 [compatibility table on caniuse.com](https://caniuse.com/fetch)를 먼저 보는 것이 좋습니다. @@ -63,7 +63,7 @@ async function getAccount(user) { } ``` -비동기로 서버에 데이터를 요청하기 위해서 `fetch` API를 사용하지만, 이번에는 데이터만 쿼리하므로, 호출할 URL 이외 추가 파라미터는 필요하지 않습니다. 기본적으로, `fetch`는 여기에서 찾는 것처럼 [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) 요청을 생성합니다. +비동기로 서버에 데이터를 요청하기 위해서 `fetch` API를 사용하지만, 이번에는 데이터만 쿼리하므로, 호출할 URL 이외 추가 파라미터는 필요하지 않습니다. 기본적으로, `fetch`는 여기에서 찾는 것처럼 [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) 요청을 생성합니다. ✅ `encodeURIComponent()`는 URL에 대한 특수 문자를 이스케이프하는 함수입니다. 이 함수를 호출하지 않고 URL에서 `user` 값을 직접 사용하면 어떤 이슈가 발생할 수 있나요? @@ -109,17 +109,17 @@ account = result; navigate('/dashboard'); ``` -✅ 기본적으로, 보고있는 웹 페이지에 *동일한 도메인와 포트*에서만 서버 API를 호출할 수 있다는 사실을 알고 있었나요? 이것은 브라우저에 의해 시행되는 보안 메커니즘입니다. 하지만, 웹 앱은 `localhost:3000`에서 실행되고 서버 API가 `localhost:5000`에서 실행됩니다. 왜 작동할까요? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)라는 기술을 사용하면 서버가 응답에 특별한 헤더를 추가하여 특정 도메인에 대한 예외를 허용하므로, cross-origin HTTP 요청을 수행 할 수 있습니다. +✅ 기본적으로, 보고있는 웹 페이지에 *동일한 도메인와 포트*에서만 서버 API를 호출할 수 있다는 사실을 알고 있었나요? 이것은 브라우저에 의해 시행되는 보안 메커니즘입니다. 하지만, 웹 앱은 `localhost:3000`에서 실행되고 서버 API가 `localhost:5000`에서 실행됩니다. 왜 작동할까요? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS)라는 기술을 사용하면 서버가 응답에 특별한 헤더를 추가하여 특정 도메인에 대한 예외를 허용하므로, cross-origin HTTP 요청을 수행 할 수 있습니다. ## 데이터를 보여주기 위해 HTML 갱신하기 이제 사용자 데이터가 있으므로, 기존 HTML을 갱신해서 보여줘야 합니다. 예시로 `document.getElementById()`를 사용하여 DOM에서 요소를 검색하는 방법은 이미 있습니다. 바탕 요소가 있으면, 수정하거나 하위 요소를 추가하는 방식으로 사용할 수 있는 몇 가지 API가 있습니다: -- [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) 속성을 사용하여 요소의 텍스트를 바꿀 수 있습니다. 이 값을 변경하면 모든 요소의 하위가(있는 경우) 제거되고 주어진 텍스트로 대체됩니다. 따라서, 빈 문자열 `''`을 할당하여 주어진 요소의 모든 하위를 제거하는 효율적인 방법일 수도 있습니다. +- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) 속성을 사용하여 요소의 텍스트를 바꿀 수 있습니다. 이 값을 변경하면 모든 요소의 하위가(있는 경우) 제거되고 주어진 텍스트로 대체됩니다. 따라서, 빈 문자열 `''`을 할당하여 주어진 요소의 모든 하위를 제거하는 효율적인 방법일 수도 있습니다. -- [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement)를 [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append)메소드와 함께 사용하면 하나 이상의 새로운 하위 요소를 만들고 붙일 수 있습니다. +- [`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/en-US/docs/Web/API/Element/innerHTML) 속성을 사용하여 HTML 내용을 바꿀 수 있지만, [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) 공격에 취약하므로 피해야 합니다. +✅ 요소의 [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) 속성을 사용하여 HTML 내용을 바꿀 수 있지만, [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) 공격에 취약하므로 피해야 합니다. ### 작업 @@ -197,7 +197,7 @@ HTML의 "Balance" 섹션을 교체하고 placeholder 요소를 추가하는 것 <section id="description" aria-label="Account description"></section> ``` -✅ 이 섹션의 내용을 설명하는 텍스트 라벨이 없기 때문에, `aria-label` 속성을 사용하여 접근성 힌트를 줍니다. 모두 웹 앱에 접근할 수 있도록 [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA)에 대해 더 알아보세요. +✅ 이 섹션의 내용을 설명하는 텍스트 라벨이 없기 때문에, `aria-label` 속성을 사용하여 접근성 힌트를 줍니다. 모두 웹 앱에 접근할 수 있도록 [ARIA attributes](https://developer.mozilla.org/docs/Web/Accessibility/ARIA)에 대해 더 알아보세요. 다음으로, `app.js`에 placeholder를 채우기 위해서 새로운 함수를 만듭니다: @@ -215,7 +215,7 @@ function updateDashboard() { 먼저, 나아가기 전 필요한 계정 데이터가 있는지 확인합니다. 그러고 일찍 만들어 둔 `updateElement()` 함수로 HTML을 업데이트합니다. -> 잔액을 더 예쁘게 보이게 만드려면, [`toFixed(2)`](https://developer.mozilla.org/en-US/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()` 함수를 호출해야 합니다. 이미 [lesson 1 assignment](../../1-template-route/assignment.md)를 완료했다면 간단해야 합니다. 그렇지 않다면 이미 구현된 내용으로 쓸 수 있습니다. @@ -240,7 +240,7 @@ const routes = { ## HTML 템플릿으로 동적 테이블 row 만들기 -[first lesson](../../1-template-route/translations/README.ko.md)에서는 HTML 템플릿과 [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) 메소드로 앱의 탐색을 구현했습니다. 템플릿은 더 작아 질 수 있고 페이지의 반복적인 부분을 동적으로 채우는 데 쓸 수 있습니다. +[first lesson](../../1-template-route/translations/README.ko.md)에서는 HTML 템플릿과 [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) 메소드로 앱의 탐색을 구현했습니다. 템플릿은 더 작아 질 수 있고 페이지의 반복적인 부분을 동적으로 채우는 데 쓸 수 있습니다. 유사한 접근 방식을 사용하여 HTML 테이블에 트랜잭션 목록을 출력합니다. @@ -291,7 +291,7 @@ for (const transaction of account.transactions) { updateElement('transactions', transactionsRows); ``` -여기서는 새로운 DOM 프래그먼트를 만들 [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) 메소드로 최종적인 HTML 테이블에 붙입니다. +여기서는 새로운 DOM 프래그먼트를 만들 [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) 메소드로 최종적인 HTML 테이블에 붙입니다. 현재 `updateElement()` 함수가 텍스트 내용만 지원하므로 이 코드가 실행되기 전에 할 일이 하나 더 있습니다. 코드를 약간 바꿔 보겠습니다: @@ -303,7 +303,7 @@ function updateElement(id, textOrNode) { } ``` -[`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append)] 메소드를 사용하면 상위 요소에 텍스트 혹은 [DOM Nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node)를 붙일 수 있으므로, 모든 사용 케이스에 적당합니다. +[`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append)] 메소드를 사용하면 상위 요소에 텍스트 혹은 [DOM Nodes](https://developer.mozilla.org/docs/Web/API/Node)를 붙일 수 있으므로, 모든 사용 케이스에 적당합니다. `test` 계정을 사용하여 로그인을 해보면, 지금 대시보드에 거래 목록이 보입니다 🎉. @@ -311,7 +311,7 @@ function updateElement(id, textOrNode) { ## 🚀 도전 -대시보드 페이지를 실제 은행 앱처럼 보이도록 함께 작업해보세요. 이미 앱 스타일한 경우, [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries)를 사용하여 데스크톱과 모바일 장치 다 잘 작동하는 [responsive design](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)으로 만들어보세요. +대시보드 페이지를 실제 은행 앱처럼 보이도록 함께 작업해보세요. 이미 앱 스타일한 경우, [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries)를 사용하여 데스크톱과 모바일 장치 다 잘 작동하는 [responsive design](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)으로 만들어보세요. 여기는 꾸며진 대시보드 페이지의 예시입니다: diff --git a/7-bank-project/3-data/translations/README.ms.md b/7-bank-project/3-data/translations/README.ms.md index 4e1067b5..aa49fceb 100644 --- a/7-bank-project/3-data/translations/README.ms.md +++ b/7-bank-project/3-data/translations/README.ms.md @@ -29,11 +29,11 @@ Laman web tradisional mengemas kini kandungan yang dipaparkan ketika pengguna me  -Ketika aplikasi web mula menjadi lebih kompleks dan interaktif, teknik baru yang disebut [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) muncul. Teknik ini membolehkan aplikasi web mengirim dan mengambil data dari pelayan secara asinkron menggunakan JavaScript, tanpa harus memuat semula halaman HTML, menghasilkan kemas kini yang lebih cepat dan interaksi pengguna yang lebih lancar. Apabila data baru diterima dari pelayan, halaman HTML semasa juga dapat diperbarui dengan JavaScript menggunakan API [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model). Dari masa ke masa, pendekatan ini telah berkembang menjadi apa yang sekarang disebut [*Aplikasi Halaman Tunggal* atau *SPA*](https://en.wikipedia.org/wiki/Single-page_application). +Ketika aplikasi web mula menjadi lebih kompleks dan interaktif, teknik baru yang disebut [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) muncul. Teknik ini membolehkan aplikasi web mengirim dan mengambil data dari pelayan secara asinkron menggunakan JavaScript, tanpa harus memuat semula halaman HTML, menghasilkan kemas kini yang lebih cepat dan interaksi pengguna yang lebih lancar. Apabila data baru diterima dari pelayan, halaman HTML semasa juga dapat diperbarui dengan JavaScript menggunakan API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Dari masa ke masa, pendekatan ini telah berkembang menjadi apa yang sekarang disebut [*Aplikasi Halaman Tunggal* atau *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  -Semasa AJAX pertama kali diperkenalkan, satu-satunya API yang tersedia untuk mengambil data secara asinkron adalah [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Tetapi penyemak imbas moden kini juga melaksanakan [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), yang menggunakan janji dan lebih sesuai untuk dimanipulasi Data JSON. +Semasa AJAX pertama kali diperkenalkan, satu-satunya API yang tersedia untuk mengambil data secara asinkron adalah [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Tetapi penyemak imbas moden kini juga melaksanakan [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), yang menggunakan janji dan lebih sesuai untuk dimanipulasi Data JSON. > Walaupun semua penyemak imbas moden menyokong `Fetch API`, jika anda mahu aplikasi web anda berfungsi pada penyemak imbas lama atau penyemak imbas lama, sebaiknya periksa [jadual keserasian di caniuse.com](https://caniuse.com/fetch) pertama. @@ -63,7 +63,7 @@ async function getAccount(user) { } ``` -Kami menggunakan API `fetch` untuk meminta data secara tidak serentak dari pelayan, tetapi kali ini kami tidak memerlukan parameter tambahan selain URL untuk dipanggil, kerana kami hanya meminta data. Secara lalai, `fetch` membuat permintaan HTTP [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET), itulah yang kami cari di sini. +Kami menggunakan API `fetch` untuk meminta data secara tidak serentak dari pelayan, tetapi kali ini kami tidak memerlukan parameter tambahan selain URL untuk dipanggil, kerana kami hanya meminta data. Secara lalai, `fetch` membuat permintaan HTTP [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), itulah yang kami cari di sini. ✅ `encodeURIComponent()` adalah fungsi yang melarikan diri daripada watak khas untuk URL. Masalah apa yang mungkin kita hadapi jika kita tidak memanggil fungsi ini dan menggunakan nilai `pengguna` secara langsung di URL? @@ -109,19 +109,19 @@ account = result; navigate('/dashboard'); ``` -✅ Tahukah anda bahawa secara lalai, anda hanya dapat memanggil API pelayan dari *domain dan port yang sama* daripada halaman web yang anda lihat? Ini adalah mekanisme keselamatan yang dikuatkuasakan oleh penyemak imbas. Tetapi tunggu, aplikasi web kami berjalan di `localhost: 3000` sedangkan API pelayan berjalan di `localhost: 5000`, mengapa ia berfungsi? Dengan menggunakan teknik yang disebut [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), adalah mungkin untuk melakukan permintaan HTTP bersilang asal jika pelayan menambah tajuk khas untuk respons, yang memungkinkan pengecualian untuk domain tertentu. +✅ Tahukah anda bahawa secara lalai, anda hanya dapat memanggil API pelayan dari *domain dan port yang sama* daripada halaman web yang anda lihat? Ini adalah mekanisme keselamatan yang dikuatkuasakan oleh penyemak imbas. Tetapi tunggu, aplikasi web kami berjalan di `localhost: 3000` sedangkan API pelayan berjalan di `localhost: 5000`, mengapa ia berfungsi? Dengan menggunakan teknik yang disebut [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), adalah mungkin untuk melakukan permintaan HTTP bersilang asal jika pelayan menambah tajuk khas untuk respons, yang memungkinkan pengecualian untuk domain tertentu. -> Ketahui lebih lanjut mengenai API dengan mengambil [pelajaran](https://docs.microsoft.com/en-us/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-13441-cxa) +> Ketahui lebih lanjut mengenai API dengan mengambil [pelajaran](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-13441-cxa) ## Kemas kini HTML untuk memaparkan data Sekarang kita mempunyai data pengguna, kita harus mengemas kini HTML yang ada untuk memaparkannya. Kami sudah tahu cara mendapatkan elemen dari DOM menggunakan contohnya `document.getElementById()`. Setelah anda mempunyai elemen asas, berikut adalah beberapa API yang boleh anda gunakan untuk mengubahnya atau menambahkan elemen anak padanya: -- Dengan menggunakan sifat [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent), anda boleh mengubah teks elemen. Perhatikan bahawa mengubah nilai ini akan membuang semua anak elemen (jika ada) dan menggantinya dengan teks yang disediakan. Oleh itu, ini juga kaedah yang berkesan untuk membuang semua anak dari elemen tertentu dengan memberikan string kosong "" kepadanya. +- Dengan menggunakan sifat [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent), anda boleh mengubah teks elemen. Perhatikan bahawa mengubah nilai ini akan membuang semua anak elemen (jika ada) dan menggantinya dengan teks yang disediakan. Oleh itu, ini juga kaedah yang berkesan untuk membuang semua anak dari elemen tertentu dengan memberikan string kosong "" kepadanya. -- Menggunakan [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/DocumentcreateElement) bersama dengan [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) kaedah anda boleh membuat dan melampirkan satu atau lebih elemen anak baru. +- Menggunakan [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/DocumentcreateElement) bersama dengan [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) kaedah anda boleh membuat dan melampirkan satu atau lebih elemen anak baru. -✅ Menggunakan sifat [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) elemen juga mungkin untuk mengubah kandungan HTMLnya, tetapi yang ini harus dielakkan kerana terdedah kepada serangan [cross-site scripting (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) serangan. +✅ Menggunakan sifat [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) elemen juga mungkin untuk mengubah kandungan HTMLnya, tetapi yang ini harus dielakkan kerana terdedah kepada serangan [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) serangan. ### Tugas @@ -159,7 +159,7 @@ Sekiranya anda cuba log masuk dengan akaun yang tidak sah, anda akan melihat sep  -Sekarang kita mempunyai teks ralat yang muncul secara visual, tetapi jika anda mencubanya dengan pembaca skrin, anda akan melihat bahawa tidak ada yang diumumkan. Agar teks yang ditambahkan secara dinamis ke halaman diumumkan oleh pembaca skrin, ia perlu menggunakan sesuatu yang disebut [Live Region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Di sini kita akan menggunakan jenis kawasan langsung yang disebut amaran: +Sekarang kita mempunyai teks ralat yang muncul secara visual, tetapi jika anda mencubanya dengan pembaca skrin, anda akan melihat bahawa tidak ada yang diumumkan. Agar teks yang ditambahkan secara dinamis ke halaman diumumkan oleh pembaca skrin, ia perlu menggunakan sesuatu yang disebut [Live Region](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Di sini kita akan menggunakan jenis kawasan langsung yang disebut amaran: ```html <div id="loginError" role="alert"></div> @@ -223,7 +223,7 @@ function updateDashboard() { Pertama, kami memeriksa bahawa kami mempunyai data akaun yang kami perlukan sebelum melangkah lebih jauh. Kemudian kami menggunakan fungsi `updateElement()` yang kami buat sebelumnya untuk mengemas kini HTML. -> Untuk menjadikan paparan keseimbangan lebih cantik, kami menggunakan kaedah [`toFixed(2)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) untuk daya memaparkan nilai dengan 2 digit selepas titik perpuluhan. +> Untuk menjadikan paparan keseimbangan lebih cantik, kami menggunakan kaedah [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) untuk daya memaparkan nilai dengan 2 digit selepas titik perpuluhan. Sekarang kita perlu memanggil fungsi `updateDashboard()` setiap kali papan pemuka dimuat. Sekiranya anda sudah menyelesaikan [tugasan 1](../1-template-route/assignment.md) ini harus dilakukan dengan mudah, jika tidak, anda boleh menggunakan pelaksanaan berikut. @@ -248,7 +248,7 @@ Dengan perubahan ini, setiap kali halaman dashboard ditampilkan, fungsi `updateD ## Buat baris jadual secara dinamik dengan templat HTML -Dalam [first lesson](../1-template-route/README.md) kami menggunakan templat HTML bersama dengan [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) kaedah untuk melaksanakan navigasi di aplikasi kami. Templat juga dapat lebih kecil dan digunakan untuk mengisi bahagian halaman yang berulang secara dinamis. +Dalam [first lesson](../1-template-route/README.md) kami menggunakan templat HTML bersama dengan [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) kaedah untuk melaksanakan navigasi di aplikasi kami. Templat juga dapat lebih kecil dan digunakan untuk mengisi bahagian halaman yang berulang secara dinamis. Kami akan menggunakan pendekatan yang serupa untuk memaparkan senarai transaksi dalam jadual HTML. @@ -299,7 +299,7 @@ for (const transaction of account.transactions) { updateElement('transactions', transactionsRows); ``` -Di sini kita menggunakan kaedah [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment) yang membuat serpihan DOM baru yang boleh kita gunakan , sebelum akhirnya melampirkannya ke jadual HTML kami. +Di sini kita menggunakan kaedah [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) yang membuat serpihan DOM baru yang boleh kita gunakan , sebelum akhirnya melampirkannya ke jadual HTML kami. Masih ada satu perkara lagi yang harus kita lakukan sebelum kod ini dapat berfungsi, kerana fungsi `updateElement()` kami pada masa ini hanya menyokong kandungan teks. Mari ubah kodnya sedikit: @@ -311,7 +311,7 @@ function updateElement(id, textOrNode) { } ``` -Kami menggunakan kaedah [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) kerana ia membolehkan melampirkan teks atau [DOM Nodes] (https : //developer.mozilla.org/en-US/docs/Web/API/Node) ke elemen induk, yang sangat sesuai untuk semua kes penggunaan kami. +Kami menggunakan kaedah [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) kerana ia membolehkan melampirkan teks atau [DOM Nodes] (https : //developer.mozilla.org/docs/Web/API/Node) ke elemen induk, yang sangat sesuai untuk semua kes penggunaan kami. Sekiranya anda cuba menggunakan akaun `test` untuk log masuk, kini anda akan melihat senarai transaksi di papan pemuka 🎉. @@ -319,7 +319,7 @@ Sekiranya anda cuba menggunakan akaun `test` untuk log masuk, kini anda akan mel ## 🚀 Cabaran -Bekerjasama untuk menjadikan halaman papan pemuka kelihatan seperti aplikasi perbankan sebenar. Sekiranya anda sudah menggayakan aplikasi anda, cuba gunakan [pertanyaan media](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries) untuk membuat [responsive design](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) berfungsi dengan baik pada kedua-dua desktop dan peranti mudah alih. +Bekerjasama untuk menjadikan halaman papan pemuka kelihatan seperti aplikasi perbankan sebenar. Sekiranya anda sudah menggayakan aplikasi anda, cuba gunakan [pertanyaan media](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) untuk membuat [responsive design](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) berfungsi dengan baik pada kedua-dua desktop dan peranti mudah alih. Berikut adalah contoh halaman papan pemuka yang digayakan: diff --git a/7-bank-project/3-data/translations/README.zh-tw.md b/7-bank-project/3-data/translations/README.zh-tw.md new file mode 100644 index 00000000..79b9df9d --- /dev/null +++ b/7-bank-project/3-data/translations/README.zh-tw.md @@ -0,0 +1,336 @@ +# 建立銀行網頁應用程式 Part 3:取得並使用資料 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/45?loc=zh_tw) + +### 大綱 + +每一個網頁應用程式的核心為*資料*。資料有很多種格式,但它們的目的都是為了顯示使用者需要的資訊。網頁應用程式變得高互動性與複雜,使用者如何取得內容並與之進行互動變成網頁開發重要的一環。 + +在這堂課中,我們會了解伺服器是如何非同步地取得資料,並在不重新載入 HTML 的情況下,利用這些資料顯示在網頁上。 + +### 開始之前 + +你需要先完成系列課程 ── [登入與註冊表單](../../2-forms/translations/README.zh-tw.md)。你還需要安裝 [Node.js](https://nodejs.org) 並[執行伺服器 API](../../api/translations/README.zh-tw.md)。 + +你可以測試伺服器是否運作正常,在終端機中輸入指令: + +```sh +curl http://localhost:5000/api +# -> 會回傳結果 "Bank API v1.0.0" +``` + +--- + +## AJAX 和取得資料 + +傳統的網頁在使用者點擊連結,或是提交表單資料時,重新載入全部的 HTML 頁面來更新網頁內容。每當資料要被更新時,伺服器就需要回傳全新的 HTML 頁面給瀏覽器處理,同時也干涉到使用者正在進行的動作,重新載入的機制也限制了許多互動功能。這種工作流程被稱為*多頁面應用程式(Multi-Page Application)*,簡稱 *MPA*。 + + + +網頁應用程式變得更加複雜,促使新的技術問世:[AJAX (Asynchronous JavaScript and XML)](https://zh.wikipedia.org/wiki/AJAX)。 + +這個技巧允許網頁應用程式使用 JavaScript 非同步地傳遞與接收伺服器的資料,不需要重新載入 HTML 頁面,也反映在更快速的更新速率與更流暢的使用者體驗。在接收伺服器的新資料時,目前的 HTML 頁面可以被 JavaScript 利用 [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) API 更新。自此之後,這種流程演變成現今的[*單一頁面應用程式(Single-Page Application)*,*SPA*](https://zh.wikipedia.org/wiki/%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8)。 + + + +在 AJAX 早期,唯一取得資料的 API 為 [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)。但當代的瀏覽器已經建立出更方便且強大的 [`Fetch` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),它們使用 Promises 物件且更適合應用在 JSON 資料上。 + +> 許多當代瀏覽器支援 `Fetch API`,如果你想確認你的網頁應用程式是否運作在舊款的瀏覽器,檢查[caniuse.com 上的相容性測試](https://caniuse.com/fetch)是一個好方法。 + +### 課題 + +在[前一堂課程中](../../2-forms/translations/README.zh-tw.md),我們製作出註冊表單來建立新帳戶。現在我們來加入新程式,使用現有的帳戶登入,並取得其相關資料。開啟檔案 `app.js`並新增函式 `login`: + +```js +async function login() { + const loginForm = document.getElementById('loginForm') + const user = loginForm.user.value; +} +``` + +現在我們利用 `getElementById()` 接收表單元素,並藉由 `loginForm.user.value` 取得輸入框內的使用者名稱。每一個表單控制可以以各自名稱(即 HTML 內的 `name` 屬性)來存取。 + +就像我們為註冊帳戶作的事一樣,我們建立另一個函式來執行伺服器請求,但這次是為了取得帳戶資料: + +```js +async function getAccount(user) { + try { + const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user)); + return await response.json(); + } catch (error) { + return { error: error.message || 'Unknown error' }; + } +} +``` + +我們使用 `fetch` API 來向伺服器做非同步資料請求。這次我們不需要添加額外的參數,如網址,我們只詢問資料內容。預設上,`fetch` 建立出 [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) HTTP 請求,即我們想做的事情。 + +✅ 函式 `encodeURIComponent()` 可以轉換網址內的特殊字元。如果我們不呼叫這個函式,而是直接將 `user` 這項數值放入網址中,這會發生什麼問題? + +讓我們來更新函式 `login`,使用 `getAccount`: + +```js +async function login() { + const loginForm = document.getElementById('loginForm') + const user = loginForm.user.value; + const data = await getAccount(user); + + if (data.error) { + return console.log('loginError', data.error); + } + + account = data; + navigate('/dashboard'); +} +``` + +首先,`getAccount` 是一個非同步函式,它利用關鍵字 `await` 等待伺服器的回傳結果。就如其他伺服器請求一樣,我們也必須要處理錯誤的情況。現在我們只加錯誤訊息給這些情況,之後再回過頭解決這些問題。 + +接著,我們必須儲存資料,在之後可以輸出成儀表板的資訊。目前變數 `account` 還沒存在,我們建立它的全域變數在檔案最上方: + +```js +let account = null; +``` + +在用戶資料存到變數中後,我們可以使用函式 `navigate()` 從*登入*頁面切換到*儀表板*頁面。 + +最後,在登入表單提交時,呼叫函式 `login`。修改 HTML 語法: + +```html +<form id="loginForm" action="javascript:login()"> +``` + +測試註冊功能,以及新註冊的帳戶的登入行為是否運作正常。 + +在進行下一步驟前,我們還必須完成函式 `register`。在此函式的最下方加入: + +```js +account = result; +navigate('/dashboard'); +``` + +✅ 你知道在預設上,你只能從*同一個網域(domain)與連接埠(port)*的網頁呼叫伺服器 APIs嗎?這是瀏覽器強制性的安全機制。但我們的網頁應用程式在 `localhost:3000` 上執行,而伺服器 API 則在 `localhost:5000` 上執行。為什麼這樣能正常運作?利用[跨來源資源共用 (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS),只要伺服器添加特殊的標頭檔到網頁回應中,我們就可以處理跨資源的 HTTP 請求,允許特殊的網域進行呼叫。 + +> 藉由前往[此課程](https://docs.microsoft.com/en-us/learn/modules/use-apis-discover-museum-art?WT.mc_id=academic-13441-cxa)學習更多有關 API 的資訊。 + +## 更新 HTML 顯示資料 + +現在取得完用戶資料,我們必須更新到現有的 HTML 上。我們已經知道如何接收 DOM 的元素,例子為 `document.getElementById()`。只要你有元素,這邊有一些 API 讓你修改,或是新增子元素上去: + +- 使用 [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) 屬性,你可以改變元素的文字內容。注意改變此數值會刪除它的所有子元素(若存在的話),並以該文字內容來替換它。同時,這也是個有效的方法來刪去所有的子成員,只要賦予它空字串 `''`。 + +- 使用 [`document.createElement()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) 與 [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) 這兩方法,你可以建立並接上一到多個子元素成員。 + +✅ 使用 [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) 元素屬性也能改變 HTML 的內容,但這方法要避免使用。這可能會遭遇有關[跨網站指令碼 (XSS)](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)的攻擊。 + +### 課題 + +在來到儀表板畫面之前,我們還需要幫*登入*頁面加一件事。目前,如果你試著使用不存在的帳戶進行登入,訊息只會出現在命令欄中,而使用者不會發覺到任何事情改變,也不清楚網頁發生了什麼事。 + +我們在登入表單中新增顯示錯誤訊息的地方。最好的地方為登入按鈕 `<button>` 之前: + +```html +... +<div id="loginError"></div> +<button>Login</button> +... +``` + +這個 `<div>` 元素為空的,代表著畫面不會印出任何訊息,直到我們添加內容進去。我們還給了它 `id`,讓 JavaScript 可以容易地存取它。 + +回到檔案 `app.js`,建立新的補助函數 `updateElement`: + +```js +function updateElement(id, text) { + const element = document.getElementById(id); + element.textContent = text; +} +``` + +這條就很直觀:給定元素的 *id* 與 *text*,它會更新 DOM 元素內符合 `id` 條件的文字內容。我們也使用這個方法到前面 `login` 函式的錯誤訊息中: + +```js +if (data.error) { + return updateElement('loginError', data.error); +} +``` + +現在,試著以不合法的帳戶進行登入,你應該能看到像這樣的畫面: + + + +現在我們印出錯誤訊息,但螢幕報讀器並沒有做任何報讀。為了讓被動態加入的文字能被螢幕報讀器閱讀出來,我們需要使用 [Live Region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)。這邊我們使用一種 Live Region 的類型 alert: + +```html +<div id="loginError" role="alert"></div> +``` + +建立同樣的行為到函式 `register` 的錯誤訊息當中,也別忘了更新你的 HTML。 + +## 在儀表板顯示資訊 + +使用同樣的技巧,我們需要將帳戶資訊印在儀表板頁面中。 + +這是從伺服器接收到的帳戶資料物件: + +```json +{ + "user": "test", + "currency": "$", + "description": "Test account", + "balance": 75, + "transactions": [ + { "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 }, + { "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 }, + { "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 } + ], +} +``` + +> 筆記:為了讓開發更加的容易,你可以使用已經存在資料的帳戶 `test`。 + +### 課題 + +我們開始置換掉 HTML 檔內的 "Balance" 區域,加入放置區: + +```html +<section> + Balance: <span id="balance"></span><span id="currency"></span> +</section> +``` + +我們還需要在下方新增區域來顯示帳戶資訊: + +```html +<h2 id="description"></h2> +``` + +✅ 表示帳戶資訊的函式剛好為在內容的標題處,我們可以將它作為語義化的標頭。學習更多關於[標頭結構](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility),它對於網頁親和力格外重要,也明顯地表達出頁面的標頭位置。 + +接著,我們在 `app.js` 檔案中加入新的函式來為放置區新增內容: + +```js +function updateDashboard() { + if (!account) { + return navigate('/login'); + } + + updateElement('description', account.description); + updateElement('balance', account.balance.toFixed(2)); + updateElement('currency', account.currency); +} +``` + +首先,我們需要先檢查帳戶的資料。使用我們之前建立的函式 `updateElement()` 來更新 HTML 檔。 + +> 為了讓帳戶餘額漂亮地呈現,我們使用 [`toFixed(2)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 這個方法,強迫數值只顯示到小數點第二位。 + +現在,每當儀表板被載入時,我們就需要呼叫函式 `updateDashboard()`。如果你已經完成[課程一的作業](../../1-template-route/translations/assignment.zh-tw.md),就不需要額外做處理,不然你可以使用接下來的設定。 + +加入這段程式碼到函式 `updateRoute()` 的下方: + +```js +if (typeof route.init === 'function') { + route.init(); +} +``` + +並更新路由定義: + +```js +const routes = { + '/login': { templateId: 'login' }, + '/dashboard': { templateId: 'dashboard', init: updateDashboard } +}; +``` + +做完這些更動後,當儀表板要被呈現時,函式 `updateDashboard() 就會被呼叫。在你登入後就能看到帳戶的描述、餘額與交易狀況。 + +## 利用 HTML 模板動態建立表格列 + +在[第一堂課](../../1-template-route/translations/README.zh-tw.md)中,我們使用 HTML 模板與方法 [`appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild) 來做出應用程式內的轉換。模板還能執行更小規模的行為,動態地改變一部份的頁面 + +我們使用類似的方式來顯示 HTML 表格中的交易清單。 + +### 課題 + +加入新的模板到 HTML 的 `<body>` 中: + +```html +<template id="transaction"> + <tr> + <td></td> + <td></td> + <td></td> + </tr> +</template> +``` + +這個模板表示單一條的表格列,其中包含了三格欄位:交易的*日期*、*物件* 與 *金額*。 + +接著,加入 `id` 屬性到模板的表格 `<tbody>` 元素中,讓 JavaScript 能更容易地取得: + +```html +<tbody id="transactions"></tbody> +``` + +當我們的 HTML 準備好時,我們切換到 JavaScript 檔案中,加入新函式 `createTransactionRow`: + +```js +function createTransactionRow(transaction) { + const template = document.getElementById('transaction'); + const transactionRow = template.content.cloneNode(true); + const tr = transactionRow.querySelector('tr'); + tr.children[0].textContent = transaction.date; + tr.children[1].textContent = transaction.object; + tr.children[2].textContent = transaction.amount.toFixed(2); + return transactionRow; +} +``` + +這個函式做就如它名字的功能:藉由剛建立的模板,建立出新的表格列並填入交易明細的資料。我們會在函式 `updateDashboard()` 中,利用它來更新表格: + +```js +const transactionsRows = document.createDocumentFragment(); +for (const transaction of account.transactions) { + const transactionRow = createTransactionRow(transaction); + transactionsRows.appendChild(transactionRow); +} +updateElement('transactions', transactionsRows); +``` + +這裡我們使用了方法 [`document.createDocumentFragment()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment),建立新的 DOM 分段,再接到我們的 HTML 表格中。 + +我們還需要做一件事才能讓程式運作正常,目前函式 `updateElement()` 只能接受文字類型的內容。我們稍微修改一下程式碼: + +```js +function updateElement(id, textOrNode) { + const element = document.getElementById(id); + element.textContent = ''; // Removes all children + element.append(textOrNode); +} +``` + +我們使用方法 [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append),它能連接文字或者是 [DOM 節點](https://developer.mozilla.org/en-US/docs/Web/API/Node)到父元素中,正好滿足我們的需求。 + +試著以 `test` 帳戶來登入,你應該能看到儀表板顯示出交易明細了 🎉。 + +--- + +## 🚀 挑戰 + +花功夫讓儀表板頁面看起來像是正規的銀行界面。如果你已經為你的應用程式做好造型,你可以試試 [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries) 來建立出[回應式網頁設計](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks),它能完美地呈現在電腦或是行動裝置上。 + +這邊有造型過後的儀表板例子: + + + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/46?loc=zh_tw) + +## 作業 + +[重構並註解你的程式碼](assignment.zh-tw.md) diff --git a/7-bank-project/3-data/translations/assignment.nl.md b/7-bank-project/3-data/translations/assignment.nl.md new file mode 100644 index 00000000..6114def3 --- /dev/null +++ b/7-bank-project/3-data/translations/assignment.nl.md @@ -0,0 +1,15 @@ +# Refactoreer en becommentarieer uw code + +## Instructies + +Naarmate uw codebase groeit, is het belangrijk om uw code regelmatig te refactoren om deze in de loop van de tijd leesbaar en onderhoudbaar te houden. Voeg opmerkingen toe en refactoreer uw `app.js` om de kwaliteit van de code te verbeteren: + +- Extraheer constanten, zoals de basis-URL van de server-API +- Factoriseer vergelijkbare code: u kunt bijvoorbeeld een `sendRequest()` functie maken om de code die wordt gebruikt in zowel `createAccount()` als `getAccount()` groeperen +- Reorganiseer de code zodat deze gemakkelijker leesbaar is en voeg opmerkingen toe + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| | Code is becommentarieerd, goed georganiseerd in verschillende secties en gemakkelijk te lezen. Constanten worden geëxtraheerd en er is een gefactoriseerde `sendRequest()`-functie gemaakt. | Code is schoon, maar kan nog worden verbeterd met meer opmerkingen, constante extractie of factorisatie. | Code is rommelig, er wordt geen commentaar op gegeven, constanten worden niet geëxtraheerd en code wordt niet in factoren verwerkt. | diff --git a/7-bank-project/3-data/translations/assignment.zh-tw.md b/7-bank-project/3-data/translations/assignment.zh-tw.md new file mode 100644 index 00000000..91b20b47 --- /dev/null +++ b/7-bank-project/3-data/translations/assignment.zh-tw.md @@ -0,0 +1,15 @@ +# 重構並註解你的程式碼 + +## 簡介 + +正當你的程式碼越來越多時,頻繁地重構你的程式,讓程式碼容易去閱讀與維護變得十分重要。加入一些註解並重構檔案 `app.js` 來增進檔案的品質: + +- 取出常數,好比說伺服器 API 的根網址 +- 重構相同的程式碼:舉例來說,你可以建立函式 `sendRequest()` 來合併 `createAccount()` 與 `getAccount()`。 +- 重新編排你的程式和加入註解,讓它更容易地閱讀。 + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------- | +| | 程式碼有做註解,分塊地整理好。常數有被取出來且函式 `sendRequest()` 已設定完成 | 程式碼有做過處理,但仍可以藉由加入註解、排版與重構來增進品質 | 程式碼很雜亂,缺乏註解,常數與函式並沒有做規劃 | diff --git a/7-bank-project/4-state-management/README.md b/7-bank-project/4-state-management/README.md index 689335e0..8df308fb 100644 --- a/7-bank-project/4-state-management/README.md +++ b/7-bank-project/4-state-management/README.md @@ -84,9 +84,9 @@ Now that we have put in place the `state` object to store our data, the next ste To avoid having changes made to the `state` object, it's also a good practice to consider it [*immutable*](https://en.wikipedia.org/wiki/Immutable_object), meaning that it cannot be modified at all. It also means that you have to create a new state object if you want to change anything in it. By doing this, you build a protection about potentially unwanted [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)), and open up possibilities for new features in your app like implementing undo/redo, while also making it easier to debug. For example, you could log every change made to the state and keep a history of the changes to understand the source of a bug. -In JavaScript, you can use [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) to create an immutable version of an object. If you try to make changes to an immutable object, an exception will be raised. +In JavaScript, you can use [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) to create an immutable version of an object. If you try to make changes to an immutable object, an exception will be raised. -✅ Do you know the difference between a *shallow* and a *deep* immutable object? You can read about it [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). +✅ Do you know the difference between a *shallow* and a *deep* immutable object? You can read about it [here](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). ### Task @@ -101,7 +101,7 @@ function updateState(property, newData) { } ``` -In this function, we're creating a new state object and copy data from the previous state using the [*spread (`...`) operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Then we override a particular property of the state object with the new data using the [bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` for assignment. Finally, we lock the object to prevent modifications using `Object.freeze()`. We only have the `account` property stored in the state for now, but with this approach you can add as many properties as you need in the state. +In this function, we're creating a new state object and copy data from the previous state using the [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Then we override a particular property of the state object with the new data using the [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` for assignment. Finally, we lock the object to prevent modifications using `Object.freeze()`. We only have the `account` property stored in the state for now, but with this approach you can add as many properties as you need in the state. We'll also update the `state` initialization to make sure the initial state is frozen too: @@ -149,16 +149,16 @@ When you want to persist data in your browser, there are a few important questio - *Is the data sensitive?* You should avoid storing any sensitive data on client, such as user passwords. - *For how long do you need to keep this data?* Do you plan to access this data only for the current session or do you want it to be stored forever? -There are multiple ways of storing information inside a web app, depending on what you want to achieve. For example, you can use the URLs to store a search query, and make it shareable between users. You can also use [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) if the data needs to be shared with the server, like [authentication](https://en.wikipedia.org/wiki/Authentication) information. +There are multiple ways of storing information inside a web app, depending on what you want to achieve. For example, you can use the URLs to store a search query, and make it shareable between users. You can also use [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies) if the data needs to be shared with the server, like [authentication](https://en.wikipedia.org/wiki/Authentication) information. Another option is to use one of the many browser APIs for storing data. Two of them are particularly interesting: -- [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage): a [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) allowing to persist data specific to the current web site across different sessions. The data saved in it never expires. -- [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage): this one is works the same as `localStorage` except that the data stored in it is cleared when the session ends (when the browser is closed). +- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): a [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) allowing to persist data specific to the current web site across different sessions. The data saved in it never expires. +- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): this one is works the same as `localStorage` except that the data stored in it is cleared when the session ends (when the browser is closed). -Note that both these APIs only allow to store [strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). If you want to store complex objects, you will need to serialize it to the [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) format using [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). +Note that both these APIs only allow to store [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). If you want to store complex objects, you will need to serialize it to the [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) format using [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). -✅ If you want to create a web app that does not work with a server, it's also possible to create a database on the client using the [`IndexedDB` API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). This one is reserved for advanced use cases or if you need to store significant amount of data, as it's more complex to use. +✅ If you want to create a web app that does not work with a server, it's also possible to create a database on the client using the [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). This one is reserved for advanced use cases or if you need to store significant amount of data, as it's more complex to use. ### Task diff --git a/7-bank-project/4-state-management/assignment.md b/7-bank-project/4-state-management/assignment.md index 6d5ce37f..6aeed403 100644 --- a/7-bank-project/4-state-management/assignment.md +++ b/7-bank-project/4-state-management/assignment.md @@ -6,7 +6,7 @@ Our bank app is still missing one important feature: the possibility to enter ne Using everything that you've learnt in the four previous lessons, implement an "Add transaction" dialog: - Add an "Add transaction" button in the dashboard page -- Either create a new page with an HTML template, or use JavaScript to show/hide the dialog HTML without leaving the dashboard page (you can use [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) property for that, or CSS classes) +- Either create a new page with an HTML template, or use JavaScript to show/hide the dialog HTML without leaving the dashboard page (you can use [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) property for that, or CSS classes) - Make sure you handle [keyboard and screen reader accessibility](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) for the dialog - Implement an HTML form to receive input data - Create JSON data from the form data and send it to the API diff --git a/7-bank-project/4-state-management/translations/README.es.md b/7-bank-project/4-state-management/translations/README.es.md index 798edd60..88173210 100644 --- a/7-bank-project/4-state-management/translations/README.es.md +++ b/7-bank-project/4-state-management/translations/README.es.md @@ -83,9 +83,9 @@ Ahora que hemos implementado el objeto `state` para almacenar nuestros datos, el Para evitar que se realicen cambios en el objeto `state`, también es una buena práctica considerarlo [*inmutable*](https://en.wikipedia.org/wiki/Immutable_object), lo que significa que no se puede modificar en absoluto. También significa que debe crear un nuevo objeto de estado si desea cambiar algo en él. Al hacer esto, crea una protección contra [efectos secundarios](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) potencialmente no deseados y abre posibilidades para nuevas funciones en su aplicación, como implementar deshacer / rehacer, al mismo tiempo que facilita la depuración. Por ejemplo, puede registrar todos los cambios realizados en el estado y mantener un historial de los cambios para comprender el origen de un error. -En JavaScript, puede usar [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) para crear una versión inmutable de un objeto. Si intenta realizar cambios en un objeto inmutable, se generará una excepción. +En JavaScript, puede usar [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) para crear una versión inmutable de un objeto. Si intenta realizar cambios en un objeto inmutable, se generará una excepción. -✅ ¿Conoce la diferencia entre un objeto *superficial* y un objeto inmutable *profundo*? Puede leer sobre esto [aquí](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). +✅ ¿Conoce la diferencia entre un objeto *superficial* y un objeto inmutable *profundo*? Puede leer sobre esto [aquí](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). ### Tarea @@ -100,7 +100,7 @@ function updateState(property, newData) { } ``` -En esta función, estamos creando un nuevo objeto de estado y copiamos datos del estado anterior usando el operador [*spread (`...`)*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Luego anulamos una propiedad particular del objeto de estado con los nuevos datos usando la [notación de corchetes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` para asignación. Finalmente, bloqueamos el objeto para evitar modificaciones usando `Object.freeze()`. Solo tenemos la propiedad `account` almacenada en el estado por ahora, pero con este enfoque puede agregar tantas propiedades como necesite en el estado. +En esta función, estamos creando un nuevo objeto de estado y copiamos datos del estado anterior usando el operador [*spread (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Luego anulamos una propiedad particular del objeto de estado con los nuevos datos usando la [notación de corchetes](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` para asignación. Finalmente, bloqueamos el objeto para evitar modificaciones usando `Object.freeze()`. Solo tenemos la propiedad `account` almacenada en el estado por ahora, pero con este enfoque puede agregar tantas propiedades como necesite en el estado. También actualizaremos la inicialización del `estado` para asegurarnos de que el estado inicial también esté congelado: @@ -148,16 +148,16 @@ Cuando desee conservar los datos en su navegador, hay algunas preguntas importan - *¿Son los datos confidenciales?* Debe evitar almacenar datos confidenciales en el cliente, como contraseñas de usuario. - *¿Por cuánto tiempo necesita conservar estos datos?* ¿Planea acceder a estos datos solo para la sesión actual o desea que se almacenen para siempre? -Hay varias formas de almacenar información dentro de una aplicación web, dependiendo de lo que desee lograr. Por ejemplo, puede utilizar las URL para almacenar una consulta de búsqueda y hacer que se pueda compartir entre los usuarios. También puede utilizar [cookies HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) si los datos deben compartirse con el servidor, como [autenticación](https://en.wikipedia.org/wiki/Authentication) información. +Hay varias formas de almacenar información dentro de una aplicación web, dependiendo de lo que desee lograr. Por ejemplo, puede utilizar las URL para almacenar una consulta de búsqueda y hacer que se pueda compartir entre los usuarios. También puede utilizar [cookies HTTP](https://developer.mozilla.org/docs/Web/HTTP/Cookies) si los datos deben compartirse con el servidor, como [autenticación](https://en.wikipedia.org/wiki/Authentication) información. Otra opción es utilizar una de las muchas API del navegador para almacenar datos. Dos de ellos son particularmente interesantes: -- [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage): un [almacén de claves / valores](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) que permite conservar datos específicos del sitio web actual en diferentes sesiones. Los datos guardados en él nunca caducan. -- [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage): este funciona igual que `localStorage` excepto que los datos almacenados en él son se borra cuando finaliza la sesión (cuando se cierra el navegador). +- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): un [almacén de claves / valores](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) que permite conservar datos específicos del sitio web actual en diferentes sesiones. Los datos guardados en él nunca caducan. +- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): este funciona igual que `localStorage` excepto que los datos almacenados en él son se borra cuando finaliza la sesión (cuando se cierra el navegador). -Tenga en cuenta que estas dos API solo permiten almacenar [cadenas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). Si desea almacenar objetos complejos, deberá serializarlos al formato [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) usando [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). +Tenga en cuenta que estas dos API solo permiten almacenar [cadenas](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Si desea almacenar objetos complejos, deberá serializarlos al formato [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) usando [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). -✅ Si desea crear una aplicación web que no funcione con un servidor, también es posible crear una base de datos en el cliente usando la [API de IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). Este está reservado para casos de uso avanzados o si necesita almacenar una cantidad significativa de datos, ya que es más complejo de usar. +✅ Si desea crear una aplicación web que no funcione con un servidor, también es posible crear una base de datos en el cliente usando la [API de IndexedDB](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Este está reservado para casos de uso avanzados o si necesita almacenar una cantidad significativa de datos, ya que es más complejo de usar. ### Tarea diff --git a/7-bank-project/4-state-management/translations/README.it.md b/7-bank-project/4-state-management/translations/README.it.md index 2af21d74..987e7515 100644 --- a/7-bank-project/4-state-management/translations/README.it.md +++ b/7-bank-project/4-state-management/translations/README.it.md @@ -86,7 +86,7 @@ Per evitare che vengano apportate modifiche all'oggetto `state` è anche una buo In JavaScript, si può utilizzare [`Object.freeze()`](https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) per creare una versione immutabile di un oggetto. Se si prova ad apportare modifiche a un oggetto immutabile, verrà sollevata un'eccezione. -✅ Si conosce la differenza tra un oggetto *shallow* e uno *deep* immutabile? Si può leggere [qui](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze) per saperne di più. +✅ Si conosce la differenza tra un oggetto *shallow* e uno *deep* immutabile? Si può leggere [qui](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze) per saperne di più. ### Attività @@ -101,7 +101,7 @@ function updateState(property, newData) { } ``` -In questa funzione, si crea un nuovo oggetto di stato e si copiano i dati dallo stato precedente utilizzando l' [*operatore spread (`...`)*](https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Operators/Spread_syntax). Quindi si sovrascrive una particolare proprietà dell'oggetto state con i nuovi dati usando la [notazione tra parentesi quadre](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` per l'assegnazione. Infine, si blocca l'oggetto per impedire modifiche utilizzando `Object.freeze()`. Per ora si ha solo la proprietà `account` memorizzata nello stato, ma con questo approccio si possono aggiungere tutte le proprietà che servono nello stato. +In questa funzione, si crea un nuovo oggetto di stato e si copiano i dati dallo stato precedente utilizzando l' [*operatore spread (`...`)*](https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Operators/Spread_syntax). Quindi si sovrascrive una particolare proprietà dell'oggetto state con i nuovi dati usando la [notazione tra parentesi quadre](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` per l'assegnazione. Infine, si blocca l'oggetto per impedire modifiche utilizzando `Object.freeze()`. Per ora si ha solo la proprietà `account` memorizzata nello stato, ma con questo approccio si possono aggiungere tutte le proprietà che servono nello stato. Si aggiornerà anche l'inizializzazione di `state` per assicurarsi che anche lo stato iniziale sia congelato: diff --git a/7-bank-project/4-state-management/translations/README.ko.md b/7-bank-project/4-state-management/translations/README.ko.md index e112c20d..db66b1ac 100644 --- a/7-bank-project/4-state-management/translations/README.ko.md +++ b/7-bank-project/4-state-management/translations/README.ko.md @@ -84,9 +84,9 @@ const account = state.account; `state` 객체가 변경되지 않으려면, [*immutable*](https://en.wikipedia.org/wiki/Immutable_object)한 것으로 간주하는 것이 좋습니다. 즉, 전혀 수정할 수 없다는 점을 의미합니다. 또한 변경하려는 경우에는 새로운 상태 객체를 만들어야 된다는 점을 의미합니다. 이렇게 하면, 잠재적으로 원하지 않는 [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science))에 보호하도록 만들고, undo/redo를 구현하는 것 처럼 앱의 새로운 기능에 대한 가능성을 열어 디버깅을 더 쉽게 만듭니다. 예를 들자면, 상태에 대한 모든 변경점을 남기고 유지하여 버그의 원인을 파악할 수 있습니다. -JavaScript에서, [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)를 사용하여 변경할 수 없는 버전의 객체를 만들 수 있습니다. 변경 불가능한 객체를 바꾸려고 하면 예외가 발생합니다. +JavaScript에서, [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)를 사용하여 변경할 수 없는 버전의 객체를 만들 수 있습니다. 변경 불가능한 객체를 바꾸려고 하면 예외가 발생합니다. -✅ *shallow*와 *deep* 불변 객체의 차이점을 알고 계시나요? [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze)에서 읽을 수 있습니다. +✅ *shallow*와 *deep* 불변 객체의 차이점을 알고 계시나요? [here](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze)에서 읽을 수 있습니다. ### 작업 @@ -101,7 +101,7 @@ function updateState(property, newData) { } ``` -이 함수에서는, 새로운 상태 객체를 만들고 [*spread (`...`) operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)로 이전 상태의 데이터를 복사합니다. 그러고 할당을 위해 [bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]`를 사용하여 상태 객체의 특정한 속성을 새로운 데이터로 다시 정의합니다. 최종적으로, 변경되는 것을 막기 위해 `Object.freeze()`를 사용하여 객체를 잠급니다. 지금 상태에는 `account` 속성만 저장되어 있지만, 이 접근 방식으로 상태에 필요한 순간마다 많은 속성들을 추가할 수 있습니다. +이 함수에서는, 새로운 상태 객체를 만들고 [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)로 이전 상태의 데이터를 복사합니다. 그러고 할당을 위해 [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]`를 사용하여 상태 객체의 특정한 속성을 새로운 데이터로 다시 정의합니다. 최종적으로, 변경되는 것을 막기 위해 `Object.freeze()`를 사용하여 객체를 잠급니다. 지금 상태에는 `account` 속성만 저장되어 있지만, 이 접근 방식으로 상태에 필요한 순간마다 많은 속성들을 추가할 수 있습니다. 또한 초기 상태가 동결되도록 `state` 초기화 작업도 갱신합니다: @@ -149,16 +149,16 @@ function logout() { - *민감한 데이터인가요?* 사용자 암호와 같은, 민감한 데이터는 클라이언트에 저장하지 않아야 합니다. - *데이터를 얼마나 오래 보관해야 하나요?* 현재 세션에서만 데이터에 접근하거나 계속 저장할 계획인가요? -달성하려는 목표에 따라, 웹 앱 안에서 정보를 저장하는 방법에는 여러 가지가 있습니다. 예를 들면, URL을 사용하여 검색 쿼리를 저장하고, 사용자끼리 공유할 수 있습니다. [authentication](https://en.wikipedia.org/wiki/Authentication) 정보처럼, 데이터를 서버와 공유해야하는 경우에도 [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)를 사용할 수 있습니다. +달성하려는 목표에 따라, 웹 앱 안에서 정보를 저장하는 방법에는 여러 가지가 있습니다. 예를 들면, URL을 사용하여 검색 쿼리를 저장하고, 사용자끼리 공유할 수 있습니다. [authentication](https://en.wikipedia.org/wiki/Authentication) 정보처럼, 데이터를 서버와 공유해야하는 경우에도 [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies)를 사용할 수 있습니다. 다른 옵션으로는 데이터 저장을 위해 여러 브라우저 API 중 하나를 사용하는 것입니다. 그 중 2가지가 특히 흥미롭습니다: -- [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage): [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)는 다른 세션에서 현재 웹 사이트에 대한 특정 데이터를 유지할 수 있습니다. 저장된 데이터는 만료되지 않습니다. -- [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage): 이는 세션이 끝날 때(브라우저가 닫힐 때)에 저장된 데이터가 지워진다는 점을 제외하면 `localStorage`와 동일하게 작동합니다. +- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)는 다른 세션에서 현재 웹 사이트에 대한 특정 데이터를 유지할 수 있습니다. 저장된 데이터는 만료되지 않습니다. +- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): 이는 세션이 끝날 때(브라우저가 닫힐 때)에 저장된 데이터가 지워진다는 점을 제외하면 `localStorage`와 동일하게 작동합니다. -이 두 API는 모두 [strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)만 저장할 수 있습니다. 복잡한 객체를 저장하려면, [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)를 사용하여 [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) 포맷으로 직렬화해야 합니다. +이 두 API는 모두 [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)만 저장할 수 있습니다. 복잡한 객체를 저장하려면, [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)를 사용하여 [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) 포맷으로 직렬화해야 합니다. -✅ 서버에서 동작하지 않는 웹 앱을 만드려면, [`IndexedDB` API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)로 클라이언트에 데이터베이스를 만들 수도 있습니다. 이는 고급 사용 케이스이거나, 사용하기 복잡한 많은 양의 데이터를 저장해야 할 때에 사용하도록 되어있습니다. +✅ 서버에서 동작하지 않는 웹 앱을 만드려면, [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API)로 클라이언트에 데이터베이스를 만들 수도 있습니다. 이는 고급 사용 케이스이거나, 사용하기 복잡한 많은 양의 데이터를 저장해야 할 때에 사용하도록 되어있습니다. ### 작업 diff --git a/7-bank-project/4-state-management/translations/README.ms.md b/7-bank-project/4-state-management/translations/README.ms.md index 69488d05..851a6b8c 100644 --- a/7-bank-project/4-state-management/translations/README.ms.md +++ b/7-bank-project/4-state-management/translations/README.ms.md @@ -84,9 +84,9 @@ Sekarang kita telah meletakkan objek `state` untuk menyimpan data kita, langkah Untuk mengelakkan berlakunya perubahan pada objek `state`, adalah praktik yang baik untuk mempertimbangkannya [*tidak berubah*](https://en.wikipedia.org/wiki/Immutable_object), yang bermaksud bahawa ia tidak dapat diubah sama sekali. Ini juga bermaksud bahawa anda harus membuat objek keadaan baru jika anda ingin mengubah apa-apa di dalamnya. Dengan melakukan ini, anda membina perlindungan mengenai [kesan sampingan](https://en.wikipedia.org/wiki/Side_effect_ (computer_science)), dan membuka kemungkinan untuk ciri baru dalam aplikasi anda seperti melaksanakan undo / redo, sambil mempermudah debug. Sebagai contoh, anda boleh mencatat setiap perubahan yang dibuat ke negeri dan menyimpan sejarah perubahan untuk memahami sumber pepijat. -Dalam JavaScript, anda boleh menggunakan [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) untuk membuat versi yang tidak berubah dari sebuah objek. Sekiranya anda cuba membuat perubahan pada objek yang tidak dapat diubah, pengecualian akan ditimbulkan. +Dalam JavaScript, anda boleh menggunakan [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) untuk membuat versi yang tidak berubah dari sebuah objek. Sekiranya anda cuba membuat perubahan pada objek yang tidak dapat diubah, pengecualian akan ditimbulkan. -✅ Adakah anda tahu perbezaan antara objek *cetek* dan *dalam* tidak berubah? Anda boleh membacanya [di sini](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). +✅ Adakah anda tahu perbezaan antara objek *cetek* dan *dalam* tidak berubah? Anda boleh membacanya [di sini](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). ### Tugas @@ -101,7 +101,7 @@ function updateState(property, newData) { } ``` -Dalam fungsi ini, kami membuat objek keadaan baru dan menyalin data dari keadaan sebelumnya menggunakan operator [*spread (`...`) operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Kemudian kami menimpa harta benda objek tertentu dengan data baru menggunakan [notasi kurungan](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` untuk tugasan. Akhirnya, kita mengunci objek untuk mengelakkan pengubahsuaian menggunakan `Object.freeze()`. Kami hanya menyimpan harta `akaun` di negeri ini buat masa ini, tetapi dengan pendekatan ini anda dapat menambahkan seberapa banyak harta tanah yang anda perlukan di negeri ini. +Dalam fungsi ini, kami membuat objek keadaan baru dan menyalin data dari keadaan sebelumnya menggunakan operator [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Kemudian kami menimpa harta benda objek tertentu dengan data baru menggunakan [notasi kurungan](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` untuk tugasan. Akhirnya, kita mengunci objek untuk mengelakkan pengubahsuaian menggunakan `Object.freeze()`. Kami hanya menyimpan harta `akaun` di negeri ini buat masa ini, tetapi dengan pendekatan ini anda dapat menambahkan seberapa banyak harta tanah yang anda perlukan di negeri ini. Kami juga akan mengemas kini inisialisasi `state` untuk memastikan keadaan awal juga dibekukan: @@ -149,16 +149,16 @@ Apabila anda ingin menyimpan data dalam penyemak imbas anda, terdapat beberapa s - *Adakah data sensitif?* Anda harus mengelakkan menyimpan data sensitif pada pelanggan, seperti kata laluan pengguna. - *Berapa lama anda perlu menyimpan data ini?* Adakah anda merancang untuk mengakses data ini hanya untuk sesi semasa atau adakah anda ingin menyimpannya selamanya? -Terdapat banyak cara untuk menyimpan maklumat di dalam aplikasi web, bergantung pada apa yang ingin anda capai. Sebagai contoh, anda boleh menggunakan URL untuk menyimpan pertanyaan carian, dan menjadikannya boleh dibagikan antara pengguna. Anda juga boleh menggunakan [kuki HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) jika data perlu dikongsi dengan pelayan, seperti [pengesahan](https://en.wikipedia.org/wiki/Authentication) maklumat. +Terdapat banyak cara untuk menyimpan maklumat di dalam aplikasi web, bergantung pada apa yang ingin anda capai. Sebagai contoh, anda boleh menggunakan URL untuk menyimpan pertanyaan carian, dan menjadikannya boleh dibagikan antara pengguna. Anda juga boleh menggunakan [kuki HTTP](https://developer.mozilla.org/docs/Web/HTTP/Cookies) jika data perlu dikongsi dengan pelayan, seperti [pengesahan](https://en.wikipedia.org/wiki/Authentication) maklumat. Pilihan lain adalah menggunakan salah satu dari banyak API penyemak imbas untuk menyimpan data. Dua daripadanya sangat menarik: -- [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage): a [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) yang memungkinkan untuk mengekalkan data khusus untuk laman web semasa di pelbagai sesi. Data yang disimpan di dalamnya tidak akan luput. -- [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage): ini berfungsi sama seperti `localStorage` kecuali data yang disimpan di dalamnya dibersihkan semasa sesi berakhir (semasa penyemak imbas ditutup). +- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): a [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) yang memungkinkan untuk mengekalkan data khusus untuk laman web semasa di pelbagai sesi. Data yang disimpan di dalamnya tidak akan luput. +- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): ini berfungsi sama seperti `localStorage` kecuali data yang disimpan di dalamnya dibersihkan semasa sesi berakhir (semasa penyemak imbas ditutup). -Perhatikan bahawa kedua-dua API ini hanya membenarkan menyimpan [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String). Sekiranya anda ingin menyimpan objek yang kompleks, anda perlu membuat siri ke siri [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) menggunakan [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). +Perhatikan bahawa kedua-dua API ini hanya membenarkan menyimpan [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Sekiranya anda ingin menyimpan objek yang kompleks, anda perlu membuat siri ke siri [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) menggunakan [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). -✅ Sekiranya anda ingin membuat aplikasi web yang tidak berfungsi dengan pelayan, anda juga boleh membuat pangkalan data pada klien menggunakan [`IndexedDB` API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). Yang ini dikhaskan untuk kes penggunaan lanjutan atau jika anda perlu menyimpan sejumlah besar data, kerana lebih kompleks untuk digunakan. +✅ Sekiranya anda ingin membuat aplikasi web yang tidak berfungsi dengan pelayan, anda juga boleh membuat pangkalan data pada klien menggunakan [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Yang ini dikhaskan untuk kes penggunaan lanjutan atau jika anda perlu menyimpan sejumlah besar data, kerana lebih kompleks untuk digunakan. ### Tugas diff --git a/7-bank-project/4-state-management/translations/README.zh-tw.md b/7-bank-project/4-state-management/translations/README.zh-tw.md new file mode 100644 index 00000000..aab8db7e --- /dev/null +++ b/7-bank-project/4-state-management/translations/README.zh-tw.md @@ -0,0 +1,284 @@ +# 建立銀行網頁應用程式 Part 4: 狀態控管的概念 + +## 課前測驗 + +[課前測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/47?loc=zh_tw) + +### 大綱 + +隨著網頁應用越來越龐大,追蹤資料流的動向也是一種挑戰。程式取得了何種資料、網頁如何處理它、何時何處被更新上去……這些很容易地導致程式碼凌亂而難以維護。尤其是當你需要在不同頁面上做資料共享時,好比說使用者的資料。*狀態控管(state management)* 的觀念已經存在於所有程式中,我們也開始需要在開發複雜的網頁應用程式時,注意這個關鍵點。 + +在這個最終章內,我們會總覽整個程式並重新思考該如何管理程式狀態,讓瀏覽器能在任何時刻做重新整理,在不同的使用者階段維持資料的狀態。 + +### 開始之前 + +你需要先完成[取得資料](../../3-data/translations/README.zh-tw.md)的網頁開發章節。你還需要安裝 [Node.js](https://nodejs.org) 並於本地端[執行伺服器 API](../../api/translations/README.zh-tw.md)以管理使用者資料。 + +你可以測試伺服器是否運作正常,在終端機中輸入指令: + +```sh +curl http://localhost:5000/api +# -> should return "Bank API v1.0.0" as a result +``` + +--- + +## 思考狀態控管 + +在[前一堂課](../../3-data/translations/README.zh-tw.md)中,我們介紹了應用程式基本的狀態,全域變數 `account` 提供登入帳戶的相關銀行資料。然而,現在的專案存在著一些瑕疵。試著在儀表板介面中重新整理。發生了什麼事? + +目前我們的程式碼有三個問題: + +- 網頁狀態並沒有被儲存,當瀏覽器重新整理時,會被導回登入頁面。 +- 有許多函式會修改網頁狀態。隨著應用程式變大,我們很難去追蹤之後的改變,時刻地去更新相關的網頁狀態。 +- 網頁狀態並不完整,當你*登出*帳戶時,帳戶資訊仍然顯示在登入頁面上。 + +我們是可以逐一的解決這些問題,但這樣會創造出許多獨立的程式碼,讓應用程式更複雜而難以去管理。或者是我們停下來思考一下我們的策略。 + +> 我們究竟要解決什麼問題? + +[狀態控管(State management)](https://en.wikipedia.org/wiki/State_management)可以為兩項問題提供良好的解決方案: + +- 如何讓應用程式中的資料流容易理解? +- 如何讓網頁狀態一直與使用者介面,或是相關物件進行同步? + +一旦你處理好這些問題,其他問題可以被簡化,甚至被一併解決。有許多可能的方法能解決這些問題,但我們使用一種常見的解法:**中心化資料與更新方式**。資料流會呈現下列模式: + + + +> 我們不會處理如何讓資料同步觸發頁面的更新,這比較像是關於[回應式程式設計](https://zh.wikipedia.org/wiki/%E5%93%8D%E5%BA%94%E5%BC%8F%E7%BC%96%E7%A8%8B)的更進階知識。當你更深入網頁開發領域時,這是個很好的發展方向。 + +✅ 有許多函式庫提供狀態管理的方式,[Redux](https://redux.js.org) 就是常見的選擇。閱讀它的概念與運作模式,這是種有效的的學習方式,讓你在大型的網頁開發中預測潛在的風險,並預想解決方案。 + +### 課題 + +我們會先做一些程式重構。替換掉 `account` 的定義: + +```js +let account = null; +``` + +變成: + +```js +let state = { + account: null +}; +``` + +這個構想是要*中心化*應用程式資料到一個狀態物件中。目前我們只有 `account` 在狀態中,但這能提供未來新增新功能的基礎。 + +我們還需要更新與它相關的函式。在函式 `register()` 和 `login()` ,將 `account = ...` 替換為 `state.account = ...`。 + +在函式 `updateDashboard()` 的上方,加入此行: + +```js +const account = state.account; +``` + +這個重構並不會帶來任何提升,但這是之後改變上的基礎。 +This refactoring by itself did not bring much improvements, but the idea was to lay out the foundation for the next changes. + +## 追蹤資料改變 + +現在我們有 `state` 物件儲存資料了,接下來要來中心化這些更新。目標是能輕易地追蹤任何被觸發的改變。 + +為了避免改動 `state` 物件,我們考慮使它[*不可變*](https://zh.wikipedia.org/wiki/%E4%B8%8D%E5%8F%AF%E8%AE%8A%E7%89%A9%E4%BB%B6),意味著它不能被做任何的修改。 +這也代表你必須建立新的狀態物件來替換它。藉由這個方式,你就有一套保護措施阻絕潛在非預期[風險](https://zh.wikipedia.org/wiki/%E5%89%AF%E4%BD%9C%E7%94%A8_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)),也開創出應用程式內還原與重做的功能,讓程式偵錯更加的容易。舉例來說,你可以紀錄狀態的改變,儲存狀態的歷史紀錄來了解錯誤的來源。 + +在 JavaScript 中,你可以使用 [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) 來建立不可變物件。若你想在不可變物件上做更動,例外處理(exception)就會發生。 + +✅ 你知道*淺複製(shallow)*和*深複製(deep)*這兩種不可變物件的差別嗎?你可以從[這裡](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze)閱讀相關資訊。 + +### 課題 + +我們來建立新的函式 `updateState()`: + +```js +function updateState(property, newData) { + state = Object.freeze({ + ...state, + [property]: newData + }); +} +``` + +在這個函式中,我們會建立新的狀態物件,並利用[*展開運算子(`...`)(Spread Operator)*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)複製前一個資料狀態。接著,我們使用[括弧記法(Bracket Notation)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` 賦予並覆蓋特定的狀態物件。最後,我們為物件上鎖,`Object.freeze()` 避免任何的改動。目前我們只有 `account` 資料存在狀態中,利用此方法可以讓你新增任何你想要的資料。 + +我們會更新 `state` 初始化設定,確保初始狀態也被上鎖: + +```js +let state = Object.freeze({ + account: null +}); +``` + +接著,更新函式 `register`,將 `state.account = result;` 替換為: + +```js +updateState('account', result); +``` + +在函式 `login` 上做一樣的事,將 `state.account = data;` 替換為: + +```js +updateState('account', data); +``` + +藉由這個機會,我們能解決帳戶資料在*登出*時,不會被清除的問題。 + +建立新的函式 `logout()`: + +```js +function logout() { + updateState('account', null); + navigate('/login'); +} +``` + +在 `updateDashboard()` 中,替換重新導向 `return navigate('/login');` 為 `return logout()`。 + +試著註冊新的帳戶,登入登出以確保功能都運作正常。 + +> 提示:你可以觀察所有的狀態改變,在 `updateState()` 裡的最下方加入 `console.log(state)`,開啟瀏覽器開發工具,命令欄就會顯示狀態的紀錄。 + +## 紀錄狀態 + +多數的網頁應用程式需要儲存資料以確保運作正常。所有重要的資料都會存在資料庫中,並藉由伺服器 API 來存取,就像我們專案中的帳戶資料。但有時候,瀏覽器用戶端的應用程式也需要儲存一些資料,提供更好的使用者體驗與增進負載效能。 + +當你想在瀏覽器內儲存資料,你必須思考幾項重要的問題: + +- *這項資料很危險嗎?* 你應該要避免在用戶端儲存敏感的資料,例如帳戶密碼。 +- *你需要儲存資料多久?* 你打算短時間內做存取,還是永久地保存? + +網頁應用程式中有許多儲存資訊的方法,一切都取決於你想達成的目標。舉例來說,你可以利用網址來儲存搜尋資訊,讓使用者間能共享資訊。若資料需要與伺服器共享,好比說[認證](https://zh.wikipedia.org/wiki/%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81)資訊,你可以使用 [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)。 + +另一個選擇是使用其中一個廣大的瀏覽器 API 來儲存資料。下列這兩項就特別有趣: + +- [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):[Key/Value 儲存法](https://zh.wikipedia.org/wiki/%E9%94%AE-%E5%80%BC%E5%AD%98%E5%82%A8)可以保存不同時刻的網頁資料。這些資料不會有期限的限制。 +- [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage):它的運作模式與 `localStorage` 相同,只差在資料會在網頁段落結束時被清除,如瀏覽器關閉時。 + +紀錄一下這兩個 API 只能儲存[字串](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)格式。 +如果你想儲存更複雜的物件,你需要利用 [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) 將資料整理成 [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) 格式。 + +✅ 如果你想要建立不仰賴伺服器的網頁應用程式,你有辦法在用戶端建立資料庫。[`IndexedDB` API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) 可以應用在更進階的案例上,儲存更大量的資料,當然使用上也相對複雜。 + +### 課題 + +我們想讓使用者在登出之前,保持登入狀態。所以我們使用 `localStorage` 來儲存帳戶資料。首先,定義一組 key 來紀錄我們的資料內容。 + +```js +const storageKey = 'savedAccount'; +``` + +在函式 `updateState()` 末端加入此行: + +```js +localStorage.setItem(storageKey, JSON.stringify(state.account)); +``` + +藉由此方式,帳戶資料就能保存下來,並隨著之前中心化後的狀態而更新。我們開始從之前的重構獲取效益了 🙂。 + +當資料被儲存後,我們還需要在程式讀取時載入資料。在 `app.js` 下方編寫更多的初始化程式,建立新的函式 `init` 並收入之前的程式碼: + +```js +function init() { + const savedAccount = localStorage.getItem(storageKey); + if (savedAccount) { + updateState('account', JSON.parse(savedAccount)); + } + + // 之前的初始化程式 + window.onpopstate = () => updateRoute(); + updateRoute(); +} + +init(); +``` + +我們在此接收了儲存資料,並同步地更新狀態資訊。這必須在更新路由*之前*完成,否則有些程式碼會在頁面更新時,依據狀態來決定其行為。 + +當儲存完帳戶資料後,我們也定義了*儀表板*頁面為我們的預設首頁。若程式沒有找到資料,儀表板頁面也能重新導向回*登入*頁面。在 `updateRoute()` 中,替換回傳值 `return navigate('/login');` 為 `return navigate('/dashboard');`。 + +登入應用程式並重新整理頁面。你應該能維持在儀表板那頁。這個改變也解決了我們最初面臨的問題...... + +## 重整資料 + +......但我們可能也產生了新問題。啊呀! + +使用 `test` 帳戶進入儀表板頁面,在終端機內執行下列指令以建立新的交易項目: + +```sh +curl --request POST \ + --header "Content-Type: application/json" \ + --data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \ + http://localhost:5000/api/accounts/test/transactions +``` + +試著重新整理瀏覽器內儀表板頁面。發生了什麼事?你有看到新的交易項目嗎? + +感謝 `localStorage` 的幫助,狀態成功的儲存下來,但也代表我們在登出登入之前,不能再改變它的內容了! + +一個可能的修復策略是在儀表板載入時,重新載入帳戶資訊以避免資料不同步。 + +### 課題 + +建立新的函式 `updateAccountData`: + +```js +async function updateAccountData() { + const account = state.account; + if (!account) { + return logout(); + } + + const data = await getAccount(account.user); + if (data.error) { + return logout(); + } + + updateState('account', data); +} +``` + +這個方法能檢查我們是否已經登入,重新從伺服器載入用戶資料。 + +建立另一個函式 `refresh`: + +```js +async function refresh() { + await updateAccountData(); + updateDashboard(); +} +``` + +這能更新帳戶資料,更新 HTML 中的儀表板頁面。這是在儀表板路由被載入時,我們所需要呼叫的函式。更新路由定義為: + +```js +const routes = { + '/login': { templateId: 'login' }, + '/dashboard': { templateId: 'dashboard', init: refresh } +}; +``` + +試著重新載入儀表板,它現在應該能顯示更新後的帳戶資料。 + +--- + +## 🚀 挑戰 + +每一次儀表板載入時,我們都會重新載入帳戶資料,你認為我們還需要在用戶端儲存*所有的帳戶*資料嗎? + +試著改變 `localStorage` 內的儲存內容,只包含我們能運行程式的必要資料。 + +## 課後測驗 + +[課後測驗](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/48?loc=zh_tw) + +## 作業 + +[編寫"加入交易明細"視窗](assignment.zh-tw.md) + +這邊有完成之後的結果: + + diff --git a/7-bank-project/4-state-management/translations/assignment.es.md b/7-bank-project/4-state-management/translations/assignment.es.md index 71672511..c28d7ada 100644 --- a/7-bank-project/4-state-management/translations/assignment.es.md +++ b/7-bank-project/4-state-management/translations/assignment.es.md @@ -6,7 +6,7 @@ A nuestra aplicación bancaria todavía le falta una característica importante: Utilizando todo lo que ha aprendido en las cuatro lecciones anteriores, implemente un cuadro de diálogo "Agregar transacción": - Agregue un botón "Agregar transacción" en la página del panel -- Cree una nueva página con una plantilla HTML o use JavaScript para mostrar / ocultar el cuadro de diálogo HTML sin salir de la página del tablero (puede usar [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) para eso, o clases CSS) +- Cree una nueva página con una plantilla HTML o use JavaScript para mostrar / ocultar el cuadro de diálogo HTML sin salir de la página del tablero (puede usar [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) para eso, o clases CSS) - Implementar un formulario HTML para recibir datos de entrada. - Cree datos JSON a partir de los datos del formulario y envíelos a la API - Actualiza la página del tablero con los nuevos datos. diff --git a/7-bank-project/4-state-management/translations/assignment.hi.md b/7-bank-project/4-state-management/translations/assignment.hi.md index 7f0cc61f..1fff2d16 100644 --- a/7-bank-project/4-state-management/translations/assignment.hi.md +++ b/7-bank-project/4-state-management/translations/assignment.hi.md @@ -6,7 +6,7 @@ पिछले चार पाठों में आपने जो कुछ भी सीखा है, उसका उपयोग करके "लेनदेन जोड़ें" डियलॉग को लागू करें: - डैशबोर्ड पृष्ठ में "लेनदेन जोड़ें" बटन जोड़ें -- या तो HTML टेम्पलेट के साथ एक नया पृष्ठ बनाएँ, या डैशबोर्ड पृष्ठ को छोड़े बिना संवाद HTML दिखाने / छिपाने के लिए जावास्क्रिप्ट का उपयोग करें (आप उसके लिए, या CSS कक्षाओं के लिए [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) हुई संपत्ति का उपयोग कर सकते हैं) +- या तो HTML टेम्पलेट के साथ एक नया पृष्ठ बनाएँ, या डैशबोर्ड पृष्ठ को छोड़े बिना संवाद HTML दिखाने / छिपाने के लिए जावास्क्रिप्ट का उपयोग करें (आप उसके लिए, या CSS कक्षाओं के लिए [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) हुई संपत्ति का उपयोग कर सकते हैं) - सुनिश्चित करें कि आप [कीबोर्ड और स्क्रीन रीडर एक्सेसिबिलिटी](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) डियलॉग संभालते हैं - इनपुट डेटा प्राप्त करने के लिए एक HTML फॉर्म को लागू करें - फॉर्म डेटा से JSON डेटा बनाएं और इसे API पर भेजें diff --git a/7-bank-project/4-state-management/translations/assignment.it.md b/7-bank-project/4-state-management/translations/assignment.it.md index 0b665b7d..4c60ca1d 100644 --- a/7-bank-project/4-state-management/translations/assignment.it.md +++ b/7-bank-project/4-state-management/translations/assignment.it.md @@ -6,7 +6,7 @@ All'app bancaria manca ancora una caratteristica importante: la possibilità di Utilizzando tutto quanto appreso nelle quattro lezioni precedenti, implementare una finestra di dialogo "Aggiungi transazione": - Aggiungere un pulsante "Aggiungi transazione" nella pagina del cruscotto -- Creare una nuova pagina con un modello HTML o usare JavaScript per mostrare/nascondere l'HTML della finestra di dialogo senza lasciare la pagina del cruscotto (si può usare la proprietà [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) per quello o le classi CSS) +- Creare una nuova pagina con un modello HTML o usare JavaScript per mostrare/nascondere l'HTML della finestra di dialogo senza lasciare la pagina del cruscotto (si può usare la proprietà [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) per quello o le classi CSS) - Assicurarsi di gestire l' [accessibilità dalla tastiera e dal lettore di schermo](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) per la finestra di dialogo - Implementare un form HTML per ricevere i dati di input - Creare dati JSON dai dati del form e inviarli all'API diff --git a/7-bank-project/4-state-management/translations/assignment.ko.md b/7-bank-project/4-state-management/translations/assignment.ko.md index 0f58c39b..7450e9e0 100644 --- a/7-bank-project/4-state-management/translations/assignment.ko.md +++ b/7-bank-project/4-state-management/translations/assignment.ko.md @@ -5,7 +5,7 @@ 우리 은행 앱에는 여전히 새로운 거래를 입력 할 수 있는 한 가지 중요한 기능이 없습니다. 이전 네 가지 수업에서 배운 모든 것을 사용하여 "트랜잭션 추가" 대화 상자를 구현해봅시다. - 대시 보드 페이지에 "거래 추가" 버튼 추가 -- HTML 템플릿으로 새 페이지를 만들거나 JavaScript를 사용하여 대시 보드 페이지를 벗어나지 않고 대화 상자 HTML을 표시하거나 숨깁니다(해당 항목에 대해 [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) 속성 또는 CSS 클래스를 사용할 수 있음). +- HTML 템플릿으로 새 페이지를 만들거나 JavaScript를 사용하여 대시 보드 페이지를 벗어나지 않고 대화 상자 HTML을 표시하거나 숨깁니다(해당 항목에 대해 [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) 속성 또는 CSS 클래스를 사용할 수 있음). - 대화 상자에 대한 [키보드 및 화면 판독기 접근성](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/)을 처리해야합니다. - 입력 데이터 수신을 위한 HTML 양식 구현 - 양식 데이터에서 JSON 데이터를 만들어 API로 보냅니다. diff --git a/7-bank-project/4-state-management/translations/assignment.ms.md b/7-bank-project/4-state-management/translations/assignment.ms.md index 25594f78..180137be 100644 --- a/7-bank-project/4-state-management/translations/assignment.ms.md +++ b/7-bank-project/4-state-management/translations/assignment.ms.md @@ -6,7 +6,7 @@ Aplikasi bank kami masih belum mempunyai satu ciri penting: kemungkinan untuk me Menggunakan semua yang telah anda pelajari dalam empat pelajaran sebelumnya, laksanakan dialog "Tambah transaksi": - Tambahkan butang "Tambah transaksi" di halaman papan pemuka -- Buat halaman baru dengan templat HTML, atau gunakan JavaScript untuk menunjukkan / menyembunyikan HTML dialog tanpa meninggalkan halaman papan pemuka (anda boleh menggunakan [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) property for that, or CSS classes) untuk itu, atau kelas CSS) +- Buat halaman baru dengan templat HTML, atau gunakan JavaScript untuk menunjukkan / menyembunyikan HTML dialog tanpa meninggalkan halaman papan pemuka (anda boleh menggunakan [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) property for that, or CSS classes) untuk itu, atau kelas CSS) - Pastikan anda mengendalikan [kebolehcapaian pembaca papan kekunci dan skrin](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) untuk dialog - Terapkan borang HTML untuk menerima data input - Buat data JSON dari data formulir dan kirimkan ke API diff --git a/7-bank-project/4-state-management/translations/assignment.nl.md b/7-bank-project/4-state-management/translations/assignment.nl.md new file mode 100644 index 00000000..4d2b0f65 --- /dev/null +++ b/7-bank-project/4-state-management/translations/assignment.nl.md @@ -0,0 +1,25 @@ +# Implementeer het dialoogvenster "Transactie toevoegen" + +## Instructies + +Onze bank-app mist nog één belangrijk kenmerk: de mogelijkheid om nieuwe transacties in te voeren. +Gebruik alles wat u in de vier voorgaande lessen heeft geleerd en implementeer een dialoogvenster "Transactie toevoegen": + +- Voeg een knop "Transactie toevoegen" toe op de dashboardpagina +- Maak een nieuwe pagina met een HTML-sjabloon of gebruik JavaScript om de HTML-dialoog weer te geven/te verbergen zonder de dashboardpagina te verlaten (u kunt [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) eigenschap daarvoor gebruiken, of CSS-class) +- Zorg ervoor dat u [toetsenbord en schermlezer toegankelijkheid](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) afhandelt voor het dialoogvenster +- Implementeer een HTML-formulier om invoergegevens te ontvangen +- Maak JSON-gegevens van de formuliergegevens en stuur deze naar de API +- Werk de dashboardpagina bij met de nieuwe gegevens + +Kijk naar de [server API-specificaties](../api/README.md) om te zien welke API u moet aanroepen en wat het verwachte JSON-formaat is. + +Hier is een voorbeeldresultaat na het voltooien van de opdracht: + + + +## Rubriek + +| Criteria | Voorbeeldig | Voldoende | Moet worden verbeterd | +| -------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------| +| | Het toevoegen van een transactie wordt volledig geïmplementeerd volgens alle best practices uit de lessen. | Het toevoegen van een transactie is geïmplementeerd, maar volgt niet de best practices uit de lessen, of werkt slechts gedeeltelijk. | Het toevoegen van een transactie werkt helemaal niet. | diff --git a/7-bank-project/4-state-management/translations/assignment.zh-tw.md b/7-bank-project/4-state-management/translations/assignment.zh-tw.md new file mode 100644 index 00000000..6d58308b --- /dev/null +++ b/7-bank-project/4-state-management/translations/assignment.zh-tw.md @@ -0,0 +1,25 @@ +# 編寫"加入交易明細"視窗 + +## 簡介 + +我們的銀行應用程式還缺乏一項重要的功能:輸入新的交易明細。 +使用你在這四堂課中學到的知識,編寫"加入交易明細"視窗: + +- 在儀表板頁面新增"加入交易明細"按鈕 +- 加入新的 HTML 模板建立新頁面,或是在同一頁面中使用 JavaScript 顯示 HTML 窗格(可以使用 [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) 屬性,或是 CSS classes) +- 確保視窗能滿足[鍵盤與螢幕報讀器的相容性](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) +- 編寫 HTML 表單來接收輸入資料 +- 建立 JSON 表單資料並傳送到 API 上 +- 使用新資料更新到儀表板頁面上 + +看看[伺服器 API 規格](../../api/README.zh-tw.md)來查詢你需要呼叫的 API 和所需的 JSON 格式。 + +這邊有完成作業後的成果: + + + +## 學習評量 + +| 作業內容 | 優良 | 普通 | 待改進 | +| -------- | ------------------------------------ | -------------------------------------------------- | ---------------------- | +| | 利用課程內容完美的製作出交易明細功能 | 有製作出交易明細功能,但有缺少部分要點且功能不完全 | 新的交易明細功能不正常 | diff --git a/7-bank-project/api/translations/README.zh-tw.md b/7-bank-project/api/translations/README.zh-tw.md new file mode 100644 index 00000000..6dda5b4d --- /dev/null +++ b/7-bank-project/api/translations/README.zh-tw.md @@ -0,0 +1,33 @@ +# 銀行 API (Bank API) + +> 由 [Node.js](https://nodejs.org) 與 [Express](https://expressjs.com/) 建立而成。 + +這套 API 已經建好而不在本次課程的範疇內。 + +然而,如果你想學習如何建立 API,你可以追蹤這一系列的影片:https://aka.ms/NodeBeginner (影片 17 到 21 為這套 API)。 + +你也可以看看這套互動式教學: https://aka.ms/learn/express-api + +## 運行伺服器 + +確保你的 [Node.js](https://nodejs.org) 已經安裝完成。 + +1. Git clone 這個數據庫. +2. 在資料夾 `api` 中開啟終端機,執行 `npm install`。 +3. 執行 `npm start`。 + +伺服器應該要在連接埠 `5000` 上監聽訊息。 + +> 筆記:所有儲存的資料不是永久保存的,伺服器終止時會遺失所有資料。 + +## API 項目 + +路由 | 描述 +---------------------------------------------|------------------------------------ +GET /api/ | 取得伺服器資訊 +POST /api/accounts/ | 建立新的帳戶,範例: `{ user: 'Yohan', description: 'My budget', currency: 'EUR', balance: 100 }` +GET /api/accounts/:user | 取得特定帳戶的所有資料 +DELETE /api/accounts/:user | 移除特定帳戶 +POST /api/accounts/:user/transactions | 建立新的交易明細,範例: `{ date: '2020-07-23T18:25:43.511Z', object: 'Bought a book', amount: -20 }` +DELETE /api/accounts/:user/transactions/:id | 移除特定交易明細 + diff --git a/7-bank-project/translations/README.nl.md b/7-bank-project/translations/README.nl.md new file mode 100644 index 00000000..024091e7 --- /dev/null +++ b/7-bank-project/translations/README.nl.md @@ -0,0 +1,21 @@ +# :dollar: Bouw een bank + +In dit project leert u hoe u een fictieve bank bouwt. Deze lessen bevatten instructies voor het opmaken van een web-app en het aanbieden van routes, het bouwen van formulieren, het beheren van de staat en het ophalen van gegevens uit een API waaruit u de gegevens van de bank kunt ophalen. + +|  |  | +|--------------------------------|--------------------------------| + +## Lessen + +1. [HTML-sjablonen en routes in een webapp](../1-template-route/translations/README.nl.md) +2. [Bouw een aanmeldings- en registratieformulier](../2-forms/translations/README.nl.md) +3. [Methoden voor het ophalen en gebruiken van gegevens](../3-data/translations/README.nl.md) +4. [Concepten van staatsbeheer](../4-state-management/translations/README.nl.md) + +### Credits + +Deze lessen zijn geschreven met :hearts: door [Yohan Lasorsa](https://twitter.com/sinedied). + +Als u geïnteresseerd bent om te leren hoe u de [server API](../api/translations/README.nl.md) bouwt die in deze lessen wordt gebruikt, kunt u [deze reeks video's](https://aka.ms/NodeBeginner) volgen (in het bijzonder video's 17 t/m 21). + +U kunt ook een kijkje nemen op [deze interactieve Leer-tutorial](https://aka.ms/learn/express-api). \ No newline at end of file diff --git a/7-bank-project/translations/README.zh-tw.md b/7-bank-project/translations/README.zh-tw.md new file mode 100644 index 00000000..e3bf6f0b --- /dev/null +++ b/7-bank-project/translations/README.zh-tw.md @@ -0,0 +1,21 @@ +# :dollar: 建立銀行 + +在這個專案中,你會學習如何建立虛擬銀行。這些課程包含許多教程:設計網頁應用程式的格式、提供網頁路由、建立表單、管理狀態和利用 API 抓取銀行的資料。 + +|  |  | +|---------------------------------|-----------------------------------| + +## 課程 + +1. [HTML 模板與網頁路由](../1-template-route/translations/README.md) +2. [建立登入與註冊表單](../2-forms/translations/README.md) +3. [取得並使用資料](../3-data/translations/README.md) +4. [狀態控管的概念](../4-state-management/translations/README.md) + +### 參與人員 + +這些課程是由 [Yohan Lasorsa](https://twitter.com/sinedied) 用滿滿的 ♥️ 來編寫。 + +如果你有興趣建立本課程使用的[伺服器 API](../api/translations/README.zh-tw.md),你可以遵循[這一系列的影片](https://aka.ms/NodeBeginner),特別是影片 17 至 21。 + +你也可以造訪[這款互動式教學網站](https://aka.ms/learn/express-api)。 \ No newline at end of file diff --git a/README.md b/README.md index b5b1a06c..39ab2445 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Azure Cloud Advocates at Microsoft are pleased to offer a 12-week, 24-lesson cur **Hearty thanks to our authors Jen Looper, Chris Noring, Christopher Harrison, Jasmine Greenaway, Yohan Lasorsa, Floor Drees, and sketchnote artist Tomomi Imura!** -> **Teachers**, we have [included some suggestions](for-teachers.md) on how to use this curriculum. If you would like to create your own lessons, we have also included a [lesson template](lesson-template/README.md) +> **Teachers**, we have [included some suggestions](for-teachers.md) on how to use this curriculum. If you would like to create your own lessons, we have also included a [lesson template](lesson-template/README.md). We'd love your feedback [via this form](https://forms.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR2humCsRZhxNuI79cm6n0hRUQzRVVU9VVlU5UlFLWTRLWlkyQUxORTg5WS4u)! > **Students**, to use this curriculum on your own, fork the entire repo and complete the exercises on your own, starting with a pre-lecture quiz, then reading the lecture and completing the rest of the activities. Try to create the projects by comprehending the lessons rather than copying the solution code; however that code is available in the /solutions folders in each project-oriented lesson. Another idea would be to form a study group with friends and go through the content together. For further study, we recommend [Microsoft Learn](https://docs.microsoft.com/users/jenlooper-2911/collections/jg2gax8pzd6o81?WT.mc_id=academic-13441-cxa) and by watching the videos mentioned below. @@ -52,37 +52,34 @@ While we have purposefully avoided introducing JavaScript frameworks so as to co ## Lessons -| | Project Name | Concepts Taught | Learning Objectives | Linked Lesson | Written Lesson | Sketchnote | Assignment | Starting Quiz | Ending Quiz | Video | Author | -| :---: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :------------: | :--------: | :--------: | :-----------: | :---------: | :---: | :---------------------: | -| 01 | Getting Started | Introduction to Programming and Tools of the Trade | Learn the basic underpinnings behind most programming languages and about software that helps professional developers do their jobs | [Intro to Programming Languages and Tools of the Trade](/1-getting-started-lessons/1-intro-to-programming-languages/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Jasmine | -| 02 | Getting Started | Basics of GitHub, includes working with a team | How to use GitHub in your project, how to collaborate with others on a code base | [Intro to GitHub](/1-getting-started-lessons/2-github-basics/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Floor | -| 03 | Getting Started | Accessibility | Learn the basics of web accessibility | [Accessibility Fundamentals](/1-getting-started-lessons/3-accessibility/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Christopher | -| 04 | JS Basics | JavaScript Data Types | The basics of JavaScript data types | [Data Types](/2-js-basics/1-data-types/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Jasmine | -| 05 | JS Basics | Functions and Methods | Learn about functions and methods to manage an application's logic flow | [Functions and Methods](/2-js-basics/2-functions-methods/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Jasmine and Christopher | -| 06 | JS Basics | Making Decisions with JS | Learn how to create conditions in your code using decision-making methods | [Making Decisions](/2-js-basics/3-making-decisions/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Jasmine | -| 07 | JS Basics | Arrays and Loops | Work with data using arrays and loops in JavaScript | [Arrays and Loops](/2-js-basics/4-arrays-loops/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Jasmine | -| 08 | [Terrarium](/3-terrarium/solution/README.md) | HTML in Practice | Build the HTML to create an online terrarium, focusing on building a layout | [Introduction to HTML](/3-terrarium/1-intro-to-html/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Jen | -| 09 | [Terrarium](/3-terrarium/solution/README.md) | CSS in Practice | Build the CSS to style the online terrarium, focusing on the basics of CSS including making the page responsive | [Introduction to CSS](/3-terrarium/2-intro-to-css/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Jen | -| 10 | [Terrarium](/3-terrarium/solution) | JavaScript Closures, DOM manipulation | Build the JavaScript to make the terrarium function as a drag/drop interface, focusing on closures and DOM manipulation | [JavaScript Closures, DOM manipulation](/3-terrarium/3-intro-to-DOM-and-closures/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Jen | -| 11 | [Typing Game](/4-typing-game/solution) | Build a Typing Game | Learn how to use keyboard events to drive the logic of your JavaScript app | [Event-Driven Programming](/4-typing-game/typing-game/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | ✅ | Christopher | -| 12 | [Green Browser Extension](/5-browser-extension/solution) | Working with Browsers | Learn how browsers work, their history, and how to scaffold the first elements of a browser extension | [About Browsers](/5-browser-extension/1-about-browsers/README.md) | ✅ | ✅ | ✅ | ✅ | ✅ | 🛑 | Jen | -| 13 | [Green Browser Extension](/5-browser-extension/solution) | Building a form, calling an API and storing variables in local storage | Build the JavaScript elements of your browser extension to call an API using variables stored in local storage | [APIs, Forms, and Local Storage](/5-browser-extension/2-forms-browsers-local-storage/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | ✅ | Jen | -| 14 | [Green Browser Extension](/5-browser-extension/solution) | Background processes in the browser, web performance | Use the browser's background processes to manage the extension's icon; learn about web performance and some optimizations to make | [Background Tasks and Performance](/5-browser-extension/3-background-tasks-and-performance/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Jen | -| 15 | [Space Game](/6-space-game/solution) | More Advanced Game Development with JavaScript | Learn about Inheritance using both Classes and Composition and the Pub/Sub pattern, in preparation for building a game | [Introduction to Advanced Game Development](/6-space-game/1-introduction/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 16 | [Space Game](/6-space-game/solution) | Drawing to canvas | Learn about the Canvas API, used to draw elements to a screen | [Drawing to Canvas](/6-space-game/2-drawing-to-canvas/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 17 | [Space Game](/6-space-game/solution) | Moving elements around the screen | Discover how elements can gain motion using the cartesian coordinates and the Canvas API | [Moving Elements Around](/6-space-game/3-moving-elements-around/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 18 | [Space Game](/6-space-game/solution) | Collision detection | Make elements collide and react to each other using keypresses and provide a cooldown function to ensure performance of the game | [Collision Detection](/6-space-game/4-collision-detection/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 19 | [Space Game](/6-space-game/solution) | Keeping score | Perform math calculations based on the game's status and performance | [Keeping Score](/6-space-game/5-keeping-score/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 20 | [Space Game](/6-space-game/solution) | Ending and restarting the game | Learn about ending and restarting the game, including cleaning up assets and resetting variable values | [The Ending Condition](/6-space-game/6-end-condition/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | 🛑 | Chris | -| 21 | [Banking App](/7-bank-project/solution) | HTML Templates and Routes in a Web App | Learn how to create the scaffold of a multipage website's architecture using routing and HTML templates | [HTML Templates and Routes](/7-bank-project/1-template-route/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | ✅ | Yohan | -| 22 | [Banking App](/7-bank-project/solution) | Build a Login and Registration Form | Learn about building forms and handing validation routines | [Forms](/7-bank-project/2-forms/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | ✅ | Yohan | -| 23 | [Banking App](/7-bank-project/solution) | Methods of Fetching and Using Data | How data flows in and out of your app, how to fetch it, store it, and dispose of it | [Data](/7-bank-project/3-data/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | ✅ | Yohan | -| 24 | [Banking App](/7-bank-project/solution) | Concepts of State Management | Learn how your app retains state and how to manage it programmatically | [State Management](/7-bank-project/4-state-management/README.md) | ✅ | 🛑 | ✅ | ✅ | ✅ | | Yohan | +| | Project Name | Concepts Taught | Learning Objectives | Linked Lesson | Author | +| :---: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: | +| 01 | Getting Started | Introduction to Programming and Tools of the Trade | Learn the basic underpinnings behind most programming languages and about software that helps professional developers do their jobs | [Intro to Programming Languages and Tools of the Trade](/1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine | +| 02 | Getting Started | Basics of GitHub, includes working with a team | How to use GitHub in your project, how to collaborate with others on a code base | [Intro to GitHub](/1-getting-started-lessons/2-github-basics/README.md) | Floor | +| 03 | Getting Started | Accessibility | Learn the basics of web accessibility | [Accessibility Fundamentals](/1-getting-started-lessons/3-accessibility/README.md) | Christopher | +| 04 | JS Basics | JavaScript Data Types | The basics of JavaScript data types | [Data Types](/2-js-basics/1-data-types/README.md) | Jasmine | +| 05 | JS Basics | Functions and Methods | Learn about functions and methods to manage an application's logic flow | [Functions and Methods](/2-js-basics/2-functions-methods/README.md) | Jasmine and Christopher | +| 06 | JS Basics | Making Decisions with JS | Learn how to create conditions in your code using decision-making methods | [Making Decisions](/2-js-basics/3-making-decisions/README.md) | Jasmine | +| 07 | JS Basics | Arrays and Loops | Work with data using arrays and loops in JavaScript | [Arrays and Loops](/2-js-basics/4-arrays-loops/README.md) | Jasmine | +| 08 | [Terrarium](/3-terrarium/solution/README.md) | HTML in Practice | Build the HTML to create an online terrarium, focusing on building a layout | [Introduction to HTML](/3-terrarium/1-intro-to-html/README.md) | Jen | +| 09 | [Terrarium](/3-terrarium/solution/README.md) | CSS in Practice | Build the CSS to style the online terrarium, focusing on the basics of CSS including making the page responsive | [Introduction to CSS](/3-terrarium/2-intro-to-css/README.md) | Jen | +| 10 | [Terrarium](/3-terrarium/solution) | JavaScript Closures, DOM manipulation | Build the JavaScript to make the terrarium function as a drag/drop interface, focusing on closures and DOM manipulation | [JavaScript Closures, DOM manipulation](/3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen | +| 11 | [Typing Game](/4-typing-game/solution) | Build a Typing Game | Learn how to use keyboard events to drive the logic of your JavaScript app | [Event-Driven Programming](/4-typing-game/typing-game/README.md) | Christopher | +| 12 | [Green Browser Extension](/5-browser-extension/solution) | Working with Browsers | Learn how browsers work, their history, and how to scaffold the first elements of a browser extension | [About Browsers](/5-browser-extension/1-about-browsers/README.md) | Jen | +| 13 | [Green Browser Extension](/5-browser-extension/solution) | Building a form, calling an API and storing variables in local storage | Build the JavaScript elements of your browser extension to call an API using variables stored in local storage | [APIs, Forms, and Local Storage](/5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen | +| 14 | [Green Browser Extension](/5-browser-extension/solution) | Background processes in the browser, web performance | Use the browser's background processes to manage the extension's icon; learn about web performance and some optimizations to make | [Background Tasks and Performance](/5-browser-extension/3-background-tasks-and-performance/README.md) | Jen | +| 15 | [Space Game](/6-space-game/solution) | More Advanced Game Development with JavaScript | Learn about Inheritance using both Classes and Composition and the Pub/Sub pattern, in preparation for building a game | [Introduction to Advanced Game Development](/6-space-game/1-introduction/README.md) | Chris | +| 16 | [Space Game](/6-space-game/solution) | Drawing to canvas | Learn about the Canvas API, used to draw elements to a screen | [Drawing to Canvas](/6-space-game/2-drawing-to-canvas/README.md) | Chris | +| 17 | [Space Game](/6-space-game/solution) | Moving elements around the screen | Discover how elements can gain motion using the cartesian coordinates and the Canvas API | [Moving Elements Around](/6-space-game/3-moving-elements-around/README.md) | Chris | +| 18 | [Space Game](/6-space-game/solution) | Collision detection | Make elements collide and react to each other using keypresses and provide a cooldown function to ensure performance of the game | [Collision Detection](/6-space-game/4-collision-detection/README.md) | Chris | +| 19 | [Space Game](/6-space-game/solution) | Keeping score | Perform math calculations based on the game's status and performance | [Keeping Score](/6-space-game/5-keeping-score/README.md) | Chris | +| 20 | [Space Game](/6-space-game/solution) | Ending and restarting the game | Learn about ending and restarting the game, including cleaning up assets and resetting variable values | [The Ending Condition](/6-space-game/6-end-condition/README.md) | Chris | +| 21 | [Banking App](/7-bank-project/solution) | HTML Templates and Routes in a Web App | Learn how to create the scaffold of a multipage website's architecture using routing and HTML templates | [HTML Templates and Routes](/7-bank-project/1-template-route/README.md) | Yohan | +| 22 | [Banking App](/7-bank-project/solution) | Build a Login and Registration Form | Learn about building forms and handing validation routines | [Forms](/7-bank-project/2-forms/README.md) | Yohan | +| 23 | [Banking App](/7-bank-project/solution) | Methods of Fetching and Using Data | How data flows in and out of your app, how to fetch it, store it, and dispose of it | [Data](/7-bank-project/3-data/README.md) | Yohan | +| 24 | [Banking App](/7-bank-project/solution) | Concepts of State Management | Learn how your app retains state and how to manage it programmatically | [State Management](/7-bank-project/4-state-management/README.md) | Yohan | ## Offline access You can run this documentation offline by using [Docsify](https://docsify.js.org/#/). Fork this repo, [install Docsify](https://docsify.js.org/#/quickstart) on your local machine, and then in the root folder of this repo, type `docsify serve`. The website will be served on port 3000 on your localhost: `localhost:3000`. -<a href="https://trackgit.com"> -<img src="https://us-central1-trackgit-analytics.cloudfunctions.net/token/ping/kkcxjd6o25veljfkpm9k" alt="trackgit-views" /> -</a> diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..f7b89984 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ +<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK --> + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). + +<!-- END MICROSOFT SECURITY.MD BLOCK --> \ No newline at end of file diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 00000000..89842c18 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,11 @@ +# Support + +## How to file issues and get help + +This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue. + +For help and questions about using this project, please refer to [our contributing guidelines](CONTRIBUTING.md). + +## Microsoft Support Policy + +Support for this project is limited to the resources listed above. diff --git a/quiz-app/src/App.vue b/quiz-app/src/App.vue index 76e53410..4f4e629e 100644 --- a/quiz-app/src/App.vue +++ b/quiz-app/src/App.vue @@ -6,12 +6,16 @@ <select v-model="locale"> <option>en</option> <option>es</option> - <option>ko</option> - <option>id</option> + <option>gr</option> <option>hi</option> + <option>id</option> <option>it</option> - <option>gr</option> + <option>ko</option> <option>ms</option> + <option>nl</option> + <option>zh_cn</option> + <option>zh_tw</option> + </select> </nav> <div id="app"> diff --git a/quiz-app/src/assets/translations/en.json b/quiz-app/src/assets/translations/en.json index d45f25ba..5ad362d5 100644 --- a/quiz-app/src/assets/translations/en.json +++ b/quiz-app/src/assets/translations/en.json @@ -2343,7 +2343,7 @@ }, { "id": 46, - "title": "Lesson 23 - Bank Project Methods of Fetching and Using Data: Post-Lecture Quiz", + "title": "Lesson 23 - Bank Project - Methods of Fetching and Using Data: Post-Lecture Quiz", "quiz": [ { "questionText": "In a Single-page application, the HTML is loaded once and never updated", diff --git a/quiz-app/src/assets/translations/index.js b/quiz-app/src/assets/translations/index.js index c95be853..ec072f61 100644 --- a/quiz-app/src/assets/translations/index.js +++ b/quiz-app/src/assets/translations/index.js @@ -8,6 +8,10 @@ import ja from './ja.json'; import gr from './gr.json'; import ms from './ms.json'; import es from './es.json'; +import nl from './nl.json'; +import zh_cn from './zh_cn.json'; +import zh_tw from './zh_tw.json'; + //export const defaultLocale = 'en'; @@ -21,6 +25,10 @@ const messages = { gr: gr[0], ms: ms[0], es: es[0], + nl: nl[0], + zh_cn: zh_cn[0], + zh_tw: zh_tw[0], + }; export default messages; diff --git a/quiz-app/src/assets/translations/nl.json b/quiz-app/src/assets/translations/nl.json new file mode 100644 index 00000000..a3a80756 --- /dev/null +++ b/quiz-app/src/assets/translations/nl.json @@ -0,0 +1,2509 @@ +[ + { + "title": "Webontwikkeling voor Beginners: Quizzen", + "complete": "Gefeliciteerd, u hebt de quiz voltooid!", + "error": "Sorry probeer het opnieuw", + "quizzes": [ + { + "id": 1, + "title": "Les 1 - Inleiding tot Programmeertalen: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Een programma kan worden gemaakt zonder dat de maker zelf code hoeft te schrijven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Talen op laag niveau zijn een populaire keuze voor", + "answerOptions": [ + { + "answerText": "Websites", + "isCorrect": "false" + }, + { + "answerText": "Hardware", + "isCorrect": "true" + }, + { + "answerText": "Software voor videogames", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Welke van deze tools zou zich waarschijnlijk in de omgeving van een webontwikkelaar bevinden?", + "answerOptions": [ + { + "answerText": "Hardware, zoals een Raspberry Pi", + "isCorrect": "false" + }, + { + "answerText": "Browser DevTools", + "isCorrect": "true" + }, + { + "answerText": "Besturingssysteem documentatie", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 2, + "title": "Les 1 - Inleiding tot Programmeertalen: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Welke taal zou u waarschijnlijk gebruiken om een website te maken?", + "answerOptions": [ + { + "answerText": "Machine Code", + "isCorrect": "false" + }, + { + "answerText": "JavaScript", + "isCorrect": "true" + }, + { + "answerText": "Bash", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Ontwikkelomgevingen zijn uniek voor elke ontwikkelaar", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wat zal een ontwikkelaar doen om foutcodes te herstellen?", + "answerOptions": [ + { + "answerText": "Syntaxis accentuering", + "isCorrect": "false" + }, + { + "answerText": "Debuggen", + "isCorrect": "true" + }, + { + "answerText": "Code-opmaak", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 3, + "title": "Les 2 - Inleiding tot GitHub: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Hoe maakt u een Git-repo aan?", + "answerOptions": [ + { + "answerText": "git create", + "isCorrect": "false" + }, + { + "answerText": "git start", + "isCorrect": "false" + }, + { + "answerText": "git init", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat doet git add?", + "answerOptions": [ + { + "answerText": "Commit uw code", + "isCorrect": "false" + }, + { + "answerText": "Voegt uw bestanden toe aan een verzamelgebied voor tracking", + "isCorrect": "true" + }, + { + "answerText": "Voegt uw bestanden toe aan GitHub", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Hoe controleert u of git op uw computer is geïnstalleerd?", + "answerOptions": [ + { + "answerText": "typ git --version", + "isCorrect": "true" + }, + { + "answerText": "typ git --installed", + "isCorrect": "false" + }, + { + "answerText": "typ git --init", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 4, + "title": "Les 2 - Inleiding tot GitHub: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Een plek om de verschillen die op een tak zijn geïntroduceerd te vergelijken en te bespreken met recensies, opmerkingen, geïntegreerde tests en meer is:", + "answerOptions": [ + { + "answerText": "GitHub", + "isCorrect": "false" + }, + { + "answerText": "Een Pull Request", + "isCorrect": "true" + }, + { + "answerText": "Een feature tak", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Hoe zou u alle commits van een afgelegen (remote) tak krijgen?", + "answerOptions": [ + { + "answerText": "git fetch", + "isCorrect": "false" + }, + { + "answerText": "git pull", + "isCorrect": "true" + }, + { + "answerText": "git commits -r", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Hoe stapt u over naar een tak?", + "answerOptions": [ + { + "answerText": "git switch [taknaam]", + "isCorrect": "false" + }, + { + "answerText": "git checkout [taknaam]", + "isCorrect": "true" + }, + { + "answerText": "git load [taknaam]", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 5, + "title": "Les 3 - Toegankelijke Webpagina's Maken: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Een toegankelijke website kan ook in welke browser worden gecontroleerdl", + "answerOptions": [ + { + "answerText": "Lighthouse", + "isCorrect": "true" + }, + { + "answerText": "Deckhouse", + "isCorrect": "false" + }, + { + "answerText": "Cleanhouse", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U hebt een fysieke schermlezer nodig om de toegankelijkheid voor slechtzienden te testen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Toegankelijkheid is alleen belangrijk op websites van de overheid", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 6, + "title": "Les 3 - Toegankelijke Webpagina's Maken: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Lighthouse controleert alleen op toegankelijkheidsproblemen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Kleurveilige paletten helpen mensen met", + "answerOptions": [ + { + "answerText": "kleurenblindheid", + "isCorrect": "false" + }, + { + "answerText": "Gezichtsverlies", + "isCorrect": "false" + }, + { + "answerText": "beide bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Beschrijvende links zijn essentieel voor toegankelijke websites", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 7, + "title": "Les 4 - JavaScript Basics - Gegevenstypen: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Booleans zijn een gegevenstype dat u kunt gebruiken om de lengte van een string te testen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het volgende is een bewerking die u op een string kunt uitvoeren", + "answerOptions": [ + { + "answerText": "aaneenschakeling", + "isCorrect": "true" + }, + { + "answerText": "toevoeging", + "isCorrect": "false" + }, + { + "answerText": "splitsing", + "isCorrect": "false" + } + ] + }, + { + "questionText": "== en === zijn uitwisselbaar", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 8, + "title": "Les 4 - JavaScript Basics - Gegevenstypen: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Constanten zijn hetzelfde als let en var om variabelen te declareren, behalve", + "answerOptions": [ + { + "answerText": "Constanten moeten worden geïnitialiseerd", + "isCorrect": "true" + }, + { + "answerText": "Constanten kunnen worden gewijzigd", + "isCorrect": "false" + }, + { + "answerText": "Constanten kunnen opnieuw worden toegewezen", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Getallen en ____ zijn JavaScript-primitieven die numerieke gegevens verwerken", + "answerOptions": [ + { + "answerText": "bigint", + "isCorrect": "true" + }, + { + "answerText": "boolean", + "isCorrect": "false" + }, + { + "answerText": "star", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Strings kunnen tussen enkele en dubbele aanhalingstekens staan", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 9, + "title": "Les 5 - JavaScript Basics - Methoden en Functies: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Wat is een argument?", + "answerOptions": [ + { + "answerText": "Het is iets dat u aangeeft in de functiedefinitie", + "isCorrect": "false" + }, + { + "answerText": "Het is iets waar u tijdens het aanroepen in een functie overgaat", + "isCorrect": "true" + }, + { + "answerText": "Het is iets dat u heeft met mensen die u kent", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Een functie moet iets teruggeven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U kunt een functie van alles een naam geven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + }, + { + "answerText": "waar, maar het moet een beschrijvende naam zijn", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 10, + "title": "Les 5 - JavaScript Basics - Methoden en Functies: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Er moeten argumenten worden opgegeven voor alle parameters in een functie", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat doet een standaardwaarde?", + "answerOptions": [ + { + "answerText": "Stelt een juiste waarde in", + "isCorrect": "false" + }, + { + "answerText": "Geeft een startwaarde voor een parameter zodat uw code zich nog steeds gedraagt als u er een argument voor weglaat", + "isCorrect": "true" + }, + { + "answerText": "Heeft geen nut", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Een fat arrow-functie stelt u in staat om", + "answerOptions": [ + { + "answerText": "Zware functies te creëren", + "isCorrect": "false" + }, + { + "answerText": "Het functietrefwoord weg te laten", + "isCorrect": "true" + }, + { + "answerText": "Een anonieme functie creëren", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 11, + "title": "Les 6 - Basisprincipes van JavaScript - Beslissingen Nemen: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "De volgende operator == heet", + "answerOptions": [ + { + "answerText": "Gelijkheid", + "isCorrect": "true" + }, + { + "answerText": "Strikte gelijkheid", + "isCorrect": "false" + }, + { + "answerText": "Toewijzing", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Een vergelijking in JavaScript geeft welk type terug?", + "answerOptions": [ + { + "answerText": "boolean", + "isCorrect": "true" + }, + { + "answerText": "null", + "isCorrect": "false" + }, + { + "answerText": "string", + "isCorrect": "false" + } + ] + }, + { + "questionText": "De ! symbool in JavaScript betekent:", + "answerOptions": [ + { + "answerText": "Logisch niet", + "isCorrect": "true" + }, + { + "answerText": "Belangrijk", + "isCorrect": "false" + }, + { + "answerText": "Is gelijk aan", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 12, + "title": "Les 6 - Basisprincipes van JavaScript - Beslissingen Nemen: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Wat zou de volgende code retourneren:'1' == 1", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + }, + { + "answerText": "null", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wat zou de volgende code retourneren: '1' === 1", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + }, + { + "answerText": "null", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Kies de juiste operator om 'or' logica uit te drukken", + "answerOptions": [ + { + "answerText": "a | b", + "isCorrect": "false" + }, + { + "answerText": "a || b", + "isCorrect": "true" + }, + { + "answerText": "a or b", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 13, + "title": "Les 7 - JavaScript Basics - Arrays en Loops: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Om naar een specifiek item in een array te verwijzen, gebruikt u een", + "answerOptions": [ + { + "answerText": "vierkant haakje []", + "isCorrect": "false" + }, + { + "answerText": "index", + "isCorrect": "true" + }, + { + "answerText": "accolades {}", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Hoe krijgt u het aantal items in een array?", + "answerOptions": [ + { + "answerText": "De 'len(array)' methode", + "isCorrect": "false" + }, + { + "answerText": "De eigenschapsgrootte op de array", + "isCorrect": "false" + }, + { + "answerText": "De eigenschap length op de array", + "isCorrect": "true" + } + ] + }, + { + "questionText": "In JavaScript beginnen indexen bij", + "answerOptions": [ + { + "answerText": "0", + "isCorrect": "true" + }, + { + "answerText": "1", + "isCorrect": "false" + }, + { + "answerText": "2", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 14, + "title": "Les 7 - JavaScript Basics - Arrays en Loops: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Welk deel van een for-loop zou u moeten aanpassen om de iteratie met 5 te verhogen?", + "answerOptions": [ + { + "answerText": "voorwaarde", + "isCorrect": "true" + }, + { + "answerText": "teller", + "isCorrect": "false" + }, + { + "answerText": "iteratie-uitdrukking", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wat is het verschil tussen een while en een for-loop", + "answerOptions": [ + { + "answerText": "Een for-loop heeft een teller en iteratie-uitdrukking, terwijl while alleen een voorwaarde heeft", + "isCorrect": "true" + }, + { + "answerText": "Een while heeft een teller en iteratie-uitdrukking waar for-loop alleen een voorwaarde heeft", + "isCorrect": "false" + }, + { + "answerText": "Ze zijn hetzelfde, alleen een alias voor elkaar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Gezien de code voor (let i=1; i < 5; i++), hoeveel iteraties zal het uitvoeren?", + "answerOptions": [ + { + "answerText": "5", + "isCorrect": "false" + }, + { + "answerText": "4", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 15, + "title": "Les 8 - Terrariumproject - Inleiding tot HTML: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "HTML staat voor 'HyperText Mockup Language'", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Alle HTML-tags hebben zowel openings- als sluitingstags nodig", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het gebruik van semantische opmaak is het belangrijkst voor", + "answerOptions": [ + { + "answerText": "leesbaarheid van de code", + "isCorrect": "false" + }, + { + "answerText": "schermlezers", + "isCorrect": "true" + }, + { + "answerText": "onderhoud", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 16, + "title": "Les 8 - Terrariumproject - Inleiding tot HTML: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Spans en Divs zijn uitwisselbaar", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "De kop van een HTML-document kan het volgende bevatten:", + "answerOptions": [ + { + "answerText": "de title-tag", + "isCorrect": "false" + }, + { + "answerText": "metadata", + "isCorrect": "false" + }, + { + "answerText": "alle bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U kunt geen verouderde tags gebruiken in uw opmaak", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar, maar ze zijn om een goede reden verouderd", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 17, + "title": "Les 9 - Terrariumproject - Inleiding tot CSS: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "HTML-elementen moeten een class of een id hebben om te worden opgemaakt", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS staat voor 'Complete Style Sheets'", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS kan worden gebruikt om animaties te maken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 18, + "title": "Les 9 - Terrariumproject - Inleiding tot CSS: Quiz na de Lezing", + "quiz": [ + { + "questionText": "U kunt CSS rechtstreeks in het hoofdgedeelte van uw HTML-bestand schrijven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Het is altijd nodig om CSS in uw app op te nemen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar, maar als u wilt dat het er goed uitziet, heeft u waarschijnlijk CSS nodig", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Welke browsertool kan worden gebruikt om CSS te inspecteren?", + "answerOptions": [ + { + "answerText": "Elements", + "isCorrect": "false" + }, + { + "answerText": "Styles", + "isCorrect": "true" + }, + { + "answerText": "Network", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 19, + "title": "Les 10 - Terrariumproject - DOM-Manipulatie en een afsluiting: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "De DOM staat voor 'Document Object Management'", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "De DOM kan worden gezien als een boom", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Met behulp van de web-API kunt u de DOM manipuleren", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 20, + "title": "Les 10 - Terrariumproject - DOM-Manipulatie en een Afsluiting: Quiz na de Lezing", + "quiz": [ + { + "questionText": "De DOM is een model om een document op internet weer te geven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Gebruik JavaScript-sluitingen om het volgende te doen:", + "answerOptions": [ + { + "answerText": "schrijf functies binnen functies", + "isCorrect": "true" + }, + { + "answerText": "omsluit de DOM", + "isCorrect": "false" + }, + { + "answerText": "sluit scriptblokken", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Vul de blanco in: Sluitingen zijn handig wanneer een of meer functies toegang moeten hebben tot de ... van een externe functie", + "answerOptions": [ + { + "answerText": "arrays", + "isCorrect": "false" + }, + { + "answerText": "reikwijdte", + "isCorrect": "true" + }, + { + "answerText": "functies", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 21, + "title": "Les 11 - Typespel: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Gebeurtenisgestuurde programmering is wanneer een gebruiker", + "answerOptions": [ + { + "answerText": "op een knop klikt", + "isCorrect": "false" + }, + { + "answerText": "klikt op een knop", + "isCorrect": "false" + }, + { + "answerText": "interageert met de pagina", + "isCorrect": "false" + }, + { + "answerText": "elk van de bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Bij procedureel programmeren worden functies ... aangeroepen", + "answerOptions": [ + { + "answerText": "elk moment", + "isCorrect": "false" + }, + { + "answerText": "in een specifieke volgorde", + "isCorrect": "true" + }, + { + "answerText": "van links naar rechts", + "isCorrect": "false" + } + ] + }, + { + "questionText": "De universele methode die in de DOM wordt weergegeven voor het registreren van gebeurtenishandlers, heet", + "answerOptions": [ + { + "answerText": "addEventListener", + "isCorrect": "true" + }, + { + "answerText": "addListener", + "isCorrect": "false" + }, + { + "answerText": "addEvent", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 22, + "title": "Les 11 - Typespel: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Bijna alles wat een gebruiker op een pagina doet, roept een gebeurtenis op", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Veel voorkomende gebeurtenissen zijn onder meer", + "answerOptions": [ + { + "answerText": "click_event", + "isCorrect": "false" + }, + { + "answerText": "select_event", + "isCorrect": "false" + }, + { + "answerText": "input_event", + "isCorrect": "false" + }, + { + "answerText": "all of these", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U kunt anonieme functies gebruiken om gebeurtenishandlers te maken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 23, + "title": "Les 12 - Browser-Extensieproject - Alles over Browsers: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "U kunt browserextensies krijgen van", + "answerOptions": [ + { + "answerText": "WalMart", + "isCorrect": "false" + }, + { + "answerText": "De extensie store van de browser", + "isCorrect": "true" + }, + { + "answerText": "De App Store", + "isCorrect": "false" + } + ] + }, + { + "questionText": "NPM staat voor", + "answerOptions": [ + { + "answerText": "Node Package Manager", + "isCorrect": "true" + }, + { + "answerText": "Netscape Primary Mix", + "isCorrect": "false" + }, + { + "answerText": "Natural Processing Manager", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Uw browser kan webpagina's zowel veilig als onveilig weergeven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 24, + "title": "Les 12 - Browser-Extensieproject - Alles over Browsers: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Het World Wide Web is uitgevonden door", + "answerOptions": [ + { + "answerText": "Tom Barnard-Loft", + "isCorrect": "false" + }, + { + "answerText": "Tim Berners-Lee", + "isCorrect": "true" + }, + { + "answerText": "Trish Berth-Pool", + "isCorrect": "false" + } + ] + }, + { + "questionText": "De eerste browser heette", + "answerOptions": [ + { + "answerText": "WorldWideWeb", + "isCorrect": "true" + }, + { + "answerText": "Mozilla", + "isCorrect": "false" + }, + { + "answerText": "Netscape", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Browsers kunnen de browsegeschiedenis van een gebruiker opslaan", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 25, + "title": "Les 13 - Browser Extensie-project - Roep een API aan, gebruik Local Storage: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "APIs staan voor", + "answerOptions": [ + { + "answerText": "Application Programming Interfaces", + "isCorrect": "true" + }, + { + "answerText": "A Programming Inference", + "isCorrect": "false" + }, + { + "answerText": "Anti Proven Intentions", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Gebruik een API om te communiceren met", + "answerOptions": [ + { + "answerText": "Een andere web-verbonden asset", + "isCorrect": "false" + }, + { + "answerText": "Een database", + "isCorrect": "false" + }, + { + "answerText": "Een van de bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Iedereen kan een API maken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 26, + "title": "Les 13 - Browser Extensie-project - Roep een API aan, gebruik Local Storage: Quiz na de Lezingz", + "quiz": [ + { + "questionText": "LocalStorage wordt elke keer dat u het browservenster sluit gewist", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het hoofdbrowservenster regelt de LocalStorage van een browserextensie", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "REST in een API-context staat voor", + "answerOptions": [ + { + "answerText": "Representational State Transfer", + "isCorrect": "true" + }, + { + "answerText": "Returning State Tasks", + "isCorrect": "false" + }, + { + "answerText": "Rendering State To Browser", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 27, + "title": "Les 14 - Browser Extensie-project - Leer over Achtergrondtaken en Prestaties: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Test de prestaties van uw app", + "answerOptions": [ + { + "answerText": "Met behulp van de hulpprogramma's van de browser", + "isCorrect": "true" + }, + { + "answerText": "Met behulp van een apart softwarepakket", + "isCorrect": "false" + }, + { + "answerText": "Handmatig", + "isCorrect": "false" + } + ] + }, + { + "questionText": "De 'prestatie' van een website is een analyse van", + "answerOptions": [ + { + "answerText": "Hoe snel het laadt", + "isCorrect": "false" + }, + { + "answerText": "Hoe snel de code erop werkt", + "isCorrect": "false" + }, + { + "answerText": "Beide bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Over het algemeen is het 'gewicht' van webpagina's de afgelopen jaren", + "answerOptions": [ + { + "answerText": "lichter geworden", + "isCorrect": "false" + }, + { + "answerText": "zwaarder geworden", + "isCorrect": "true" + }, + { + "answerText": "het zelfde gebleven", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 28, + "title": "Les 14 - Browser-Extensieproject - Leer over Achtergrondtaken en Prestaties: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Om een beter beeld te krijgen van de prestaties van uw site, moet u het cachegeheugen wissen en opnieuw laden in de profiler", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Browserextensies zijn inherent performant", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Analyseer het volgende voor knelpunten in de prestatiess", + "answerOptions": [ + { + "answerText": "DOM-doorlopen", + "isCorrect": "false" + }, + { + "answerText": "JavaScript-optimalisaties", + "isCorrect": "false" + }, + { + "answerText": "Vermogensbeheer", + "isCorrect": "false" + }, + { + "answerText": "Alle bovenstaande", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 29, + "title": "Les 15 - Ruimtespel - Inleiding: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "JavaScript is een onpopulaire taal voor het bouwen van games", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Pub/Sub is een voorkeurspatroon voor het beheren van de activa en stroom van de game", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Overerving van objecten kan worden afgehandeld door class of compositie te gebruiken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 30, + "title": "Les 15 - Ruimtespel - Inleiding: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Class zijn afhankelijk van overerving om gedrag toe te schrijven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Compositie is het geprefereerde ontwerppatroon voor game-objecten", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Pub/Sub staat voor:", + "answerOptions": [ + { + "answerText": "Publish/Subscribe", + "isCorrect": "true" + }, + { + "answerText": "Print/Staple", + "isCorrect": "false" + }, + { + "answerText": "Publish/Sanitize", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 31, + "title": "Les 16 - Ruimtespel - Teken Held en Monsters op Canvas: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Het Canvas-element is wat u gebruikt om op een scherm te tekenen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "U kunt alleen eenvoudige geometrische vormen tekenen met de Canvas API", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het punt 0,0 staat linksonder", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 32, + "title": "Les 16 - Ruimtespel - Teken Held en Monsters op Canvas: Quiz na de Lezingz", + "quiz": [ + { + "questionText": "U kunt tekenbewerkingen rechtstreeks op het canvas uitvoeren", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U luistert naar de onload-gebeurtenis om te weten wanneer een afbeelding asynchroon is geladen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "U tekent afbeeldingen op een scherm met een bewerking genaamd:", + "answerOptions": [ + { + "answerText": "paintImage()", + "isCorrect": "false" + }, + { + "answerText": "drawImage()", + "isCorrect": "true" + }, + { + "answerText": "draw()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 33, + "title": "Les 17 - Ruimtespel - Beweging Toevoegen: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Elk object op het scherm kan toetsenbordgebeurtenissen ontvangen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "U kunt dezelfde methode gebruiken om naar toetsgebeurtenissen en muisgebeurtenissen te luisteren", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Welke functie gebruikt u om dingen met regelmatige tussenpozen te laten gebeuren?", + "answerOptions": [ + { + "answerText": "setInterval()", + "isCorrect": "true" + }, + { + "answerText": "setTimeout()", + "isCorrect": "false" + }, + { + "answerText": "sleep()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 34, + "title": "Les 17 - Ruimtespel - Beweging Toevoegen: Quiz na de Lezing", + "quiz": [ + { + "questionText": "U moet het scherm altijd opnieuw tekenen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat is een game-loop?", + "answerOptions": [ + { + "answerText": "Een functie die ervoor zorgt dat het spel herstart kan worden", + "isCorrect": "false" + }, + { + "answerText": "Een functie die bepaalt hoe snel het spel moet draaien", + "isCorrect": "false" + }, + { + "answerText": "Een functie die met regelmatige tussenpozen wordt aangeroepen en tekent wat de gebruiker zou moeten zien", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Een goede reden om het scherm opnieuw te tekenen is", + "answerOptions": [ + { + "answerText": "Er heeft een gebruikersinteractie plaatsgevonden", + "isCorrect": "false" + }, + { + "answerText": "Er is iets verplaatst", + "isCorrect": "true" + }, + { + "answerText": "Er is tijd voorbij gegaan", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 35, + "title": "Les 18 - Ruimtespel - Een laser Toevoegen en Botsingen Detecteren: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Aanrijdingsdetectie is hoe we detecteren of twee dingen zijn gebotst", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Hoe kunnen we een item van het scherm verwijderen?", + "answerOptions": [ + { + "answerText": "Bel de vuilnisman", + "isCorrect": "false" + }, + { + "answerText": "Markeer het als dood, schilder alleen geen dode objecten de volgende keer dat we het scherm tekenen", + "isCorrect": "true" + }, + { + "answerText": "Plaats het item op een negatieve coördinaat", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Een goede manier om het afvuren van een laser in JavaScript te simuleren is:", + "answerOptions": [ + { + "answerText": "een visueel element laten reageren op een toetsgebeurtenis", + "isCorrect": "true" + }, + { + "answerText": "geanimeerde gifs maken", + "isCorrect": "false" + }, + { + "answerText": "vijanden met tussenpozen laten opblazen", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 36, + "title": "Les 18 - Ruimtespel - Een Laser Toevoegen en Botsingen Detecteren: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Bij botsingsdetectie vergelijkt u twee", + "answerOptions": [ + { + "answerText": "cirkels en of ze elkaar snijden", + "isCorrect": "false" + }, + { + "answerText": "rechthoeken en of ze elkaar snijden", + "isCorrect": "true" + }, + { + "answerText": "afstanden tussen twee punten", + "isCorrect": "false" + } + ] + }, + { + "questionText": "De reden voor het implementeren van een afkoeleffect is omdat", + "answerOptions": [ + { + "answerText": "Het spel moeilijker wordt omdat u niet herhaaldelijk een laser kunt afvuren om vijanden te vernietigen", + "isCorrect": "false" + }, + { + "answerText": "JavaScript slechts een bepaald aantal gebeurtenissen per tijdseenheid kan produceren, dus u moet ze beperken", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Constanten zijn identificeerbaar in code omdat", + "answerOptions": [ + { + "answerText": "ze in hoofdletters zijn geschreven", + "isCorrect": "true" + }, + { + "answerText": "ze specifieke namen hebben", + "isCorrect": "false" + }, + { + "answerText": "ze zo in een kebab-doosje zijn geschreven", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 37, + "title": "Les 19 - Ruimtespel - Scoren en Levens: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Hoe tekent u tekst op een scherm met het Canvas-element?", + "answerOptions": [ + { + "answerText": "Plaats tekst in een div- of span-element", + "isCorrect": "false" + }, + { + "answerText": "Roep drawText() aan op het Canvas-element", + "isCorrect": "false" + }, + { + "answerText": "Roep fillText() aan voor het contextobject", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Waarom heeft u het concept van 'levens' in een game?", + "answerOptions": [ + { + "answerText": "Om te laten zien hoeveel schade u kunt oplopen", + "isCorrect": "false" + }, + { + "answerText": "Zodat het spel niet meteen eindigt, maar u n aantal kansen hebt voordat het spel afgelopen is", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Voeg kleur toe aan tekst op Canvas met", + "answerOptions": [ + { + "answerText": "fillColor", + "isCorrect": "false" + }, + { + "answerText": "fillStyle", + "isCorrect": "true" + }, + { + "answerText": "textAlign", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 38, + "title": "Les 19 - Ruimtespel - Scoren en Levens: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Wat is een leuke manier om te laten zien hoeveel levens een speler nog heeft?", + "answerOptions": [ + { + "answerText": "een aantal schepen", + "isCorrect": "false" + }, + { + "answerText": "een puntensysteem", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Hoe centreert u tekst in het midden van het scherm met behulp van het Canvas-element?", + "answerOptions": [ + { + "answerText": "U gebruikt Flexbox", + "isCorrect": "false" + }, + { + "answerText": "U instrueert de tekst die moet worden getekend op de x-coördinaat van de breedte van het cliëntvenster/2", + "isCorrect": "true" + }, + { + "answerText": "U stelt de eigenschap textAlign in op het waardecentrum van het contextobject", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Trek in code een leven af met dit:", + "answerOptions": [ + { + "answerText": "this.life-", + "isCorrect": "false" + }, + { + "answerText": "this.life--", + "isCorrect": "true" + }, + { + "answerText": "this.life++", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 39, + "title": "Les 20 - Ruimtespel - Einde en Herstart: Quiz voorafgaand aan de Lezingz", + "quiz": [ + { + "questionText": "Wanneer is een goed moment om een game opnieuw te starten?", + "answerOptions": [ + { + "answerText": "wanneer een speler wint of verliest", + "isCorrect": "true" + }, + { + "answerText": "wanneer dan ook", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wanneer moet een spel eindigen?", + "answerOptions": [ + { + "answerText": "wanneer een vijandelijk schip wordt vernietigd", + "isCorrect": "false" + }, + { + "answerText": "wanneer een heldenschip wordt vernietigd", + "isCorrect": "true" + }, + { + "answerText": "wanneer punten worden verzameld", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Een goede manier om een level aan uw game toe te voegen is:", + "answerOptions": [ + { + "answerText": "Het aantal punten dat nodig is om een bepaald niveau te voltooien verhogen", + "isCorrect": "true" + }, + { + "answerText": "Meer spelers aan het spel toe te voegen", + "isCorrect": "false" + }, + { + "answerText": "Meer afbeeldingen aan het spel toe te voegen", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 40, + "title": "Les 20 - Ruimtespel - Einde en Herstart: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Wat is een goed patroon om te gebruiken als aan een speleindvoorwaarde is voldaan?", + "answerOptions": [ + { + "answerText": "Een passend bericht weergeven", + "isCorrect": "false" + }, + { + "answerText": "Het spel verlaten", + "isCorrect": "false" + }, + { + "answerText": "Een passend bericht weergeven, bied de speler aan om opnieuw op te starten en laat zien welke toets hij voor die actie moet raken", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U moet alleen een herstart aanbieden als het spel is afgelopen", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Een goede manier om de EventEmitter te wissen bij het beëindigen van een game is:", + "answerOptions": [ + { + "answerText": "luisteraars opruimen", + "isCorrect": "true" + }, + { + "answerText": "het scherm leegmaken", + "isCorrect": "false" + }, + { + "answerText": "het spelvenster sluiten", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 41, + "title": "Les 21 - Bankproject - HTML-Sjablonen en Routes in een Webapp: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "U moet meerdere HTML-bestanden maken om verschillende schermen in een webapp weer te geven", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "U kunt gegevens lokaal opslaan en bewaren in een webapp", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wat is de beste gegevensprovider voor een webapp?", + "answerOptions": [ + { + "answerText": "Een lokale database", + "isCorrect": "false" + }, + { + "answerText": "Een JavaScript-object", + "isCorrect": "false" + }, + { + "answerText": "Een server met een JSON API", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 42, + "title": "Les 21 - Bankproject - HTML-Sjablonen en Routes in een Webapp: Quiz na de Lezing", + "quiz": [ + { + "questionText": "HTML-sjablonen maken standaard deel uit van de DOM", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Welk deel van de URL is nodig voor routering?", + "answerOptions": [ + { + "answerText": "window.location.pathname", + "isCorrect": "false" + }, + { + "answerText": "window.location.origin", + "isCorrect": "false" + }, + { + "answerText": "beide", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat is de naam van de gebeurtenis die is geactiveerd bij het aanroepen van de functie history.pushState()?", + "answerOptions": [ + { + "answerText": "pushstate", + "isCorrect": "false" + }, + { + "answerText": "popstate", + "isCorrect": "true" + }, + { + "answerText": "navigate", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 43, + "title": "Les 22 - Bankproject - Bouw een Aanmeldings- en Registratieformulier: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Met HTML-formulieren kunt u gebruikersinvoer naar een server sturen zonder JavaScript te gebruiken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "<label>-elementen zijn verplicht voor elk formulierelement", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het is veilig om formuliergegevens via HTTP naar een server te verzenden", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 44, + "title": "Les 22 - Bankproject - Bouw een Aanmeldings- en Registratieformulier: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Het gebruik van <label>-elementen in formulieren is alleen bedoeld om het formulier mooi te maken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "In welk deel van een formulier wordt een URL naar een server gestuurd?", + "answerOptions": [ + { + "answerText": "het action attribuut", + "isCorrect": "true" + }, + { + "answerText": "het method attribuut", + "isCorrect": "false" + }, + { + "answerText": "beide", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Welk attribuut kunt u gebruiken om de maximale grootte van een tekst <input> in te stellen?", + "answerOptions": [ + { + "answerText": "max", + "isCorrect": "false" + }, + { + "answerText": "maxlength", + "isCorrect": "true" + }, + { + "answerText": "pattern", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 45, + "title": "Les 23 - Bankproject - Methoden voor het Ophalen en Gebruiken van Gegevens: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Meestal haalt u gegevens synchroon op van een server in een browser", + "answerOptions": [ + { + "answerText": "waar, maar async is het beste!", + "isCorrect": "true" + }, + { + "answerText": "niet waar", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Wat is het meest gebruikte formaat om gegevens op internet uit te wisselen?", + "answerOptions": [ + { + "answerText": "HTML", + "isCorrect": "false" + }, + { + "answerText": "XML", + "isCorrect": "false" + }, + { + "answerText": "JSON", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Er is geen manier om te voorkomen dat een webpagina toegang krijgt tot een openbare server-API", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 46, + "title": "Les 23 - Bankproject - Methoden voor het Ophalen en Gebruiken van Gegevens: Quiz na de Lezing", + "quiz": [ + { + "questionText": "In een app met één pagina wordt de HTML één keer geladen en nooit bijgewerkt", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Waarom is het belangrijk om gegevens die afkomstig zijn van gebruikersinvoer niet te vertrouwen?", + "answerOptions": [ + { + "answerText": "omdat het gebruik van speciale tekens de gebruikersinterface lelijk kan maken.", + "isCorrect": "false" + }, + { + "answerText": "omdat het onlogische of aanstootgevende woorden kan bevatten.", + "isCorrect": "false" + }, + { + "answerText": "omdat het kan worden gebruikt als aanvalsvector om kwaadaardige scripts uit te voeren.", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat is de API-naam voor het verzenden van asynchrone HTTP-verzoeken naar een webserver?", + "answerOptions": [ + { + "answerText": "request()", + "isCorrect": "false" + }, + { + "answerText": "fetch()", + "isCorrect": "true" + }, + { + "answerText": "ajax()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 47, + "title": "Les 24 - Bankproject - Concepten van Staatsbeheer: Quiz voorafgaand aan de Lezing", + "quiz": [ + { + "questionText": "Wat is een onveranderlijk object?", + "answerOptions": [ + { + "answerText": "Een object gedefinieerd als een constante", + "isCorrect": "false" + }, + { + "answerText": "Een object dat niet kan worden gewijzigd nadat het is gemaakt", + "isCorrect": "true" + }, + { + "answerText": "Een kopie van een bestaand object", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Welk voordeel(en) haalt u uit het gebruik van staatsbeheer?", + "answerOptions": [ + { + "answerText": "U kunt elke plaats bijhouden waar de staat wordt bijgewerkt", + "isCorrect": "false" + }, + { + "answerText": "Het is gemakkelijker om de code te debuggen", + "isCorrect": "false" + }, + { + "answerText": "Alle bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Wat is de beste manier om kritieke gebruikersgegevens in verschillende sessies te bewaren?", + "answerOptions": [ + { + "answerText": "Met behulp van bestanden", + "isCorrect": "false" + }, + { + "answerText": "Met behulp van de localStorage API van de browser", + "isCorrect": "false" + }, + { + "answerText": "In een database achter een server-API", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 48, + "title": "Les 24 - Bankproject - Concepten van Staatsbeheer: Quiz na de Lezing", + "quiz": [ + { + "questionText": "Wat denkt u dat staatsbeheer betekent?", + "answerOptions": [ + { + "answerText": "Handhaving van de openbare orde", + "isCorrect": "false" + }, + { + "answerText": "De status van de gebruikersinterface in de loop van de tijd registreren", + "isCorrect": "false" + }, + { + "answerText": "De gegevensstromen van uw app schoon houden en de gebruikersinterface synchroniseren met gegevens", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Hoe kunt u de status van de gebruikerssessie bijhouden?", + "answerOptions": [ + { + "answerText": "HTTP-cookies", + "isCorrect": "false" + }, + { + "answerText": "Lokale of sessieopslag", + "isCorrect": "false" + }, + { + "answerText": "Alle bovenstaande", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Het muteren van een object is altijd de beste manier om het bij te werken", + "answerOptions": [ + { + "answerText": "waar", + "isCorrect": "false" + }, + { + "answerText": "niet waar", + "isCorrect": "true" + } + ] + } + ] + } + ] + } +] diff --git a/quiz-app/src/assets/translations/zh_cn.json b/quiz-app/src/assets/translations/zh_cn.json new file mode 100644 index 00000000..02cd865e --- /dev/null +++ b/quiz-app/src/assets/translations/zh_cn.json @@ -0,0 +1,2509 @@ +[ + { + "title": "面向初学者的 Web 开发入门: 小测验", + "complete": "恭喜,你完成了小测验!", + "error": "抱歉,请再试一次", + "quizzes": [ + { + "id": 1, + "title": "课程 1 - 编程语言介绍:课前小测", + "quiz": [ + { + "questionText": "程序可以在不编写任何代码的情况下生成", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "低级语言常被用于", + "answerOptions": [ + { + "answerText": "网页", + "isCorrect": "false" + }, + { + "answerText": "硬件", + "isCorrect": "true" + }, + { + "answerText": "游戏软件", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列哪种工具最可能出现在 Web 开发环境中?", + "answerOptions": [ + { + "answerText": "硬件,如树莓派", + "isCorrect": "false" + }, + { + "answerText": "浏览器开发者工具", + "isCorrect": "true" + }, + { + "answerText": "操作系统文档", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 2, + "title": "课程 1 - 编程语言介绍:课后小测", + "quiz": [ + { + "questionText": "你最可能用哪种语言来创建一个网站?", + "answerOptions": [ + { + "answerText": "机器语言", + "isCorrect": "false" + }, + { + "answerText": "JavaScript", + "isCorrect": "true" + }, + { + "answerText": "Bash", + "isCorrect": "false" + } + ] + }, + { + "questionText": "每位开发者的开发环境都不尽相同", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "开发者会通过什么方式修复有问题的代码?", + "answerOptions": [ + { + "answerText": "语法高亮", + "isCorrect": "false" + }, + { + "answerText": "代码调试", + "isCorrect": "true" + }, + { + "answerText": "代码格式化", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 3, + "title": "课程 2 - GitHub 介绍:课前小测", + "quiz": [ + { + "questionText": "如何创建一个 Git 仓库?", + "answerOptions": [ + { + "answerText": "git create", + "isCorrect": "false" + }, + { + "answerText": "git start", + "isCorrect": "false" + }, + { + "answerText": "git init", + "isCorrect": "true" + } + ] + }, + { + "questionText": "git add 命令的作用是?", + "answerOptions": [ + { + "answerText": "提交你的代码", + "isCorrect": "false" + }, + { + "answerText": "将你的文件放到暂存区以追踪它们", + "isCorrect": "true" + }, + { + "answerText": "将你的文件放到 GitHub", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何确认你的电脑上是否已经安装了 git?", + "answerOptions": [ + { + "answerText": "输入 git --version", + "isCorrect": "true" + }, + { + "answerText": "输入 git --installed", + "isCorrect": "false" + }, + { + "answerText": "输入 git --init", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 4, + "title": "课程 2 - GitHub 介绍:课后小测", + "quiz": [ + { + "questionText": "有一个地方可以用来比较和讨论一个分支引入的改动,并有检查、评论代码、集成测试等功能,这个地方是?", + "answerOptions": [ + { + "answerText": "GitHub", + "isCorrect": "false" + }, + { + "answerText": "Pull Request", + "isCorrect": "true" + }, + { + "answerText": "一个特性分支", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你该如何从一个远程分支获取所有提交?", + "answerOptions": [ + { + "answerText": "git fetch", + "isCorrect": "false" + }, + { + "answerText": "git pull", + "isCorrect": "true" + }, + { + "answerText": "git commits -r", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你该如何切换到一个分支?", + "answerOptions": [ + { + "answerText": "git switch [branch-name]", + "isCorrect": "false" + }, + { + "answerText": "git checkout [branch-name]", + "isCorrect": "true" + }, + { + "answerText": "git load [branch-name]", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 5, + "title": "课程 3 - 创造无障碍网页:课前小测", + "quiz": [ + { + "questionText": "下列哪种浏览器工具可以用于检查网站的无障碍性?", + "answerOptions": [ + { + "answerText": "Lighthouse", + "isCorrect": "true" + }, + { + "answerText": "Deckhouse", + "isCorrect": "false" + }, + { + "answerText": "Cleanhouse", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你必须得用一个实体的屏幕阅读器才能检查网页对视力障碍者的无障碍性", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有政府网站才需要关注无障碍性", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 6, + "title": "课程 3 - 创造无障碍网页:课后小测", + "quiz": [ + { + "questionText": "Lighthouse 只能用于检查无障碍相关问题", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "使用安全色的色板可以帮助到", + "answerOptions": [ + { + "answerText": "色盲人群", + "isCorrect": "false" + }, + { + "answerText": "视力障碍者", + "isCorrect": "false" + }, + { + "answerText": "以上两者", + "isCorrect": "true" + } + ] + }, + { + "questionText": "描述性链接对于无障碍网站来说很重要", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 7, + "title": "课程 4 - JavaScript 基础 - 数据类型:课前小测", + "quiz": [ + { + "questionText": "布尔值是可以用来记录字符串长度的数据类型", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以对字符串进行以下哪种操作?", + "answerOptions": [ + { + "answerText": "连接(concatenation)", + "isCorrect": "true" + }, + { + "answerText": "增添(appending)", + "isCorrect": "false" + }, + { + "answerText": "剪接(splicing)", + "isCorrect": "false" + } + ] + }, + { + "questionText": "== 和 === 可以互换使用", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 8, + "title": "课程 4 - JavaScript 基础 - 数据类型:课后小测", + "quiz": [ + { + "questionText": "在用于声明变量时,用 const 创建的常量与用 let 和 var 基本是相同的,区别在于:", + "answerOptions": [ + { + "answerText": "常量必须被初始化", + "isCorrect": "true" + }, + { + "answerText": "常量可以被修改", + "isCorrect": "false" + }, + { + "answerText": "常量可以被重新赋值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Numbers 和 ____ 是用于处理数值型数据的 JavaScript 基本类型", + "answerOptions": [ + { + "answerText": "bigint", + "isCorrect": "true" + }, + { + "answerText": "boolean", + "isCorrect": "false" + }, + { + "answerText": "star", + "isCorrect": "false" + } + ] + }, + { + "questionText": "单引号和双引号都可以用来包裹字符串", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 9, + "title": "课程 5 - JavaScript 基础 - 方法和函数:课前小测", + "quiz": [ + { + "questionText": "参数(argument)是什么?", + "answerOptions": [ + { + "answerText": "是你在函数定义中声明的一个东西", + "isCorrect": "false" + }, + { + "answerText": "是在函数调用时你传给函数的一个东西", + "isCorrect": "true" + }, + { + "answerText": "是你和熟人间共有的一个东西", + "isCorrect": "false" + } + ] + }, + { + "questionText": "函数必须有返回值", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以随意命名一个函数", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "是,但它最好是一个描述性的名称", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 10, + "title": "课程 5 - JavaScript 基础 - 方法和函数:课后小测", + "quiz": [ + { + "questionText": "函数在被调用时必须提供所有参数", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "默认值是做什么用的?", + "answerOptions": [ + { + "answerText": "设置一个正确的值", + "isCorrect": "false" + }, + { + "answerText": "为参数提供一个默认值,使得在省略参数时函数仍能正常工作", + "isCorrect": "true" + }, + { + "answerText": "毫无意义", + "isCorrect": "false" + } + ] + }, + { + "questionText": "箭头函数(fat arrow function)可以让你", + "answerOptions": [ + { + "answerText": "创建很重(heavy)的函数", + "isCorrect": "false" + }, + { + "answerText": "省略部分函数关键字(keyword)", + "isCorrect": "true" + }, + { + "answerText": "创建匿名函数", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 11, + "title": "课程 6 - JavaScript 基础 - 做出决定:课前小测", + "quiz": [ + { + "questionText": "运算符 == 被称为", + "answerOptions": [ + { + "answerText": "相等", + "isCorrect": "true" + }, + { + "answerText": "严格相等", + "isCorrect": "false" + }, + { + "answerText": "赋值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "JavaScript 中比较表达式会返回什么数据类型?", + "answerOptions": [ + { + "answerText": "布尔值(boolean)", + "isCorrect": "true" + }, + { + "answerText": "空值(null)", + "isCorrect": "false" + }, + { + "answerText": "字符串(string)", + "isCorrect": "false" + } + ] + }, + { + "questionText": "JavaScript 中 ! 符号表示:", + "answerOptions": [ + { + "answerText": "逻辑非", + "isCorrect": "true" + }, + { + "answerText": "很重要", + "isCorrect": "false" + }, + { + "answerText": "等于", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 12, + "title": "课程 6 - JavaScript 基础 - 做出决定:课后小测", + "quiz": [ + { + "questionText": "表达式 '1' == 1 的返回值是?", + "answerOptions": [ + { + "answerText": "true", + "isCorrect": "true" + }, + { + "answerText": "false", + "isCorrect": "false" + }, + { + "answerText": "null", + "isCorrect": "false" + } + ] + }, + { + "questionText": "表达式 '1' === 1 的返回值是?", + "answerOptions": [ + { + "answerText": "true", + "isCorrect": "false" + }, + { + "answerText": "false", + "isCorrect": "true" + }, + { + "answerText": "null", + "isCorrect": "false" + } + ] + }, + { + "questionText": "选择一个表达逻辑“或”的运算符", + "answerOptions": [ + { + "answerText": "a | b", + "isCorrect": "false" + }, + { + "answerText": "a || b", + "isCorrect": "true" + }, + { + "answerText": "a or b", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 13, + "title": "课程 7 - JavaScript 基础 - 数组和循环:课前小测", + "quiz": [ + { + "questionText": "要引用数组中的特定元素,你需要使用", + "answerOptions": [ + { + "answerText": "方括号 []", + "isCorrect": "false" + }, + { + "answerText": "索引", + "isCorrect": "true" + }, + { + "answerText": "大括号 {}", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何获取数组内元素个数?", + "answerOptions": [ + { + "answerText": "使用 'len(array)' 方法", + "isCorrect": "false" + }, + { + "answerText": "数组的 size 属性", + "isCorrect": "false" + }, + { + "answerText": "数组的 length 属性", + "isCorrect": "true" + } + ] + }, + { + "questionText": "JavaScript 中数组的索引从多少开始?", + "answerOptions": [ + { + "answerText": "0", + "isCorrect": "true" + }, + { + "answerText": "1", + "isCorrect": "false" + }, + { + "answerText": "2", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 14, + "title": "课程 7 - JavaScript 基础 - 数组和循环:课后小测", + "quiz": [ + { + "questionText": "修改 for 循环的哪一部分可以使它的迭代次数增加 5 次?", + "answerOptions": [ + { + "answerText": "条件表达式(condition)", + "isCorrect": "true" + }, + { + "answerText": "计数器(counter)", + "isCorrect": "false" + }, + { + "answerText": "迭代表达式(iteration-expression)", + "isCorrect": "false" + } + ] + }, + { + "questionText": "while 循环和 for 循环的区别是:", + "answerOptions": [ + { + "answerText": "for 循环有迭代表达式和计数器,而 while 循环只有条件表达式", + "isCorrect": "true" + }, + { + "answerText": "while 循环有迭代表达式和计数器,而 for 循环只有条件表达式", + "isCorrect": "false" + }, + { + "answerText": "它们是相同的,只是互为别称而已", + "isCorrect": "false" + } + ] + }, + { + "questionText": "循环表达式 for (let i=1; i < 5; i++) 会执行多少次迭代?", + "answerOptions": [ + { + "answerText": "5", + "isCorrect": "false" + }, + { + "answerText": "4", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 15, + "title": "课程 8 - 玻璃养育箱项目 - HTML 介绍:课前小测", + "quiz": [ + { + "questionText": "HTML 全称 'HyperText Mockup Language'", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "所有 HTML 标签都需要起始和闭合标签", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "使用语义化标签最重要的作用在于", + "answerOptions": [ + { + "answerText": "代码可读性", + "isCorrect": "false" + }, + { + "answerText": "屏幕阅读器", + "isCorrect": "true" + }, + { + "answerText": "可维护性", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 16, + "title": "课程 8 - 玻璃养育箱项目 - HTML 介绍:课后小测", + "quiz": [ + { + "questionText": "Spans 和 Divs 可以互换", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "HTML 文档的 head 可以包含:", + "answerOptions": [ + { + "answerText": "标题(title)标签", + "isCorrect": "false" + }, + { + "answerText": "元数据(metadata)", + "isCorrect": "false" + }, + { + "answerText": "以上皆可", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你不能使用不被推荐使用的标签", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但它们不被推荐使用是有原因的", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 17, + "title": "课程 9 - 玻璃养育箱项目 - CSS 介绍:课前小测", + "quiz": [ + { + "questionText": "HTML 元素必须有一个 class 或者 id 属性才能被添加样式", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS 全称 'Complete Style Sheets'", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS 可以被用来创建动画", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 18, + "title": "课程 9 - 玻璃养育箱项目 - CSS 介绍:课后小测", + "quiz": [ + { + "questionText": "你可以在 HTML 文件的 head 部分直接写 CSS", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "CSS 在应用程序中是必须的", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但是为了好看你就得用 CSS", + "isCorrect": "true" + } + ] + }, + { + "questionText": "哪一个浏览器工具可以被用来查看 CSS?", + "answerOptions": [ + { + "answerText": "Elements", + "isCorrect": "false" + }, + { + "answerText": "Styles", + "isCorrect": "true" + }, + { + "answerText": "Network", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 19, + "title": "课程 10 - 玻璃养育箱项目 - DOM 操作与闭包:课前小测", + "quiz": [ + { + "questionText": "DOM 全称 'Document Object Management'", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "DOM 可以理解为一棵树", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你可以利用 Web API 来操作 DOM", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 20, + "title": "课程 10 - 玻璃养育箱项目 - DOM 操作与闭包:课后小测", + "quiz": [ + { + "questionText": "DOM 是用于表示网页文档的一个模型", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用 JavaScript 闭包可以做到:", + "answerOptions": [ + { + "answerText": "在函数里写函数", + "isCorrect": "true" + }, + { + "answerText": "包住 DOM", + "isCorrect": "false" + }, + { + "answerText": "关闭脚本代码块", + "isCorrect": "false" + } + ] + }, + { + "questionText": "当一个或多个函数需要访问外部函数的 ______ 时,闭包会很有用", + "answerOptions": [ + { + "answerText": "数组", + "isCorrect": "false" + }, + { + "answerText": "作用域", + "isCorrect": "true" + }, + { + "answerText": "函数", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 21, + "title": "课程 11 - 打字游戏:课前小测", + "quiz": [ + { + "questionText": "事件驱动程序发生在使用者 ______ 时", + "answerOptions": [ + { + "answerText": "点击按钮", + "isCorrect": "false" + }, + { + "answerText": "改变数值", + "isCorrect": "false" + }, + { + "answerText": "与页面互动", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在面向过程编程中,函数会以下列哪种方式被调用?", + "answerOptions": [ + { + "answerText": "任何时间", + "isCorrect": "false" + }, + { + "answerText": "按特定顺序", + "isCorrect": "true" + }, + { + "answerText": "从左到右", + "isCorrect": "false" + } + ] + }, + { + "questionText": "由 DOM 暴露的用于注册事件句柄的全局方法是", + "answerOptions": [ + { + "answerText": "addEventListener", + "isCorrect": "true" + }, + { + "answerText": "addListener", + "isCorrect": "false" + }, + { + "answerText": "addEvent", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 22, + "title": "课程 11 - 打字游戏:课后小测", + "quiz": [ + { + "questionText": "用户在页面上的几乎所有行为都会触发事件", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "常见的事件包括", + "answerOptions": [ + { + "answerText": "click_event", + "isCorrect": "false" + }, + { + "answerText": "select_event", + "isCorrect": "false" + }, + { + "answerText": "input_event", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以用匿名函数来创建事件回调", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 23, + "title": "课程 12 - 浏览器扩展程序项目 - 关于浏览器的一切:课前小测", + "quiz": [ + { + "questionText": "你可以从下列哪一处获取浏览器扩展程序:", + "answerOptions": [ + { + "answerText": "沃尔玛", + "isCorrect": "false" + }, + { + "answerText": "浏览器扩展程序商店", + "isCorrect": "true" + }, + { + "answerText": "App store", + "isCorrect": "false" + } + ] + }, + { + "questionText": "NPM 全称", + "answerOptions": [ + { + "answerText": "Node Package Manager", + "isCorrect": "true" + }, + { + "answerText": "Netscape Primary Mix", + "isCorrect": "false" + }, + { + "answerText": "Natural Processing Manager", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你的浏览器可以安全或非安全地提供网页服务", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 24, + "title": "课程 12 - 浏览器扩展程序项目 - 关于浏览器的一切:课后小测", + "quiz": [ + { + "questionText": "万维网(The World Wide Web)的发明者是", + "answerOptions": [ + { + "answerText": "Tom Barnard-Loft", + "isCorrect": "false" + }, + { + "answerText": "Tim Berners-Lee", + "isCorrect": "true" + }, + { + "answerText": "Trish Berth-Pool", + "isCorrect": "false" + } + ] + }, + { + "questionText": "世界上第一款浏览器是", + "answerOptions": [ + { + "answerText": "WorldWideWeb", + "isCorrect": "true" + }, + { + "answerText": "Mozilla", + "isCorrect": "false" + }, + { + "answerText": "Netscape", + "isCorrect": "false" + } + ] + }, + { + "questionText": "浏览器可以记录使用者的浏览记录", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 25, + "title": "课程 13 - 浏览器扩展程序项目 - 调用 API,使用 Local Storage:课前小测", + "quiz": [ + { + "questionText": "APIs 全称", + "answerOptions": [ + { + "answerText": "Application Programming Interfaces", + "isCorrect": "true" + }, + { + "answerText": "A Programming Inference", + "isCorrect": "false" + }, + { + "answerText": "Anti Proven Intentions", + "isCorrect": "false" + } + ] + }, + { + "questionText": "API 用于和 _____ 交互", + "answerOptions": [ + { + "answerText": "另一处网络资源", + "isCorrect": "false" + }, + { + "answerText": "数据库", + "isCorrect": "false" + }, + { + "answerText": "以上皆可", + "isCorrect": "true" + } + ] + }, + { + "questionText": "任何人都可以创建 API", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 26, + "title": "课程 13 - 浏览器扩展程序项目 - 调用 API,使用 Local Storage:课后小测", + "quiz": [ + { + "questionText": "LocalStorage 会在关闭浏览器窗口时清空", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "浏览器扩展程序的 LocalStorage 由浏览器主窗口负责管理", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "REST 在 API 语境下全称", + "answerOptions": [ + { + "answerText": "Representational State Transfer", + "isCorrect": "true" + }, + { + "answerText": "Returning State Tasks", + "isCorrect": "false" + }, + { + "answerText": "Rendering State To Browser", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 27, + "title": "课程 14 - 浏览器扩展程序项目 - 了解后台任务和性能:课前小测", + "quiz": [ + { + "questionText": "你该用什么方式来测试应用程序的性能?", + "answerOptions": [ + { + "answerText": "使用浏览器工具", + "isCorrect": "true" + }, + { + "answerText": "使用独立软件包", + "isCorrect": "false" + }, + { + "answerText": "手动测试", + "isCorrect": "false" + } + ] + }, + { + "questionText": "网站的“性能”一般指的是", + "answerOptions": [ + { + "answerText": "加载速度有多快", + "isCorrect": "false" + }, + { + "answerText": "代码运行速度有多快", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "总体来说,近年来网页的“重量”", + "answerOptions": [ + { + "answerText": "变轻了", + "isCorrect": "false" + }, + { + "answerText": "变重了", + "isCorrect": "true" + }, + { + "answerText": "没怎么变", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 28, + "title": "课程 14 - 浏览器扩展程序项目 - 了解后台任务和性能:课后小测", + "quiz": [ + { + "questionText": "为了更好地查看你的网站的性能,应当清空网站缓存并且重新加载分析工具", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "浏览器扩展程序天然性能就不错", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "一般会在什么方面寻找性能瓶颈?", + "answerOptions": [ + { + "answerText": "DOM 遍历", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 优化", + "isCorrect": "false" + }, + { + "answerText": "静态资源管理", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 29, + "title": "课程 15 - 太空游戏 - 介绍:课前小测", + "quiz": [ + { + "questionText": "JavaScript 不是常见的游戏开发语言", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "发布/订阅(Pub/Sub)管理游戏资源和流程的首选模式", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "类(classes)和组合(composition)都可以用来实现对象继承", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 30, + "title": "课程 15 - 太空游戏 - 介绍:课后小测", + "quiz": [ + { + "questionText": "类通过继承来合并各种行为", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "组合是游戏对象的最佳设计模式", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Pub/Sub 全称为:", + "answerOptions": [ + { + "answerText": "Publish/Subscribe", + "isCorrect": "true" + }, + { + "answerText": "Print/Staple", + "isCorrect": "false" + }, + { + "answerText": "Publish/Sanitize", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 31, + "title": "课程 16 - 太空游戏 - 把英雄和怪兽画到画布上:课前小测", + "quiz": [ + { + "questionText": "你可以利用 Canvas 元素来在屏幕上绘制图案", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你只能用 Canvas API 绘制简单的几何图形", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "坐标点 (0,0) 在画布左下角", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 32, + "title": "课程 16 - 太空游戏 - 把英雄和怪兽画到画布上:课后小测", + "quiz": [ + { + "questionText": "你可以直接在 Canvas 上执行绘制操作", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以通过监听 onload 事件来获知一个图片是否已经异步加载完成", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你可以通过下列哪个方法来将图片绘制在屏幕上?", + "answerOptions": [ + { + "answerText": "paintImage()", + "isCorrect": "false" + }, + { + "answerText": "drawImage()", + "isCorrect": "true" + }, + { + "answerText": "draw()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 33, + "title": "课程 17 - 太空游戏 - 添加动作:课前小测", + "quiz": [ + { + "questionText": "屏幕上的任何对象都可以接收键盘事件", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "你可以用相同的方式来监听鼠标事件和键盘事件", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "如果想要定期触发什么事情,你可以使用", + "answerOptions": [ + { + "answerText": "setInterval()", + "isCorrect": "true" + }, + { + "answerText": "setTimeout()", + "isCorrect": "false" + }, + { + "answerText": "sleep()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 34, + "title": "课程 17 - 太空游戏 - 添加动作:课后小测", + "quiz": [ + { + "questionText": "你总是需要完全重绘整个屏幕", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "游戏循环(game loop)是什么?", + "answerOptions": [ + { + "answerText": "一个确保游戏可以重新开始的函数", + "isCorrect": "false" + }, + { + "answerText": "一个决定游戏运行速度的函数", + "isCorrect": "false" + }, + { + "answerText": "一个定期触发来绘制使用者所见内容的函数", + "isCorrect": "true" + } + ] + }, + { + "questionText": "下列哪一个是触发屏幕重绘的恰当时机?", + "answerOptions": [ + { + "answerText": "使用者产生了交互", + "isCorrect": "false" + }, + { + "answerText": "有东西移动了", + "isCorrect": "true" + }, + { + "answerText": "时间推移", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 35, + "title": "课程 18 - 太空游戏 - 添加激光和碰撞检测:课前小测", + "quiz": [ + { + "questionText": "碰撞检测(Collision detection)指的是我们如何检测两个物件是否碰撞", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何从屏幕中移除一个物体?", + "answerOptions": [ + { + "answerText": "调用垃圾清理程序", + "isCorrect": "false" + }, + { + "answerText": "将其标记为死亡,下一次只绘制未死亡的物体", + "isCorrect": "true" + }, + { + "answerText": "将物体放到负坐标位置", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中模拟发射激光的一个好办法是:", + "answerOptions": [ + { + "answerText": "响应键盘事件来创建一个可见元素", + "isCorrect": "true" + }, + { + "answerText": "创建动态 gifs 图像", + "isCorrect": "false" + }, + { + "answerText": "使敌人定期爆炸", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 36, + "title": "课程 18 - 太空游戏 - 添加激光和碰撞检测:课后小测", + "quiz": [ + { + "questionText": "在碰撞检测中你会对比", + "answerOptions": [ + { + "answerText": "圆是否相交", + "isCorrect": "false" + }, + { + "answerText": "矩形是否相交", + "isCorrect": "true" + }, + { + "answerText": "两点间距", + "isCorrect": "false" + } + ] + }, + { + "questionText": "实现冷却时间的目的是", + "answerOptions": [ + { + "answerText": "让你没法反复地开火消灭敌人,以此提高游戏难度", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 在一定时间内只能处理有限的事件,需要进行限制", + "isCorrect": "true" + } + ] + }, + { + "questionText": "常量在代码中非常明显地原因是", + "answerOptions": [ + { + "answerText": "它们全是大写字母", + "isCorrect": "true" + }, + { + "answerText": "它们有特定的名称", + "isCorrect": "false" + }, + { + "answerText": "它们会以 kebab-case 命名", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 37, + "title": "课程 19 - 太空游戏 - 分数与生命数:课前小测", + "quiz": [ + { + "questionText": "如何利用 Canvas 元素在屏幕上绘制文字?", + "answerOptions": [ + { + "answerText": "将文字放在 div 或 span 元素中", + "isCorrect": "false" + }, + { + "answerText": "在 Canvas 元素上调用 drawText() 方法", + "isCorrect": "false" + }, + { + "answerText": "在 Canvas 上下文对象调用 fillText() 方法", + "isCorrect": "true" + } + ] + }, + { + "questionText": "为什么游戏中需要有“生命数”这一概念?", + "answerOptions": [ + { + "answerText": "来表现玩家能抗住多少攻击", + "isCorrect": "false" + }, + { + "answerText": "这样游戏就不会直接草草结束,你会有数次机会来尝试通关它", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以通过 _____ 来改变 Canvas 上文字的颜色", + "answerOptions": [ + { + "answerText": "fillColor", + "isCorrect": "false" + }, + { + "answerText": "fillStyle", + "isCorrect": "true" + }, + { + "answerText": "textAlign", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 38, + "title": "课程 19 - 太空游戏 - 分数与生命数:课后小测", + "quiz": [ + { + "questionText": "怎么样有趣地展示玩家剩余生命数?", + "answerOptions": [ + { + "answerText": "剩余舰船的数目", + "isCorrect": "false" + }, + { + "answerText": "一个点数系统", + "isCorrect": "true" + } + ] + }, + { + "questionText": "如何让 Canvas 元素中的文字在屏幕水平居中?", + "answerOptions": [ + { + "answerText": "用 Flexbox", + "isCorrect": "false" + }, + { + "answerText": "将文字的 x 坐标设置为窗口宽度的一半", + "isCorrect": "true" + }, + { + "answerText": "将上下文对象的 textAlign 属性值设置为 center", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在代码中,用这条代码来扣除一条生命:", + "answerOptions": [ + { + "answerText": "this.life-", + "isCorrect": "false" + }, + { + "answerText": "this.life--", + "isCorrect": "true" + }, + { + "answerText": "this.life++", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 39, + "title": "课程 20 - 太空游戏 - 结束与重新开始:课前小测", + "quiz": [ + { + "questionText": "何时是重新开始游戏的合适时机?", + "answerOptions": [ + { + "answerText": "当玩家胜利或失败时", + "isCorrect": "true" + }, + { + "answerText": "任何时间", + "isCorrect": "false" + } + ] + }, + { + "questionText": "游戏何时应该结束?", + "answerOptions": [ + { + "answerText": "当一艘敌方舰艇被击毁时", + "isCorrect": "false" + }, + { + "answerText": "当一艘英雄舰艇被击毁时", + "isCorrect": "true" + }, + { + "answerText": "当点数足够时", + "isCorrect": "false" + } + ] + }, + { + "questionText": "给游戏添加新关卡的合理方式是:", + "answerOptions": [ + { + "answerText": "对给定关卡,提高过关所需的点数要求", + "isCorrect": "true" + }, + { + "answerText": "增加更多玩家", + "isCorrect": "false" + }, + { + "answerText": "增加更多图像", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 40, + "title": "课程 20 - 太空游戏 - 结束与重新开始:课后小测", + "quiz": [ + { + "questionText": "当触发游戏结束条件时,该以什么方式来展现?", + "answerOptions": [ + { + "answerText": "展示一条合适的信息", + "isCorrect": "false" + }, + { + "answerText": "退出游戏", + "isCorrect": "false" + }, + { + "answerText": "展示一条合适的信息,询问玩家是否重来,并展示对应操作的按键", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有游戏结束时才应该提供重新开始功能", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "当游戏结束时,清除 EventEmitter 的合适方式是:", + "answerOptions": [ + { + "answerText": "清除事件监听", + "isCorrect": "true" + }, + { + "answerText": "清空屏幕", + "isCorrect": "false" + }, + { + "answerText": "关闭游戏窗口", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 41, + "title": "课程 21 - 银行项目 - HTML 模板和 Web 应用的路由:课前小测", + "quiz": [ + { + "questionText": "Web 应用中需要用多个 HTML 文件才能创建多个页面", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Web 应用中可以在本地存储和保持数据", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Web 应用中数据来源的最佳选择是:", + "answerOptions": [ + { + "answerText": "一个本地数据库", + "isCorrect": "false" + }, + { + "answerText": "一个 JavaScript 对象", + "isCorrect": "false" + }, + { + "answerText": "一个有 JSON API 的服务器", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 42, + "title": "课程 21 - 银行项目 - HTML 模板和 Web 应用的路由:课后小测", + "quiz": [ + { + "questionText": "HTML 模板默认是 DOM 的一部分", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "URL 中的哪一部分被用于路由?", + "answerOptions": [ + { + "answerText": "window.location.pathname", + "isCorrect": "false" + }, + { + "answerText": "window.location.origin", + "isCorrect": "false" + }, + { + "answerText": "两者皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "当 history.pushState() 函数被调用时,触发的事件名为", + "answerOptions": [ + { + "answerText": "pushstate", + "isCorrect": "false" + }, + { + "answerText": "popstate", + "isCorrect": "true" + }, + { + "answerText": "navigate", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 43, + "title": "课程 22 - 银行项目 - 建立登录和注册表单:课前小测", + "quiz": [ + { + "questionText": "HTML 表单允许你不利用 JavaScript 即可将用户输入传给服务器", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "<label> 元素在每个表单控制上都是强制需要的", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "通过 HTTP 协议向服务器传输表单数据是安全的", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 44, + "title": "课程 22 - 银行项目 - 建立登录和注册表单:课后小测", + "quiz": [ + { + "questionText": "在表单中使用 <label> 元素只是为了让表单更好看", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "将数据传给服务器时,URL 会在表单的哪一部分?", + "answerOptions": [ + { + "answerText": "Action 属性", + "isCorrect": "true" + }, + { + "answerText": "Method 属性", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "false" + } + ] + }, + { + "questionText": "用哪个属性可以设置 <input> 标签输入文字的字数上限?", + "answerOptions": [ + { + "answerText": "max", + "isCorrect": "false" + }, + { + "answerText": "maxlength", + "isCorrect": "true" + }, + { + "answerText": "pattern", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 45, + "title": "课程 23 - 银行项目 - 拉取和使用数据的方法:课前小测", + "quiz": [ + { + "questionText": "在浏览器中,常通过同步(synchronously)的方式拉取服务器的数据", + "answerOptions": [ + { + "answerText": "是,但是异步才是最好的!", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 Web 中最常见的数据交换格式是", + "answerOptions": [ + { + "answerText": "HTML", + "isCorrect": "false" + }, + { + "answerText": "XML", + "isCorrect": "false" + }, + { + "answerText": "JSON", + "isCorrect": "true" + } + ] + }, + { + "questionText": "没有办法阻止一个网页访问公开服务器的 API", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 46, + "title": "课程 23 - 银行项目 - 拉取和使用数据的方法:课后小测", + "quiz": [ + { + "questionText": "在单页应用中,HTML 文件只会被加载一次且不再更新", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "为什么不信任来自用户输入的数据很重要?", + "answerOptions": [ + { + "answerText": "因为使用特定字符会让 UI 变丑。", + "isCorrect": "false" + }, + { + "answerText": "因为可能包含无意义或攻击性的言论。", + "isCorrect": "false" + }, + { + "answerText": "因为其可被利用为执行恶意脚本进行攻击的途径。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "发送异步 HTTP 请求到 Web 服务器的 API 名称是?", + "answerOptions": [ + { + "answerText": "request()", + "isCorrect": "false" + }, + { + "answerText": "fetch()", + "isCorrect": "true" + }, + { + "answerText": "ajax()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 47, + "title": "课程 24 - 银行项目 - 状态管理介绍:课前小测", + "quiz": [ + { + "questionText": "什么是不可变对象(immutable object)?", + "answerOptions": [ + { + "answerText": "定义为常量的一个对象", + "isCorrect": "false" + }, + { + "answerText": "在创建后就不能再修改的对象", + "isCorrect": "true" + }, + { + "answerText": "对已经存在的对象的拷贝", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用状态管理的益处有?", + "answerOptions": [ + { + "answerText": "可以追踪到每一个状态发生改变的位置", + "isCorrect": "false" + }, + { + "answerText": "更容易调试代码", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在不同会话期(session)保留重要用户数据的最佳方式是?", + "answerOptions": [ + { + "answerText": "使用文件", + "isCorrect": "false" + }, + { + "answerText": "使用浏览器的 localStorage API", + "isCorrect": "false" + }, + { + "answerText": "使用服务器 API 后的数据库", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 48, + "title": "课程 24 - 银行项目 - 状态管理介绍:课后小测", + "quiz": [ + { + "questionText": "你认为状态管理的意义是?", + "answerOptions": [ + { + "answerText": "规则与秩序的强制性", + "isCorrect": "false" + }, + { + "answerText": "随时间变化记录用户界面的状态", + "isCorrect": "false" + }, + { + "answerText": "保证应用的数据流清晰可控,保持数据和用户界面的同步性", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你该如何保持用户会话期状态的追踪?", + "answerOptions": [ + { + "answerText": "HTTP cookies", + "isCorrect": "false" + }, + { + "answerText": "Local or session storage", + "isCorrect": "false" + }, + { + "answerText": "两者皆可", + "isCorrect": "true" + } + ] + }, + { + "questionText": "直接改变一个对象总是更新它的最佳方式", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + } + ] + } +] diff --git a/quiz-app/src/assets/translations/zh_tw.json b/quiz-app/src/assets/translations/zh_tw.json new file mode 100644 index 00000000..239c835a --- /dev/null +++ b/quiz-app/src/assets/translations/zh_tw.json @@ -0,0 +1,2509 @@ +[ + { + "title": "給初學者的網頁開發:小測驗", + "complete": "恭喜,您完成了所有試題!", + "error": "抱歉。請稍後再試。", + "quizzes": [ + { + "id": 1, + "title": "課程一 - 程式語言概論:課前測驗", + "quiz": [ + { + "questionText": "開發人員可在不編寫程式碼的情況下產生程式。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "低階語言常被使用在:", + "answerOptions": [ + { + "answerText": "網頁", + "isCorrect": "false" + }, + { + "answerText": "硬體", + "isCorrect": "true" + }, + { + "answerText": "遊戲軟體", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者工具會出現在網頁開發的環境中?", + "answerOptions": [ + { + "answerText": "硬體,如樹莓派", + "isCorrect": "false" + }, + { + "answerText": "瀏覽器開發工具", + "isCorrect": "true" + }, + { + "answerText": "作業系統相關文件", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 2, + "title": "課程一 - 程式語言簡介:課後測驗", + "quiz": [ + { + "questionText": "下列何者程式語言比較適合用來撰寫網頁?", + "answerOptions": [ + { + "answerText": "機器語言", + "isCorrect": "false" + }, + { + "answerText": "JavaScript", + "isCorrect": "true" + }, + { + "answerText": "Bash", + "isCorrect": "false" + } + ] + }, + { + "questionText": "每一位開發人員的開發環境都不盡相同。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "開發人員會如何修正錯誤的程式碼?", + "answerOptions": [ + { + "answerText": "語法突顯", + "isCorrect": "false" + }, + { + "answerText": "偵錯", + "isCorrect": "true" + }, + { + "answerText": "程式碼格式化", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 3, + "title": "課程二 - GitHub簡介:課前測驗", + "quiz": [ + { + "questionText": "下列何種指令可以建立 Git 數據庫?", + "answerOptions": [ + { + "answerText": "git create", + "isCorrect": "false" + }, + { + "answerText": "git start", + "isCorrect": "false" + }, + { + "answerText": "git init", + "isCorrect": "true" + } + ] + }, + { + "questionText": "指令 git add 的目的為何?", + "answerOptions": [ + { + "answerText": "提交程式碼。", + "isCorrect": "false" + }, + { + "answerText": "加入檔案至索引成追蹤對象。", + "isCorrect": "true" + }, + { + "answerText": "加入檔案至GitHub。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何確認電腦內是否有安裝 git?", + "answerOptions": [ + { + "answerText": "輸入 git --version", + "isCorrect": "true" + }, + { + "answerText": "輸入 git --installed", + "isCorrect": "false" + }, + { + "answerText": "輸入 git --init", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 4, + "title": "課程二 - GitHub簡介:課後測驗", + "quiz": [ + { + "questionText": "下列何者能確認同一分支內不同更動的審查、評論、測試……等?", + "answerOptions": [ + { + "answerText": "GitHub", + "isCorrect": "false" + }, + { + "answerText": "Pull Request", + "isCorrect": "true" + }, + { + "answerText": "Feature Branch", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何從遠端數據庫中取得所有的提交?", + "answerOptions": [ + { + "answerText": "git fetch", + "isCorrect": "false" + }, + { + "answerText": "git pull", + "isCorrect": "true" + }, + { + "answerText": "git commits -r", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何切換分支?", + "answerOptions": [ + { + "answerText": "git switch [分支名稱]", + "isCorrect": "false" + }, + { + "answerText": "git checkout [分支名稱]", + "isCorrect": "true" + }, + { + "answerText": "git load [分支名稱]", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 5, + "title": "課程三 - 建立無障礙網頁:課前測驗", + "quiz": [ + { + "questionText": "下列何種工具可以確認網頁的無障礙性?", + "answerOptions": [ + { + "answerText": "Lighthouse", + "isCorrect": "true" + }, + { + "answerText": "Deckhouse", + "isCorrect": "false" + }, + { + "answerText": "Cleanhouse", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有實體的螢幕報讀器才能對視覺障礙者測試網頁親和力。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "網頁親和力只在公家機關的網頁才有需求。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 6, + "title": "課程三 - 建立無障礙網頁:課後測驗", + "quiz": [ + { + "questionText": "Lighthouse 只能檢查網頁親和力。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "安全的配色可以幫助到:", + "answerOptions": [ + { + "answerText": "色盲", + "isCorrect": "false" + }, + { + "answerText": "視覺障礙者", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "描述性連結是無障礙網頁中重要的部分。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 7, + "title": "課程四 - JavaScript 入門 - 資料型態:課前測驗", + "quiz": [ + { + "questionText": "布林是檢查字串的長度的資料型態。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "下列何種行為可以用在字串上?", + "answerOptions": [ + { + "answerText": "合併", + "isCorrect": "true" + }, + { + "answerText": "串接", + "isCorrect": "false" + }, + { + "answerText": "拼接", + "isCorrect": "false" + } + ] + }, + { + "questionText": "== 和 === 是可互換的。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 8, + "title": "課程四 - JavaScript 入門 - 資料型態:課後測驗", + "quiz": [ + { + "questionText": "常數與 let 和 var 宣告的變數相同,除了:", + "answerOptions": [ + { + "answerText": "常數必須要初始化。", + "isCorrect": "true" + }, + { + "answerText": "常數可以被修改。", + "isCorrect": "false" + }, + { + "answerText": "常數可以被重新賦值。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,負責處理數值型態資料的為 Numbers 與:", + "answerOptions": [ + { + "answerText": "bigint", + "isCorrect": "true" + }, + { + "answerText": "boolean", + "isCorrect": "false" + }, + { + "answerText": "star", + "isCorrect": "false" + } + ] + }, + { + "questionText": "字串值可以被單引號與雙引號所包住。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 9, + "title": "課程五 - JavaScript 入門 - 函式與方法:課前測驗", + "quiz": [ + { + "questionText": "什麼是引數物件?", + "answerOptions": [ + { + "answerText": "用來宣告函式的定義。", + "isCorrect": "false" + }, + { + "answerText": "用來呼叫函式。", + "isCorrect": "true" + }, + { + "answerText": "用來與熟識的人共同持有。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "函式必須要有回傳值。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "你可以隨意命名函式的名稱。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "是,但以可描述性的名稱為佳。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 10, + "title": "課程五 - JavaScript 入門 - 函式與方法:課後測驗", + "quiz": [ + { + "questionText": "引數物件必須提供函式需要的所有參數。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "預設值(Default Value)的目的為何?", + "answerOptions": [ + { + "answerText": "設定正確的數值。", + "isCorrect": "false" + }, + { + "answerText": "參數的初始值,當忽略引數時,程式碼仍可運作。", + "isCorrect": "true" + }, + { + "answerText": "沒有意義。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "箭頭函式(fat arrow functions)允許開發人員:", + "answerOptions": [ + { + "answerText": "建立很重(heavy)的函式。", + "isCorrect": "false" + }, + { + "answerText": "可以忽略部分的函式名稱。", + "isCorrect": "true" + }, + { + "answerText": "建立匿名函式。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 11, + "title": "課程六 - JavaScript 入門 - 做出決定:課前測驗", + "quiz": [ + { + "questionText": "運算子 == 的運算為:", + "answerOptions": [ + { + "answerText": "相等", + "isCorrect": "true" + }, + { + "answerText": "嚴格相等", + "isCorrect": "false" + }, + { + "answerText": "賦值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,比較式後回傳的資料型態為?", + "answerOptions": [ + { + "answerText": "布林", + "isCorrect": "true" + }, + { + "answerText": "空值", + "isCorrect": "false" + }, + { + "answerText": "字串", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中,符號 ! 代表:", + "answerOptions": [ + { + "answerText": "邏輯非", + "isCorrect": "true" + }, + { + "answerText": "重要的", + "isCorrect": "false" + }, + { + "answerText": "等於", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 12, + "title": "課程六 - JavaScript 入門 - 做出決定:課後測驗", + "quiz": [ + { + "questionText": "條件式 '1' == 1 會回傳下列何種結果?", + "answerOptions": [ + { + "answerText": "true", + "isCorrect": "true" + }, + { + "answerText": "false", + "isCorrect": "false" + }, + { + "answerText": "null", + "isCorrect": "false" + } + ] + }, + { + "questionText": "條件式 '1' === 1 會回傳下列何種結果?", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + }, + { + "answerText": "空值", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者為正確的邏輯「或」表示方法?", + "answerOptions": [ + { + "answerText": "a | b", + "isCorrect": "false" + }, + { + "answerText": "a || b", + "isCorrect": "true" + }, + { + "answerText": "a or b", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 13, + "title": "課程七 - JavaScript 入門 - 矩陣與迴圈:課前測驗", + "quiz": [ + { + "questionText": "如果要提出矩陣中特定的元素,必須使用:", + "answerOptions": [ + { + "answerText": "中括號 []", + "isCorrect": "false" + }, + { + "answerText": "索引", + "isCorrect": "true" + }, + { + "answerText": "大括號 {}", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何取得矩陣內的元素個數?", + "answerOptions": [ + { + "answerText": "len(array)", + "isCorrect": "false" + }, + { + "answerText": "矩陣的屬性大小(Property Size)。", + "isCorrect": "false" + }, + { + "answerText": "矩陣的屬性長度(Property Length)。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在 JavaScript 中,索引從何數開始計算?", + "answerOptions": [ + { + "answerText": "0", + "isCorrect": "true" + }, + { + "answerText": "1", + "isCorrect": "false" + }, + { + "answerText": "2", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 14, + "title": "課程七 - JavaScript 入門 - 矩陣與迴圈:課後測驗", + "quiz": [ + { + "questionText": "在 for-loop 迴圈中,需要修改何處來增加迭代次數到5次?", + "answerOptions": [ + { + "answerText": "條件式", + "isCorrect": "true" + }, + { + "answerText": "計數器", + "isCorrect": "false" + }, + { + "answerText": "迭代陳述式", + "isCorrect": "false" + } + ] + }, + { + "questionText": "while 迴圈與 for-loop 迴圈的差異在於:", + "answerOptions": [ + { + "answerText": "for-loop 迴圈需要計數器與迭代陳述式,while 迴圈只需要條件式。", + "isCorrect": "true" + }, + { + "answerText": "while 迴圈需要計數器與迭代陳述式,for-loop 迴圈只需要條件式。", + "isCorrect": "false" + }, + { + "answerText": "它們是一樣的,只是另一種稱呼而已。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "迴圈 (let i=1; i < 5; i++)中,會執行多少次迭代??", + "answerOptions": [ + { + "answerText": "5", + "isCorrect": "false" + }, + { + "answerText": "4", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 15, + "title": "課程八 - Terrarium 專案 - HTML 簡介:課前測驗", + "quiz": [ + { + "questionText": "HTML 的全名為 HyperText Mockup Language。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "所有的 HTML 標籤都需要起始標籤與結束標籤。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "使用語意標籤最重要的應用為:", + "answerOptions": [ + { + "answerText": "方便程式碼的閱讀。", + "isCorrect": "false" + }, + { + "answerText": "螢幕閱讀器。", + "isCorrect": "true" + }, + { + "answerText": "管理用途。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 16, + "title": "課程八 - 盆栽盒專案 - HTML 簡介:課後測驗", + "quiz": [ + { + "questionText": "Spans 與 Divs 可以互相替換。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "HTML 文件的標頭可以包含:", + "answerOptions": [ + { + "answerText": "標題標籤(title tag)", + "isCorrect": "false" + }, + { + "answerText": "元資訊(metadata)", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "開發人員無法使用不推薦使用的標籤。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但它們有被否決的充分理由。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 17, + "title": "課程九 - 盆栽盒專案 - CSS 簡介:課前測驗", + "quiz": [ + { + "questionText": "HTML 元素必須包含 class 或 id 才能被造型化。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "CSS 全名為 Complete Style Sheets。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以利用 CSS 來建立動畫。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 18, + "title": "課程九 - 盆栽盒專案 - CSS 簡介:課後測驗", + "quiz": [ + { + "questionText": "CSS 可以被撰寫在 HTML 檔案的開頭。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "CSS 在應用程式中是必須的物件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "false" + }, + { + "answerText": "否,但如果想讓畫面變美觀就需要使用CSS。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以利用下列何者瀏覽器工具來檢查 CSS?", + "answerOptions": [ + { + "answerText": "Elements", + "isCorrect": "false" + }, + { + "answerText": "Styles", + "isCorrect": "true" + }, + { + "answerText": "Network", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 19, + "title": "課程十 - 盆栽盒專案 - DOM 元素控制與閉包:課前測驗", + "quiz": [ + { + "questionText": "DOM 全名為 Document Object Management", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以將 DOM 理解為樹的一種。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "利用網頁 API,開發人員就能控制 DOM 元素。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 20, + "title": "課程十 - 盆栽盒專案 - DOM 元素控制與閉包:課後測驗", + "quiz": [ + { + "questionText": "DOM 元素是表現網頁文件的一種物件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用 JavaScript 閉包可以達成:", + "answerOptions": [ + { + "answerText": "在函式中撰寫函式。", + "isCorrect": "true" + }, + { + "answerText": "將 DOM 元素包住。", + "isCorrect": "false" + }, + { + "answerText": "關閉腳本區。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用閉包可以在單一或多個函式中存取外部函式的 _________。", + "answerOptions": [ + { + "answerText": "矩陣", + "isCorrect": "false" + }, + { + "answerText": "作用域", + "isCorrect": "true" + }, + { + "answerText": "函式", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 21, + "title": "課程十一 - 打字遊戲:課前測驗", + "quiz": [ + { + "questionText": "事件驅動程式發生在使用者:", + "answerOptions": [ + { + "answerText": "按下按鈕。", + "isCorrect": "false" + }, + { + "answerText": "改變數值。", + "isCorrect": "false" + }, + { + "answerText": "與網頁作互動。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "在程序式程式中,函式會以下列方式被呼叫。", + "answerOptions": [ + { + "answerText": "在任何時刻中。", + "isCorrect": "false" + }, + { + "answerText": "在特定的順序中。", + "isCorrect": "true" + }, + { + "answerText": "由左至右。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 DOM 中最常用來建立事件處理的方法為:", + "answerOptions": [ + { + "answerText": "addEventListener", + "isCorrect": "true" + }, + { + "answerText": "addListener", + "isCorrect": "false" + }, + { + "answerText": "addEvent", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 22, + "title": "課程十一 - 打字遊戲:課後測驗", + "quiz": [ + { + "questionText": "使用者做的大部分網頁互動都會觸發事件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "常見的事件包括:", + "answerOptions": [ + { + "answerText": "click_event", + "isCorrect": "false" + }, + { + "answerText": "select_event", + "isCorrect": "false" + }, + { + "answerText": "input_event", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "可以使用匿名函式來建立事件處理。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 23, + "title": "課程十二 - 瀏覽器擴充功能專案 - 關於瀏覽器:課前測驗", + "quiz": [ + { + "questionText": "使用者可以從下列管道取得瀏覽器擴充功能:", + "answerOptions": [ + { + "answerText": "沃爾瑪(WalMart)", + "isCorrect": "false" + }, + { + "answerText": "瀏覽器擴充商店", + "isCorrect": "true" + }, + { + "answerText": "應用程式商店", + "isCorrect": "false" + } + ] + }, + { + "questionText": "NPM 全名為", + "answerOptions": [ + { + "answerText": "Node Package Manager", + "isCorrect": "true" + }, + { + "answerText": "Netscape Primary Mix", + "isCorrect": "false" + }, + { + "answerText": "Natural Processing Manager", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器可以安全地或非安全地提供網頁服務。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 24, + "title": "課程十二 - 瀏覽器擴充功能專案 - 關於瀏覽器:課後測驗", + "quiz": [ + { + "questionText": "網際網路的發明者為:", + "answerOptions": [ + { + "answerText": "Tom Barnard-Loft", + "isCorrect": "false" + }, + { + "answerText": "Tim Berners-Lee", + "isCorrect": "true" + }, + { + "answerText": "Trish Berth-Pool", + "isCorrect": "false" + } + ] + }, + { + "questionText": "第一款網頁瀏覽器為:", + "answerOptions": [ + { + "answerText": "WorldWideWeb", + "isCorrect": "true" + }, + { + "answerText": "Mozilla", + "isCorrect": "false" + }, + { + "answerText": "Netscape", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器可以儲存使用者上網的歷史紀錄。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 25, + "title": "課程十三 - 瀏覽器擴充功能專案 - 呼叫API、使用Local Storage:課前測驗", + "quiz": [ + { + "questionText": "APIs 全名為", + "answerOptions": [ + { + "answerText": "Application Programming Interfaces", + "isCorrect": "true" + }, + { + "answerText": "A Programming Inference", + "isCorrect": "false" + }, + { + "answerText": "Anti Proven Intentions", + "isCorrect": "false" + } + ] + }, + { + "questionText": "使用API能與 _________ 做互動。", + "answerOptions": [ + { + "answerText": "網路上的一項資產", + "isCorrect": "false" + }, + { + "answerText": "資料庫", + "isCorrect": "false" + }, + { + "answerText": "以上皆是", + "isCorrect": "true" + } + ] + }, + { + "questionText": "任何人都可以建立 API。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 26, + "title": "課程十三 - 瀏覽器擴充功能專案 - 呼叫API、使用Local Storage:課後測驗", + "quiz": [ + { + "questionText": "當使用者關閉瀏覽器視窗時,LocalStorage 會被清除。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "主要瀏覽器視窗會管理擴充功能的LocalStorage使用情形。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在API context中,REST 全名為", + "answerOptions": [ + { + "answerText": "Representational State Transfer", + "isCorrect": "true" + }, + { + "answerText": "Returning State Tasks", + "isCorrect": "false" + }, + { + "answerText": "Rendering State To Browser", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 27, + "title": "課程十四 - 瀏覽器擴充功能專案 - 學習背景工作與效能:課前測驗", + "quiz": [ + { + "questionText": "使用者可以利用下列何種方式測試應用程式的效能?", + "answerOptions": [ + { + "answerText": "瀏覽器工具", + "isCorrect": "true" + }, + { + "answerText": "獨立軟體包", + "isCorrect": "false" + }, + { + "answerText": "手動測試", + "isCorrect": "false" + } + ] + }, + { + "questionText": "通常網頁的效能代表:", + "answerOptions": [ + { + "answerText": "多快可以載入完成。", + "isCorrect": "false" + }, + { + "answerText": "程式執行的速率有多快。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "總體來說,在這幾年間網頁的「負擔」:", + "answerOptions": [ + { + "answerText": "變輕了。", + "isCorrect": "false" + }, + { + "answerText": "變重了。", + "isCorrect": "true" + }, + { + "answerText": "維持原樣。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 28, + "title": "課程十四 - 瀏覽器擴充功能專案 - 學習背景工作與效能:課後測驗", + "quiz": [ + { + "questionText": "為了取得更好的網頁效能,清除快取並重新載入效能分析器是一種方法。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "瀏覽器擴充功能是固有的功能。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "分析下列地方來尋找效能的瓶頸:", + "answerOptions": [ + { + "answerText": "DOM 查找元素。", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 最佳化。", + "isCorrect": "false" + }, + { + "answerText": "資產管理。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 29, + "title": "課程十五 - 太空遊戲 - 介紹:課前測驗", + "quiz": [ + { + "questionText": "JavaScript 是不常見的遊戲開發程式語言。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "發布/訂閱是管理遊戲資產與流程的合理規範。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "類別與組合可以處理物件繼承的概念。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 30, + "title": "課程十五 - 太空遊戲 - 介紹:課後測驗", + "quiz": [ + { + "questionText": "依賴物件繼承的類別可以歸咎於其行為。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "組合是處理遊戲物件最好的設計模式。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "Pub/Sub 代表的是:", + "answerOptions": [ + { + "answerText": "Publish/Subscribe", + "isCorrect": "true" + }, + { + "answerText": "Print/Staple", + "isCorrect": "false" + }, + { + "answerText": "Publish/Sanitize", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 31, + "title": "課程十六 - 太空遊戲 - 在畫布繪製英雄與怪物:課前測驗", + "quiz": [ + { + "questionText": "你可以利用Canvas元素在螢幕上繪製圖案。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "Canvas API只能畫出簡單的幾何圖形。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "座標點(0,0)代表Canvas左下方。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 32, + "title": "課程十六 - 太空遊戲 - 在畫布繪製英雄與怪物:課後測驗", + "quiz": [ + { + "questionText": "繪圖處理能直接應用在Canvas上。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "藉由監測讀取事件來得知非同步的圖片是否被載入完成。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "繪製圖片到螢幕的指令為:", + "answerOptions": [ + { + "answerText": "paintImage()", + "isCorrect": "false" + }, + { + "answerText": "drawImage()", + "isCorrect": "true" + }, + { + "answerText": "draw()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 33, + "title": "課程十七 - 太空遊戲 - 加入動作:課前測驗", + "quiz": [ + { + "questionText": "任何物件可以接收鍵盤事件。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "鍵盤事件與滑鼠事件是相同的監聽方法。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "若想讓事情定期的觸發,需要用到什麼函式?", + "answerOptions": [ + { + "answerText": "setInterval()", + "isCorrect": "true" + }, + { + "answerText": "setTimeout()", + "isCorrect": "false" + }, + { + "answerText": "sleep()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 34, + "title": "課程十七 - 太空遊戲 - 加入動作:課後測驗", + "quiz": [ + { + "questionText": "更新螢幕一定要全部重新繪製。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "什麼是遊戲迴圈?", + "answerOptions": [ + { + "answerText": "函式確保遊戲能重新開始。", + "isCorrect": "false" + }, + { + "answerText": "函式決定遊戲的運作時速。", + "isCorrect": "false" + }, + { + "answerText": "函式確保定期事件發生並將畫面呈獻給玩家。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "重新繪製螢幕的時機點為:", + "answerOptions": [ + { + "answerText": "玩家產生互動。", + "isCorrect": "false" + }, + { + "answerText": "有東西移動。", + "isCorrect": "true" + }, + { + "answerText": "時間的推移。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 35, + "title": "課程十八 - 太空遊戲 - 加入雷射與碰撞偵測:課前測驗", + "quiz": [ + { + "questionText": "碰撞偵測是偵測兩物體是否發生碰撞。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "如何將成員從螢幕中移除?", + "answerOptions": [ + { + "answerText": "呼叫垃圾清潔員。", + "isCorrect": "false" + }, + { + "answerText": "標記為陣亡,在下一個繪製週期只畫存活的成員。", + "isCorrect": "true" + }, + { + "answerText": "將成員移動到其他象限。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在 JavaScript 中模擬雷射最合適的方式為:", + "answerOptions": [ + { + "answerText": "根據鍵盤事件建立可視物件。", + "isCorrect": "true" + }, + { + "answerText": "建立動態圖像。", + "isCorrect": "false" + }, + { + "answerText": "讓敵人定期地爆炸。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 36, + "title": "課程十八 - 太空遊戲 - 加入雷射與碰撞偵測:課後測驗", + "quiz": [ + { + "questionText": "在碰撞偵測中,需要判斷兩者:", + "answerOptions": [ + { + "answerText": "圓圈內是否有所相交。", + "isCorrect": "false" + }, + { + "answerText": "矩形內是否有所相交。", + "isCorrect": "true" + }, + { + "answerText": "兩點之間的距離。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "建立冷卻時間的目的為:", + "answerOptions": [ + { + "answerText": "讓遊戲變得更難,讓玩家無法重複擊發雷射摧毀敵人。", + "isCorrect": "false" + }, + { + "answerText": "JavaScript 在單位時間內只能處理一定額度的事件,需要有所限制。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "常數在程式碼中是醒目的原因為:", + "answerOptions": [ + { + "answerText": "它們以全大寫書寫。", + "isCorrect": "true" + }, + { + "answerText": "它們有特定的名稱。", + "isCorrect": "false" + }, + { + "answerText": "它們用特定字元,連接。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 37, + "title": "課程十九 - 太空遊戲 - 分數與生命數:課前測驗", + "quiz": [ + { + "questionText": "如何利用Canvas元素在畫面上寫字?", + "answerOptions": [ + { + "answerText": "將文字包在div或span元素中。", + "isCorrect": "false" + }, + { + "answerText": "呼叫 drawText()在Canvas元素上。", + "isCorrect": "false" + }, + { + "answerText": "Call fillText() on the context object", + "isCorrect": "true" + } + ] + }, + { + "questionText": "為什麼遊戲需要有「性命數」的概念?", + "answerOptions": [ + { + "answerText": "為了表現玩家還能承受多少攻擊。", + "isCorrect": "false" + }, + { + "answerText": "為了讓遊戲不會直接結束,允許玩家有容錯空間。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "改變 Canvas 元素上字的顏色可以利用:", + "answerOptions": [ + { + "answerText": "fillColor", + "isCorrect": "false" + }, + { + "answerText": "fillStyle", + "isCorrect": "true" + }, + { + "answerText": "textAlign", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 38, + "title": "課程十九 - 太空遊戲 - 分數與性命數:課後測驗", + "quiz": [ + { + "questionText": "如何有趣地表現出玩家剩餘的性命數?", + "answerOptions": [ + { + "answerText": "剩餘艦艇的數字。", + "isCorrect": "false" + }, + { + "answerText": "得點系統。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "如何讓畫面裡 Canvas 元素上的文字置中?", + "answerOptions": [ + { + "answerText": "利用 Flexbox。", + "isCorrect": "false" + }, + { + "answerText": "讓文字的 x 座標點為玩家視窗寬度的一半。", + "isCorrect": "true" + }, + { + "answerText": "設定文字內容的 textAlign 屬性為 center。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "在程式碼中,用下列何者表示扣除一條性命?", + "answerOptions": [ + { + "answerText": "this.life-", + "isCorrect": "false" + }, + { + "answerText": "this.life--", + "isCorrect": "true" + }, + { + "answerText": "this.life++", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 39, + "title": "課程二十 - 太空遊戲 - 結束與重來:課前測驗", + "quiz": [ + { + "questionText": "何時為重新遊戲的最好時機?", + "answerOptions": [ + { + "answerText": "當玩家勝利或落敗時。", + "isCorrect": "true" + }, + { + "answerText": "任一時刻。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "什麼時候該讓遊戲結束?", + "answerOptions": [ + { + "answerText": "當單一敵人艦艇遭到擊毀。", + "isCorrect": "false" + }, + { + "answerText": "當玩家艦艇遭到擊毀。", + "isCorrect": "true" + }, + { + "answerText": "當分數進帳。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "最適合加入新關卡到遊戲的方式為:", + "answerOptions": [ + { + "answerText": "增加通關要求的分數門檻。", + "isCorrect": "true" + }, + { + "answerText": "增加更多的玩家。", + "isCorrect": "false" + }, + { + "answerText": "增加更好的圖像。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 40, + "title": "課程二十 - 太空遊戲 - 結束與重來:課後測驗", + "quiz": [ + { + "questionText": "當遊戲結束時,下列何者為合適的事件?", + "answerOptions": [ + { + "answerText": "顯示適當的訊息。", + "isCorrect": "false" + }, + { + "answerText": "結束遊戲。", + "isCorrect": "false" + }, + { + "answerText": "顯示適當的訊息,詢問玩家是否重來,顯示對應的選項按鈕。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "只有當遊戲結束時才能重新遊戲。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "當遊戲結束時,清除 EventEmitter 的合適方式是:", + "answerOptions": [ + { + "answerText": "清除事件監聽者。", + "isCorrect": "true" + }, + { + "answerText": "清除畫面。", + "isCorrect": "false" + }, + { + "answerText": "關閉遊戲視窗。", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 41, + "title": "課程二十一 - 銀行專案 - HTML模板與網路連線App:課前測驗", + "quiz": [ + { + "questionText": "一個網路程式必須要有多個HTML檔才能呈現不同頁面。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "網路程式允許用戶在本地儲存資料", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "什麼是網路程式資料供應者最合適的方式?", + "answerOptions": [ + { + "answerText": "一個本地資料庫。", + "isCorrect": "false" + }, + { + "answerText": "一個 JavaScript 物件。", + "isCorrect": "false" + }, + { + "answerText": "一個含有 JSON API 的伺服器。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 42, + "title": "課程二十一 - 銀行專案 - HTML模板與網路連線App:課後測驗", + "quiz": [ + { + "questionText": "HTML 模板在預設中是 DOM 元素的一部份。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "哪個 URL 部分需要被使用在路由上?", + "answerOptions": [ + { + "answerText": "window.location.pathname", + "isCorrect": "false" + }, + { + "answerText": "window.location.origin", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "當呼叫 history.pushState() 函式時,下列何者事件會被觸發?", + "answerOptions": [ + { + "answerText": "pushstate", + "isCorrect": "false" + }, + { + "answerText": "popstate", + "isCorrect": "true" + }, + { + "answerText": "navigate", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 43, + "title": "課程二十二 - 銀行專案 - 登入與註冊表單:課前測驗", + "quiz": [ + { + "questionText": "HTML 表單允許用戶不須利用 JavaScript 輸入資料到伺服器。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "<label> 元素在表單控制上是強制必要的。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "以 HTTP 傳送資料到伺服器是安全的。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 44, + "title": "課程二十二 - 銀行專案 - 登入與註冊表單:課後測驗", + "quiz": [ + { + "questionText": "利用 <label> 表單元素只為了表單的美觀。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "傳送給伺服器時,URL 會在表單的哪一個部分?", + "answerOptions": [ + { + "answerText": "Action 屬性。", + "isCorrect": "true" + }, + { + "answerText": "Method 屬性。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者屬性能決定文字輸入 <input> 的上限值?", + "answerOptions": [ + { + "answerText": "max", + "isCorrect": "false" + }, + { + "answerText": "maxlength", + "isCorrect": "true" + }, + { + "answerText": "pattern", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 45, + "title": "課程二十三 - 銀行專案 - 拿取與使用資料:課前測驗", + "quiz": [ + { + "questionText": "用戶通常會同步地利用瀏覽器向伺服器抓取資料。", + "answerOptions": [ + { + "answerText": "是,但非同步才是最好的!", + "isCorrect": "true" + }, + { + "answerText": "否", + "isCorrect": "false" + } + ] + }, + { + "questionText": "下列何者為最常見的網路交換資料格式?", + "answerOptions": [ + { + "answerText": "HTML", + "isCorrect": "false" + }, + { + "answerText": "XML", + "isCorrect": "false" + }, + { + "answerText": "JSON", + "isCorrect": "true" + } + ] + }, + { + "questionText": "沒有方法能阻止網頁存取供用伺服器的 API。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 46, + "title": "課程二十三 - 銀行專案 - 拿取與使用資料:課後測驗", + "quiz": [ + { + "questionText": "在單頁網頁應用中,HTML載入完後就不再更新。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + }, + { + "questionText": "為什麼阻止用戶輸入不信任的資料很重要?", + "answerOptions": [ + { + "answerText": "因為使用奇特字元讓 UI 變得很醜。", + "isCorrect": "false" + }, + { + "answerText": "因為它可能會包含無意義或攻擊性言論。", + "isCorrect": "false" + }, + { + "answerText": "因為它可以成為執行惡意程式的一種途徑。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "下列何者 API 可以向伺服器發出非同步 HTTP 請求?", + "answerOptions": [ + { + "answerText": "request()", + "isCorrect": "false" + }, + { + "answerText": "fetch()", + "isCorrect": "true" + }, + { + "answerText": "ajax()", + "isCorrect": "false" + } + ] + } + ] + }, + { + "id": 47, + "title": "課程二十四 - 銀行專案 - 狀態控管的概念:課前測驗", + "quiz": [ + { + "questionText": "什麼是不可變物件?", + "answerOptions": [ + { + "answerText": "物件被定義為常數。", + "isCorrect": "false" + }, + { + "answerText": "物件在建立後就不可以被修改。", + "isCorrect": "true" + }, + { + "answerText": "存在物件的複本。", + "isCorrect": "false" + } + ] + }, + { + "questionText": "狀態控管有什麼好處?", + "answerOptions": [ + { + "answerText": "可以追蹤到每一個狀態發生改變的位置。", + "isCorrect": "false" + }, + { + "answerText": "可以更容易地偵錯程式碼。", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "下列何者為最合適的方式來儲存不同 session 中重要的用戶資料?", + "answerOptions": [ + { + "answerText": "利用檔案。", + "isCorrect": "false" + }, + { + "answerText": "利用瀏覽器 LocalStorage API。", + "isCorrect": "false" + }, + { + "answerText": "利用伺服器 API 後的資料庫。", + "isCorrect": "true" + } + ] + } + ] + }, + { + "id": 48, + "title": "課程二十四 - 銀行專案 - 狀態控管的概念:課後測驗", + "quiz": [ + { + "questionText": "狀態管控的意義是?", + "answerOptions": [ + { + "answerText": "公權力的強制性。", + "isCorrect": "false" + }, + { + "answerText": "隨時間變化記錄用戶界面的狀態。", + "isCorrect": "false" + }, + { + "answerText": "讓用戶端的資料流清晰可控,保持資料和用戶界面的同步性。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "如何追蹤用戶 session 的狀態?", + "answerOptions": [ + { + "answerText": "HTTP cookies", + "isCorrect": "false" + }, + { + "answerText": "Local or session storage", + "isCorrect": "false" + }, + { + "answerText": "以上皆是。", + "isCorrect": "true" + } + ] + }, + { + "questionText": "改變物件一向是最佳的更新資訊方式。", + "answerOptions": [ + { + "answerText": "是", + "isCorrect": "false" + }, + { + "answerText": "否", + "isCorrect": "true" + } + ] + } + ] + } + ] + } +] diff --git a/5-browser-extension/1-about-browsers/images/sketchnote.jpg b/sketchnotes/browser.jpg similarity index 100% rename from 5-browser-extension/1-about-browsers/images/sketchnote.jpg rename to sketchnotes/browser.jpg diff --git a/1-getting-started-lessons/3-accessibility/webdev101-a11y.png b/sketchnotes/webdev101-a11y.png similarity index 100% rename from 1-getting-started-lessons/3-accessibility/webdev101-a11y.png rename to sketchnotes/webdev101-a11y.png diff --git a/3-terrarium/2-intro-to-css/images/webdev101-css.png b/sketchnotes/webdev101-css.png similarity index 100% rename from 3-terrarium/2-intro-to-css/images/webdev101-css.png rename to sketchnotes/webdev101-css.png diff --git a/1-getting-started-lessons/2-github-basics/images/webdev101-github.png b/sketchnotes/webdev101-github.png similarity index 100% rename from 1-getting-started-lessons/2-github-basics/images/webdev101-github.png rename to sketchnotes/webdev101-github.png diff --git a/3-terrarium/1-intro-to-html/images/webdev101-html.png b/sketchnotes/webdev101-html.png similarity index 100% rename from 3-terrarium/1-intro-to-html/images/webdev101-html.png rename to sketchnotes/webdev101-html.png diff --git a/2-js-basics/4-arrays-loops/images/webdev101-js-arrays.png b/sketchnotes/webdev101-js-arrays.png similarity index 100% rename from 2-js-basics/4-arrays-loops/images/webdev101-js-arrays.png rename to sketchnotes/webdev101-js-arrays.png diff --git a/2-js-basics/1-data-types/images/webdev101-js-datatypes.png b/sketchnotes/webdev101-js-datatypes.png similarity index 100% rename from 2-js-basics/1-data-types/images/webdev101-js-datatypes.png rename to sketchnotes/webdev101-js-datatypes.png diff --git a/sketchnotes/webdev101-js-decisions.png b/sketchnotes/webdev101-js-decisions.png new file mode 100644 index 00000000..57f22ebd Binary files /dev/null and b/sketchnotes/webdev101-js-decisions.png differ diff --git a/2-js-basics/2-functions-methods/images/webdev101-js-functions.png b/sketchnotes/webdev101-js-functions.png similarity index 100% rename from 2-js-basics/2-functions-methods/images/webdev101-js-functions.png rename to sketchnotes/webdev101-js-functions.png diff --git a/3-terrarium/3-intro-to-DOM-and-closures/images/webdev101-js.png b/sketchnotes/webdev101-js.png similarity index 100% rename from 3-terrarium/3-intro-to-DOM-and-closures/images/webdev101-js.png rename to sketchnotes/webdev101-js.png diff --git a/1-getting-started-lessons/1-intro-to-programming-languages/webdev101-programming.png b/sketchnotes/webdev101-programming.png similarity index 100% rename from 1-getting-started-lessons/1-intro-to-programming-languages/webdev101-programming.png rename to sketchnotes/webdev101-programming.png diff --git a/translations/for-teachers.fr.md b/translations/for-teachers.fr.md new file mode 100644 index 00000000..41bbfed5 --- /dev/null +++ b/translations/for-teachers.fr.md @@ -0,0 +1,23 @@ +## Pour les éducateurs + +Souhaitez-vous utiliser ce programme dans votre classe? N'hésitez pas! + +En fait, vous pouvez l'utiliser dans GitHub lui-même en utilisant GitHub Classroom. + +Pour ce faire, forkez ce repo. Vous allez devoir créer un référentiel pour chaque leçon, vous devrez donc extraire chaque dossier dans un référentiel distinct. De cette façon, [Classe GitHub](https://classroom.github.com/classrooms) peut prendre chaque leçon séparément. + +Ceux-ci [instructions complètes](https://github.blog/2020-03-18-set-up-your-digital-classroom-with-github-classroom/) vous donnera une idée de la configuration de votre classe. + +## Utiliser le repo tel quel + +Si vous souhaitez utiliser ce dépôt tel qu'il est actuellement, sans utiliser GitHub Classroom, cela peut également être fait. Vous auriez besoin de communiquer avec vos élèves sur quelle leçon travailler ensemble. + +Dans un format en ligne (Zoom, Teams ou autre), vous pouvez créer des ateliers pour les quiz et encadrer les étudiants pour les aider à se préparer à apprendre. Invitez ensuite les élèves à participer aux quiz et soumettez leurs réponses sous forme de «problèmes» à un moment donné. Vous pouvez faire de même avec les devoirs, si vous voulez que les étudiants travaillent en collaboration en plein air. + +Si vous préférez un format plus privé, demandez à vos élèves de convertir le programme, cours par cours, vers leurs propres dépôts GitHub en tant que dépôts privés, et vous donner accès. Ensuite, ils peuvent remplir des quiz et des devoirs en privé et vous les soumettre via des problèmes sur votre référentiel de classe. + +Il existe de nombreuses façons de faire fonctionner cela dans un format de classe en ligne. Veuillez nous indiquer ce qui fonctionne le mieux pour vous! + +## Veuillez nous donner votre avis! + +Nous voulons que ce programme fonctionne pour vous et vos étudiants. Veuillez nous donner [feedback](https://forms.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR2humCsRZhxNuI79cm6n0hRUQzRVVU9VVlU5UlFLWTRLWlkyQUxORTg5WS4u). diff --git a/translations/for-teachers.pl.md b/translations/for-teachers.pl.md new file mode 100644 index 00000000..75f633fd --- /dev/null +++ b/translations/for-teachers.pl.md @@ -0,0 +1,23 @@ +## Dla nauczycieli + +Czy chciałbyś skorzystać z tego programu nauczania w swojej klasie? Nie krępuj się! + +W rzeczywistości możesz go używać w samym GitHubie, korzystając z GitHub Classroom. + +Aby to zrobić, zrób forka tego repozytorium. Będziesz musiał utworzyć repozytorium dla każdej lekcji, więc będziesz musiał wyodrębnić każdy folder do osobnego repozytorium. W ten sposób [GitHub Classroom](https://classroom.github.com/classrooms) może odebrać każdą lekcję oddzielnie. + +Te [pełne instrukcje](https://github.blog/2020-03-18-set-up-your-digital-classroom-with-github-classroom/) dadzą ci pomysł, jak skonfigurować klasę. + +## Używanie repozytorium bez zmian + +Jeśli chcesz korzystać z tego repozytorium w obecnej postaci, bez korzystania z GitHub Classroom, również możesz to zrobić. Będziesz musiał komunikować się ze swoimi uczniami, którą lekcję wspólnie przepracować. + +W formacie online (Zoom, Teams lub inny) możesz tworzyć sale do quizów i mentorować uczniów, aby pomóc im przygotować się do nauki. Następnie poproś uczniów o udział w quizach i przedstaw ich odpowiedzi jako „issues” w określonym czasie. To samo możesz zrobić z zadaniami, jeśli chcesz, aby uczniowie wspólnie pracowali w otwartej przestrzeni. + +Jeśli wolisz bardziej prywatny format, poproś uczniów, aby podzielili program nauczania, lekcja po lekcji, na ich własne repozytoria GitHub jako prywatne repozytoria i aby przyznali ci dostęp. Następnie mogą prywatnie wypełniać quizy i zadania, i przesyłać je do ciebie za pośrednictwem issues w repozytorium klasy. + +Istnieje wiele sposobów, aby to zadziałało w klasie online. Daj nam znać, co jest dla ciebie najlepsze! + +## Przekaż nam swoje przemyślenia! + +Chcemy, aby ten program nauczania działał dla ciebie i twoich uczniów. Prześlij nam [opinię](https://forms.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR2humCsRZhxNuI79cm6n0hRUQzRVVU9VVlU5UlFLWTRLWlkyQUxORTg5WS4u). diff --git a/translations/for-teachers.zh-cn.md b/translations/for-teachers.zh-cn.md new file mode 100644 index 00000000..4148dda7 --- /dev/null +++ b/translations/for-teachers.zh-cn.md @@ -0,0 +1,23 @@ +## 写给教育工作者 + +你想要在你的课堂上使用这门课程吗?请随意使用! + +事实上,你可以通过使用 GitHub Classroom 来直接在 GitHub 中使用这门课。 + +要做到这一点,需要先复刻(fork)这个仓库。你需要对每一节课都创建一个仓库,所以需要将每一个文件夹单独提出来分别放到各个仓库中。这样一来,[GitHub Classroom](https://classroom.github.com/classrooms) 就可以分开选择各节课程。 + +这个[完整指南](https://github.blog/2020-03-18-set-up-your-digital-classroom-with-github-classroom/)将会告诉你如何建立你的教室。 + +## 原样使用这个仓库 + +如果比起 GitHub Classroom 你更愿意直接按现在这个样子使用该仓库,也是没问题的。你需要去告知学生现在该去看哪一节课。 + +在网络授课的情况下(如 Zoom、Teams 等)你可能需要建立一些分组讨论室来进行小测和指导学生,以帮助他们做好学习准备。然后邀请学生参加小测,并且在特定时间点以 Issues 的形式提交他们的答案。对于作业也可以这么做,前提是你希望学生们可以在作业上公开协作提交结果。 + +如果你倾向于更加非公开的形式,可以让你的学生分节次 Fork 这门课程到他们自己的 GitHub 仓库中,并且设为私有(private),然后给你访问权限。这样他们就可以在他们自己的仓库私下完成小测和作业,然后通过你的课堂仓库以 Issues 的形式提交给你。 + +有许多办法让这门课变成网络课堂的形式,如果你感觉某种方式非常棒,请告诉我们! + +## 请告诉我们你的想法! + +我们希望可以让这门课程对你和你的学生有所帮助。欢迎[反馈](https://forms.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR2humCsRZhxNuI79cm6n0hRUQzRVVU9VVlU5UlFLWTRLWlkyQUxORTg5WS4u)。