mirror of
https://github.com/microsoft/Web-Dev-For-Beginners.git
synced 2025-09-09 06:00:51 +02:00
ADD : add korean readme skeleton file
This commit is contained in:
231
3-terrarium/1-intro-to-html/translations/README.ko.md
Normal file
231
3-terrarium/1-intro-to-html/translations/README.ko.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# Terrarium Project Part 1: Introduction to HTML
|
||||
|
||||

|
||||
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Pre-Lecture Quiz
|
||||
|
||||
[Pre-lecture quiz](.github/pre-lecture-quiz.md)
|
||||
|
||||
### Introduction
|
||||
|
||||
HTML, or HyperText Markup Language, is the 'skeleton' of the web. If CSS 'dresses up' your HTML and JavaScript brings it to life, HTML is the body of your web application. HTML's syntax even reflects that idea, as it includes "head", "body", and "footer" tags.
|
||||
|
||||
In this lesson, we're going to use HTML to layout the 'skeleton' of our virtual terrarium's interface. It will have a title and three columns: a right and a left column where the draggable plants live, and a center area that will be the actual glass-looking terrarium. By the end of this lesson, you will be able to see the plants in the columns, but the interface will look a little strange; don't worry, in the next section you will add CSS styles to the interface to make it look better.
|
||||
|
||||
### Task
|
||||
|
||||
On your computer, create a folder called 'terrarium' and inside it, a file called 'index.html'. You can do this in Visual Studio Code after you create your terrarium folder by opening a new VS Code window, clicking 'open folder', and navigating to your new folder. Click the small 'file' button in the Explorer pane and create the new file:
|
||||
|
||||

|
||||
|
||||
Or
|
||||
|
||||
Use these commands on your git bash:
|
||||
* `mkdir terrarium`
|
||||
* `cd terrarium`
|
||||
* `touch index.html`
|
||||
* `code index.html` or `nano index.html`
|
||||
|
||||
> index.html files indicate to a browser that it is the default file in a folder; URLs such as `https://anysite.com/test` might be built using a folder structure including a folder called `test` with `index.html` inside it; `index.html` doesn't have to show in a URL.
|
||||
|
||||
---
|
||||
|
||||
## The DocType and html tags
|
||||
|
||||
The first line of an HTML file is its doctype. It's a little surprising that you need to have this line at the very top of the file, but it tells older browsers that the browser needs to render the page in a standard mode, following the current html specification.
|
||||
|
||||
> Tip: in VS Code, you can hover over a tag and get information about its use from the MDN Reference guides.
|
||||
|
||||
The second line should be the `<html>` tag's opening tag, followed right now by its closing tag `</html>`. These tags are the root elements of your interface.
|
||||
|
||||
### Task
|
||||
|
||||
Add these lines at the top of your `index.html` file:
|
||||
|
||||
```HTML
|
||||
<!DOCTYPE html>
|
||||
<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.
|
||||
|
||||
---
|
||||
|
||||
## 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 page's title
|
||||
- page metadata including:
|
||||
- the 'character set', telling about what character encoding is used in the page
|
||||
- browser information, including `x-ua-compatible` which indicates that the IE=edge browser is supported
|
||||
- information about how the viewport should behave when it is loaded. Setting the viewport to have an initial scale of 1 controls the zoom level when the page is first loaded.
|
||||
|
||||
### Task
|
||||
|
||||
Add a 'head' block to your document in between the opening and closing `<html>` tags.
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
✅ 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).
|
||||
|
||||
---
|
||||
|
||||
## The document's `body`
|
||||
|
||||
### HTML Tags
|
||||
|
||||
In HTML, you add tags to your .html file to create elements of a web page. Each tag usually has an opening and closing tag, like this: `<p>hello</p>` to indicate a paragraph. Create your interface's body by adding a set of `<body>` tags inside the `<html>` tag pair; your markup now looks like this:
|
||||
|
||||
### Task
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
Now, you can start building out your page. Normally, you use `<div>` tags to create the separate elements in a page. We'll create a series of `<div>` elements which will contain images.
|
||||
|
||||
### Images
|
||||
|
||||
One html tag that doesn't need a closing tag is the `<img>` tag, because it has a `src` element that contains all the information the page needs to render the item.
|
||||
|
||||
Create a folder in your app called `images` and in that, add all the images in the [source code folder](../images); (there are 14 images of plants).
|
||||
|
||||
### Task
|
||||
|
||||
Add those plant images into two columns between the `<body></body>` tags:
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
> Note: Spans vs. Divs. Divs are considered 'block' elements, and Spans are 'inline'. What would happen if you transformed these divs to spans?
|
||||
|
||||
With this markup, the plants now show up on the screen. It looks pretty bad, because they aren't yet styled using CSS, and we'll do that in the next lesson.
|
||||
|
||||
Each image has an alt tag that will appear even if you can't see or render an image. This is an important element to include for accessibility. Learn more about accessibility in future lessons; for now, remember that the alt attribute provides alternative information for an image if a user for some reason cannot view it (because of slow connection, an error in the src attribute, or if the user uses a screen reader).
|
||||
|
||||
✅ Did you notice that each image has the same alt tag? Is this good practice? Why or why not? Can you improve this code?
|
||||
|
||||
---
|
||||
|
||||
## Semantic markup
|
||||
|
||||
In general, it's preferable to use 'semantics' when writing HTML. What does that mean? It means that you use HTML tags the way they were designed: to represent its data; so an H1 tag should always be present on a page
|
||||
|
||||
Add the following line right below your opening `<body>` tag:
|
||||
|
||||
```html
|
||||
<h1>My Terrarium</h1>
|
||||
```
|
||||
|
||||
Using semantic markup such as having headers be `<h1>` and unordered lists be rendered as `<ul>` helps screen readers navigate through a page. In general, buttons should be written as `<button>` and lists should be `<li>`. While it's _possible_ to use specially styled `<span>` elements with click handlers to mock buttons, it's better for differently-abled users to use technologies to determine where on a page a button resides, and to interact with it, if the element appears as a button. For this reason, try to use semantic markup as much as possible.
|
||||
|
||||
✅ Take a look at a screen reader and [how it interacts with a web page](https://www.youtube.com/watch?v=OUDV1gqs9GA). Can you see why having non semantic markup might confuse the user?
|
||||
|
||||
## The terrarium
|
||||
|
||||
The last part of this interface involves creating markup that will be styled to create a terrarium.
|
||||
|
||||
### Task:
|
||||
|
||||
Add this markup above the last `</div>` tag:
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
✅ Even though you added this markup to the screen, you see absolutely nothing render. Why?
|
||||
|
||||
---
|
||||
|
||||
## 🚀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) 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
|
||||
|
||||
[Post-lecture quiz](.github/post-lecture-quiz.md)
|
||||
|
||||
## Review & Self Study
|
||||
|
||||
HTML is the 'tried and true' building block system that has helped build the web into what it is today. Learn a little about its history by studying some old and new tags. Can you figure out why some tags were deprecated and some added? What tags might be introduced in the future?
|
||||
|
||||
Learn more about building sites for the web and mobile devices at [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=cxaall-4621-cxall).
|
||||
|
||||
|
||||
## Assignment
|
||||
|
||||
[Practice your HTML: Build a blog mockup](assignment.md)
|
263
3-terrarium/2-intro-to-css/translations/README.ko.md
Normal file
263
3-terrarium/2-intro-to-css/translations/README.ko.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Terrarium Project Part 2: Introduction to CSS
|
||||
|
||||

|
||||
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Pre-Lecture Quiz
|
||||
|
||||
[Pre-lecture quiz](.github/pre-lecture-quiz.md)
|
||||
|
||||
### Introduction
|
||||
|
||||
CSS, or Cascading Style Sheets, solve an important problem of web development: how to make your web site look nice. Styling your apps makes them more usable and nicer-looking; you can also use CSS to create Responsive Web Design (RWD) - allowing your apps to look good no matter what screen size they are displayed on. CSS is not only about making your app look nice; its spec includes animations and transforms that can enable sophisticated interactions for your apps. The CSS Working Group helps maintain current CSS specifications; you can follow their work at [World Wide Web Consortium's site](https://www.w3.org/Style/CSS/members).
|
||||
|
||||
> Note, CSS is a language that evolves, like everything on the web, and not all browsers support newer parts of the specification. Always check your implementations by consulting [CanIUse.com](caniuse.com).
|
||||
|
||||
In this lesson, we're going to add styles to our online terrarium and learn more about several CSS concepts: the cascade, inheritance, and the use of selectors, positioning, and using CSS to build layouts. In the process we will layout the terrarium and create the actual terrarium itself.
|
||||
|
||||
### Prequisite
|
||||
|
||||
You should have the HTML for your terrarium built and ready to be styled.
|
||||
|
||||
### Task
|
||||
|
||||
In your terrarium folder, create a new file called `style.css`. Import that file in the `<head>` section:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The Cascade
|
||||
|
||||
Cascading Style Sheets incorporate the idea that the styles 'cascade' such that the application of a style is guided by its priority. Styles set by a web site author take priority over those set by a browser. Styles set 'inline' take priority over those set in an external style sheet.
|
||||
|
||||
### Task
|
||||
|
||||
Add the inline style "color: red" to your `<h1>` tag:
|
||||
|
||||
```HTML
|
||||
<h1 style="color: red">My Terrarium</h1>
|
||||
```
|
||||
|
||||
Then, add the following code to your `style.css` file:
|
||||
|
||||
```CSS
|
||||
h1 {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
✅ Which color displays in your web app? Why? Can you find a way to override styles? When would you want to do this, or why not?
|
||||
|
||||
---
|
||||
|
||||
## Inheritance
|
||||
|
||||
Styles are inherited from an ancestor style to a descendent, such that nested elements inherit the styles of their parents.
|
||||
|
||||
### Task
|
||||
|
||||
Set the body's font to a given font, and check to see a nested element's font:
|
||||
|
||||
```
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
Open your browser's console to the 'Elements' tab and observe the H1's font. It inherits its font from the body, as stated within the browser:
|
||||
|
||||

|
||||
|
||||
✅ Can you make a nested style inherit a different property?
|
||||
|
||||
---
|
||||
|
||||
## CSS Selectors
|
||||
|
||||
### Tags
|
||||
|
||||
So far, your `style.css` file has only a few tags styled, and the app looks pretty strange:
|
||||
|
||||
```
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #3a241d;
|
||||
text-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
This way of styling a tag gives you control over unique elements, but you need to control the styles of many plants in your terrarium. To do that, you need to leverage CSS selectors.
|
||||
|
||||
### Ids
|
||||
|
||||
Add some style to layout the left and right containers. Since there is only one left container and only one right container, they are given ids in the markup. To style them, use `#`:
|
||||
|
||||
```
|
||||
#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;
|
||||
}
|
||||
```
|
||||
|
||||
Here, you have placed these containers with absolute positioning to the far left and right of the screen, and used percentages for their width so that they can scale for small mobile screens.
|
||||
|
||||
✅ This code is quite repeated, thus not "DRY" (Don't Repeat Yourself); can you find a better way to style these ids, perhaps with an id and a class? You would need to change the markup and refactor the CSS:
|
||||
|
||||
```html
|
||||
<div id="left-container" class="container"></div>
|
||||
```
|
||||
|
||||
### Classes
|
||||
|
||||
In the example above, you styled two unique elements on the screen. If you want styles to apply to many elements on the screen, you can use CSS classes. Do this to layout the plants in the left and right containers.
|
||||
|
||||
Notice that each plant in the HTML markup has a combination of ids and classes. The ids here are used by the JavaScript that you will add later to manipulate the terrarium plant placement. The classes, however, give all the plants a given style.
|
||||
|
||||
```html
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
|
||||
</div>
|
||||
```
|
||||
|
||||
Add the following to your `style.css` file:
|
||||
|
||||
```css
|
||||
.plant-holder {
|
||||
position: relative;
|
||||
height: 13%;
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
.plant {
|
||||
position: absolute;
|
||||
max-width: 150%;
|
||||
max-height: 150%;
|
||||
z-index: 2;
|
||||
}
|
||||
```
|
||||
|
||||
Notable in this snippet is the mixture of relative and absolute positioning, which we'll cover in the next section. Take a look at the way heights are handled by percentages:
|
||||
|
||||
You set the height of the plant holder to 13%, a good number to ensure that all the plants are displayed in each vertical container without need for scrolling.
|
||||
|
||||
You set the plant holder to move to the left to allow the plants to be more centered within their container. The images have a large amount of transparent background so as to make them more draggable, so need to be pushed to the left to fit better on the screen.
|
||||
|
||||
Then, the plant itself is given a max-width of 150%. This allows it to scale down as the browser scales down. Try resizing your browser; the plants stay in their containers but scale down to fit.
|
||||
|
||||
Also notable is the use of z-index, which controls the relative altitude of an element (so that the plants sit on top of the container and appear to sit inside the terrarium).
|
||||
|
||||
✅ Why do you need both a plant holder and a plant CSS selector?
|
||||
|
||||
## CSS Positioning
|
||||
|
||||
Mixing position properties (there are static, relative, fixed, absolute, and sticky positions) can be a little tricky, but when done properly it gives you good control over the elements on your pages.
|
||||
|
||||
Absolute positioned elements are positioned relative to their nearest positioned ancestors, and if there are none, it is positioned according to the document body.
|
||||
|
||||
Relative positioned elements are positioned based on the CSS's directions to adjust its placement away from its initial position.
|
||||
|
||||
In our sample, the `plant-holder` is a relative-positioned element that is positioned within an absolute-positioned container. The resultant behavior is that the side bar containers are pinned left and right, and the plant-holder is nested, adjusting itself within the side bars, giving space for the plants to be placed in a vertical row.
|
||||
|
||||
> The `plant` itself also has absolute positioning, necessary to making it draggable, as you will discover in the next lesson.
|
||||
|
||||
✅ Experiment with switching the types of positioning of the side containers and the plant-holder. What happens?
|
||||
|
||||
## CSS Layouts
|
||||
|
||||
Now you will use what you learned to build the terrarium itself, all using CSS!
|
||||
|
||||
First, style the `.terrarium` div children as a rounded rectangle using CSS:
|
||||
|
||||
```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;
|
||||
}
|
||||
```
|
||||
|
||||
Note the use of percentages here, even for the `border-radius`. If you scale your browser down, you can see how the jar corners scale as well. Also notice the widths and height percentages for the jar elements and how each element is absolutely positioned in the center, pinned to the bottom of the viewport.
|
||||
|
||||
✅ Try changing the jar colors and opacity vs. those of the dirt. What happens? Why?
|
||||
|
||||
---
|
||||
|
||||
## 🚀Challenge
|
||||
|
||||
Add a 'bubble' shine to the left bottom area of the jar to make it look more glasslike. You will be styling the `.jar-glossy-long` and `.jar-glossy-short` to look like a reflected shine. Here's how it would look:
|
||||
|
||||

|
||||
|
||||
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)
|
||||
|
||||
## Post-Lecture Quiz
|
||||
|
||||
[Post-lecture quiz](.github/post-lecture-quiz.md)
|
||||
|
||||
## Review & Self Study
|
||||
|
||||
CSS seems deceptively straightforward, but there are many challenges when trying to style an app perfectly for all browsers and all screen sizes. CSS-Grid and Flexbox are tools that have been developed to make the job a little more structured and more reliable. Learn about these tools by playing [Flexbox Froggy](https://flexboxfroggy.com/) and [Grid Garden](https://codepip.com/games/grid-garden/).
|
||||
|
||||
## Assignment
|
||||
|
||||
[CSS Refactoring](assignment.md)
|
@@ -0,0 +1,215 @@
|
||||
# Terrarium Project Part 3: DOM Manipulation and a Closure
|
||||
|
||||

|
||||
> Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Pre-Lecture Quiz
|
||||
|
||||
[Pre-lecture quiz](.github/pre-lecture-quiz.md)
|
||||
|
||||
### 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!
|
||||
|
||||
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.
|
||||
|
||||
We will use a closure to manipulate the DOM.
|
||||
|
||||
> Think of the DOM as a tree, representing all the ways that a web page document can be manipulated. Various APIs (Application Program Interfaces) have been written so that programmers, using their programming language of choice, can access the DOM and edit, change, rearrange, and otherwise manage it.
|
||||
|
||||

|
||||
|
||||
> A representation of the DOM and the HTML markup that references it. From [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
|
||||
|
||||
In this lesson, we will complete our interactive terrarium project by creating the JavaScript that will allow a user to manipulate the plants on the page.
|
||||
|
||||
### Prequisite
|
||||
|
||||
You should have the HTML and CSS for your terrarium built. By the end of this lesson you will be able to move the plants into and out of the terrarium by dragging them.
|
||||
|
||||
### Task
|
||||
|
||||
In your terrarium folder, create a new file called `script.js`. Import that file in the `<head>` section:
|
||||
|
||||
```html
|
||||
<script src="./script.js" defer></script>
|
||||
```
|
||||
|
||||
> Note: use `defer` when importing an external JavaScript file into the html file so as to allow the JavaScript to execute only after the HTML file has been fully loaded. You could also use the `async` attribute, which allows the script to execute while the HTML file is parsing, but in our case, it's important to have the HTML elements fully available for dragging before we allow the drag script to be executed.
|
||||
---
|
||||
|
||||
## The DOM elements
|
||||
|
||||
The first thing you need to do is to create references to the elements that you want to manipulate in the DOM. In our case, they are the 14 plants currently waiting in the side bars.
|
||||
|
||||
### Task
|
||||
|
||||
```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'));
|
||||
```
|
||||
|
||||
What's going on here? You are referencing the document and looking through its DOM to find an element with a particular Id. Remember in the first lesson on HTML that you gave individual Ids to each plant image (`id="plant1"`)? Now you will make use of that effort. After identifying each element, you pass that item to a function called `dragElement` that you'll build in a minute. Thus, the element in the HTML is now drag-enabled, or will be shortly.
|
||||
|
||||
✅ Why do we reference elements by Id? Why not by their CSS class? You might refer to the previous lesson on CSS to answer this question.
|
||||
|
||||
---
|
||||
|
||||
## The Closure
|
||||
|
||||
Now you are ready to create the dragElement closure, which is an outer function that encloses an inner function or functions (in our case, we will have three).
|
||||
|
||||
Closures are useful when one or more functions need to access an outer function's scope. Here's an example:
|
||||
|
||||
```javascript
|
||||
function displayCandy(){
|
||||
let candy = ['jellybeans'];
|
||||
function addCandy(candyType) {
|
||||
candy.push(candyType)
|
||||
}
|
||||
addCandy('gumdrops');
|
||||
}
|
||||
displayCandy();
|
||||
console.log(candy)
|
||||
```
|
||||
|
||||
In this example, the displayCandy function surrounds a function that pushes a new candy type into an array that already exists in the function. If you were to run this code, the `candy` array would be undefined, as it is a local variable (local to the closure).
|
||||
|
||||
✅ How can you make the `candy` array accessible? Try moving it outside the closure. This way, the array becomes global, rather than remaining only available to the closure's local scope.
|
||||
|
||||
### Task
|
||||
|
||||
Under the element declarations in `script.js`, create a function:
|
||||
|
||||
```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` 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.
|
||||
|
||||
✅ 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 Pointerdrag function
|
||||
|
||||
The terrariumElement is ready to be dragged around; when the `onpointerdown` event is fired, the function pointerDrag is invoked. Add that function right under this line: `terrariumElement.onpointerdown = pointerDrag;`:
|
||||
|
||||
### Task
|
||||
|
||||
```javascript
|
||||
function pointerDrag(e) {
|
||||
e.preventDefault();
|
||||
console.log(e);
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
}
|
||||
```
|
||||
|
||||
Several things happen. First, you prevent the default events that normally happen on pointerdown from occurring by using `e.preventDefault();`. This way you have more control over the interface's behavior.
|
||||
|
||||
> Come back to this line when you've built the script file completely and try it without `e.preventDefault()` - what happens?
|
||||
|
||||
Second, open `index.html` in a browser window, and inspect the interface. When you click a plant, you can see how the 'e' event is captured. Dig into the event to see how much information is gathered by one pointer down event!
|
||||
|
||||
Next, note how the local variables `pos3` and `pos4` are set to e.clientX. You can find the `e` values in the inspection pane. These values capture the x and y coordinates of the plant at the moment you click on it or touch it. You will need fine-grained control over the behavior of the plants as you click and drag them, so you keep track of their coordinates.
|
||||
|
||||
✅ Is it becoming more clear why this entire app is built with one big closure? If it wasn't, how would you maintain scope for each of the 14 draggable plants?
|
||||
|
||||
Complete the initial function by adding two more pointer event manipulations under `pos4 = e.clientY`:
|
||||
|
||||
```html
|
||||
document.onpointermove = elementDrag;
|
||||
document.onpointerup = stopElementDrag;
|
||||
```
|
||||
Now you are indicating that you want the plant to be dragged along with the pointer as you move it, and for the dragging gesture to stop when you deselect the plant. `onpointermove` and `onpointerup` are all parts of the same API as `onpointerdown`. The interface will throw errors now as you have not yet defined the `elementDrag` and the `stopElementDrag` functions, so build those out next.
|
||||
|
||||
## The elementDrag and stopElementDrag functions
|
||||
|
||||
You will complete your closure by adding two more internal functions that will handle what happens when you drag a plant and stop dragging it. The behavior you want is that you can drag any plant at any time and place it anywhere on the screen. This interface is quite un-opinionated (there is no drop zone for example) to allow you to design your terrarium exactly as you like it by adding, removing, and repositioning plants.
|
||||
|
||||
### Task
|
||||
|
||||
Add the `elementDrag` function right after the closing curly bracket of `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';
|
||||
}
|
||||
```
|
||||
In this function, you do a lot of editing of the initial positions 1-4 that you set as local variables in the outer function. What's going on here?
|
||||
|
||||
As you drag, you reassign `pos1` by making it equal to `pos3` (which you set earlier as `e.clientX`) minus the current `e.clientX` value. You do a similar operation to `pos2`. Then, you reset `pos3` and `pos4` to the new X and Y coordinates of the element. You can watch these changes in the console as you drag. Then, you manipulate the plant's css style to set its new position based on the new positions of `pos1` and `pos2`, calculating the plant's top and left X and Y coordinates based on comparing its offset with these new positions.
|
||||
|
||||
> `offsetTop` and `offsetLeft` are CSS properties that set an element's position based on that of its parent; its parent can be any element that is not positioned as `static`.
|
||||
|
||||
All this recalculation of positioning allows you to fine-tune the behavior of the terrarium and its plants.
|
||||
|
||||
### Task
|
||||
|
||||
The final task to complete the interface is to add the `closeElementDrag` function after the closing curly bracket of `elementDrag`:
|
||||
|
||||
```javascript
|
||||
function stopElementDrag() {
|
||||
document.onpointerup = null;
|
||||
document.onpointermove = null;
|
||||
}
|
||||
```
|
||||
|
||||
This small function resets the `onpointerup` and `onpointermove` events so that you can either restart your plant's progress by starting to drag it again, or start dragging a new plant.
|
||||
|
||||
✅ What happens if you don't set these events to null?
|
||||
|
||||
Now you have completed your project!
|
||||
|
||||
🥇Congratulations! You have finished your beautiful terrarium. 
|
||||
|
||||
---
|
||||
|
||||
## 🚀Challenge
|
||||
|
||||
Add new event handler to your closure to do something more to the plants; for example, double-click a plant to bring it to the front. Get creative!
|
||||
|
||||
## Post-Lecture Quiz
|
||||
|
||||
[Post-lecture quiz](.github/post-lecture-quiz.md)
|
||||
|
||||
## 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.
|
||||
|
||||
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).
|
||||
|
||||
Always check browser capabilities using [CanIUse.com](https://caniuse.com/).
|
||||
|
||||
## Assignment
|
||||
|
||||
[Work a bit more with the DOM](assignment.md)
|
||||
|
34
3-terrarium/translations/README.ko.md
Normal file
34
3-terrarium/translations/README.ko.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# My Terrarium: A project to learn about HTML, CSS, and DOM manipulation using JavaScript 🌵🌱
|
||||
|
||||
A small drag and drop code-meditation. With a little HTML, JS and CSS, you can build a web interface, style it, and add an interaction.
|
||||
|
||||

|
||||
|
||||
# Lessons
|
||||
|
||||
1. [Intro to HTML](./1-intro-to-html/README.md)
|
||||
2. [Intro to CSS](./2-intro-to-css/README.md)
|
||||
3. [Intro to DOM and JS Closures](./3-intro-to-DOM-and-closures/README.md)
|
||||
|
||||
## Credits
|
||||
|
||||
Written with ♥️ by [Jen Looper](https://www.twitter.com/jenlooper)
|
||||
|
||||
The terrarium created via CSS was inspired by Jakub Mandra's glass jar [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY).
|
||||
|
||||
The artwork was hand drawn by [Jen Looper](http://jenlooper.com) using Procreate.
|
||||
|
||||
## Deploy your Terrarium
|
||||
|
||||
You can deploy, or publish your terrarium to the web using Azure Static Web Apps.
|
||||
|
||||
1. Fork this repo
|
||||
|
||||
2. Press this button
|
||||
|
||||
[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=cxaall-4621-cxall#create/Microsoft.StaticApp)
|
||||
|
||||
3. Walk through the wizard creating your app. Make sure you set the app root to either be `/solution` or the root of your codebase. There's no API in this app, so don't worry about adding that. A .github folder will be created in your forked repo that will help Azure Static Web Apps' build service build and publish your app to a new URL.
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user