-
Notifications
You must be signed in to change notification settings - Fork 35
[미션] Fetch #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[미션] Fetch #155
Changes from all commits
10008c8
cbe9654
b481dd1
38aa4e7
6ba14ed
9c1d78d
4a2b895
6046298
166cd89
b82e169
cbe1e04
590f8ae
b708cf6
77f7ebe
9738e81
69f14af
e82d1ab
3083758
e452111
ccc1745
276d08c
6698e3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
|
|
||
| # Created by https://www.gitignore.io/api/node | ||
| # Edit at https://www.gitignore.io/?templates=node | ||
|
|
||
| ### Node ### | ||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| lerna-debug.log* | ||
|
|
||
| # Diagnostic reports (https://nodejs.org/api/report.html) | ||
| report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
|
||
| # Runtime data | ||
| pids | ||
| *.pid | ||
| *.seed | ||
| *.pid.lock | ||
|
|
||
| # Directory for instrumented libs generated by jscoverage/JSCover | ||
| lib-cov | ||
|
|
||
| # Coverage directory used by tools like istanbul | ||
| coverage | ||
| *.lcov | ||
|
|
||
| # nyc test coverage | ||
| .nyc_output | ||
|
|
||
| # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
| .grunt | ||
|
|
||
| # Bower dependency directory (https://bower.io/) | ||
| bower_components | ||
|
|
||
| # node-waf configuration | ||
| .lock-wscript | ||
|
|
||
| # Compiled binary addons (https://nodejs.org/api/addons.html) | ||
| build/Release | ||
|
|
||
| # Dependency directories | ||
| node_modules/ | ||
| jspm_packages/ | ||
|
|
||
| # TypeScript v1 declaration files | ||
| typings/ | ||
|
|
||
| # TypeScript cache | ||
| *.tsbuildinfo | ||
|
|
||
| # Optional npm cache directory | ||
| .npm | ||
|
|
||
| # Optional eslint cache | ||
| .eslintcache | ||
|
|
||
| # Optional REPL history | ||
| .node_repl_history | ||
|
|
||
| # Output of 'npm pack' | ||
| *.tgz | ||
|
|
||
| # Yarn Integrity file | ||
| .yarn-integrity | ||
|
|
||
| # dotenv environment variables file | ||
| .env | ||
| .env.test | ||
|
|
||
| # parcel-bundler cache (https://parceljs.org/) | ||
| .cache | ||
|
|
||
| # next.js build output | ||
| .next | ||
|
|
||
| # nuxt.js build output | ||
| .nuxt | ||
|
|
||
| # rollup.js default build output | ||
| dist/ | ||
|
|
||
| # Uncomment the public line if your project uses Gatsby | ||
| # https://nextjs.org/blog/next-9-1#public-directory-support | ||
| # https://create-react-app.dev/docs/using-the-public-folder/#docsNav | ||
| # public | ||
|
|
||
| # Storybook build outputs | ||
| .out | ||
| .storybook-out | ||
|
|
||
| # vuepress build output | ||
| .vuepress/dist | ||
|
|
||
| # Serverless directories | ||
| .serverless/ | ||
|
|
||
| # FuseBox cache | ||
| .fusebox/ | ||
|
|
||
| # DynamoDB Local files | ||
| .dynamodb/ | ||
|
|
||
| # Temporary folders | ||
| tmp/ | ||
| temp/ | ||
|
|
||
| # End of https://www.gitignore.io/api/node |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import { setTransform, setTransition } from "./util.js"; | ||
|
|
||
| class Carousel { | ||
| constructor(config) { | ||
| this.config = config; | ||
| this.slideAll = config.slideAll; | ||
| this.width = config.MAX_PANEL_SIZE; | ||
| this.currentIndex = config.START_CAROUSEL_INDEX; | ||
| this.isMoveFinished = config.isMoveFinished; | ||
| this.nav = document.querySelectorAll(".slide-navigation > li"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네이밍 짓는게 쉽지 않죠. nav는 리스트라서 nav보다는 navList 정도도 괜찮을 듯. |
||
| this.init(); | ||
| } | ||
|
|
||
| init() { | ||
| this.buttonHandler(); | ||
| this.navigationHandler(); | ||
| } | ||
|
|
||
| moveSlides(option) { | ||
| setTransform(this.slideAll, this.currentIndex, this.width); | ||
| setTransition(this.slideAll, option); | ||
| } | ||
|
|
||
| clickEvent(index) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clickEventHandler 나 Listener 라고 이름 짓곤해요. |
||
| if (this.isMoveFinished === false) return; | ||
| this.isMoveFinished = false; | ||
|
|
||
| const transitionOption = `transform 0.4s ease-in-out`; | ||
| let prevIndex = this.currentIndex - 1; | ||
| let nextIndex = this.currentIndex + 1; | ||
| this.currentIndex = index === 0 ? prevIndex : nextIndex; | ||
| this.moveSlides(transitionOption); | ||
| } | ||
|
|
||
| transitionendEvent() { | ||
| const transitionOption = "none"; | ||
| const minIndex = this.config.START_CAROUSEL_INDEX; | ||
| const maxIndex = this.config.MAX_CAROUSEL_SIZE; | ||
|
|
||
| if (this.currentIndex === minIndex - 1) { | ||
| this.currentIndex = maxIndex - 1; | ||
| this.moveSlides(transitionOption); | ||
| } else if (this.currentIndex === maxIndex) { | ||
| this.currentIndex = minIndex; | ||
| this.moveSlides(transitionOption); | ||
| } | ||
| this.isMoveFinished = true; | ||
| } | ||
|
|
||
| buttonHandler() { | ||
| const buttons = this.config.buttons; | ||
| setTransform(this.slideAll, this.currentIndex, this.width); | ||
|
|
||
| buttons.forEach((element, index) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 델리게이션 고고 |
||
| element.addEventListener("click", () => this.clickEvent(index)); | ||
| }); | ||
|
|
||
| this.slideAll.addEventListener("transitionend", () => this.transitionendEvent()); | ||
| } | ||
|
|
||
| navigationHandler() { | ||
| const transitionOption = `transform 0.4s ease-in-out`; | ||
| setTransform(this.slideAll, this.currentIndex, this.width); | ||
|
|
||
| this.nav.forEach((el, index) => { | ||
| let nextIndex = index + 1; | ||
|
|
||
| el.addEventListener("click", () => { | ||
| if (nextIndex === this.currentIndex) return; | ||
| this.currentIndex = nextIndex; | ||
| this.moveSlides(transitionOption); | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| export { Carousel }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { Carousel } from "./carousel.js"; | ||
| import { TemplateData } from "./templateData.js"; | ||
|
|
||
| const jsonFileUrl = "http://localhost:8080/users"; | ||
| const data = localStorage.getItem("mockData"); | ||
|
|
||
| const carousel = { slideAll: document.querySelector(".slider") }; | ||
| const arrowButtons = { buttons: document.querySelectorAll(".slide-btn > button") }; | ||
| const width = { MAX_PANEL_SIZE: 760 }; | ||
| let currentIndex = { START_CAROUSEL_INDEX: 1 }; | ||
| let maxIndex = { MAX_CAROUSEL_SIZE: 5 }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기까지 선언된 default 값은 누구의 것일까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코멘트 보고 이해가 잘 안 갔었는데 오늘 강의 보고 이해했습니다. 제가 원했던 구조가 model, cardMenu와 casouselSlide였었어서 참고해서 적용해 다음 pr에 보내도록 하겠습니다! |
||
|
|
||
| const config = Object.assign(carousel, arrowButtons, width, currentIndex, maxIndex); | ||
|
|
||
| const run = () => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. run은 여기서만 호출되는 코드라면, 이름없이 익명즉시실행함수라는 걸 써도 되겠군요. |
||
| fetch(jsonFileUrl) | ||
| .then(response => response.json()) | ||
| .then(mockData => { | ||
| localStorage.setItem("mockData", JSON.stringify(mockData)); | ||
| }) | ||
| .then(() => { | ||
| const templateData = new TemplateData(JSON.parse(data)); | ||
| }) | ||
| .then(() => { | ||
| const carousel = new Carousel(config); | ||
| }); | ||
| }; | ||
|
|
||
| run(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| class TemplateData { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TemplateData가 클래스 형태이여야 하는 이유는 뭘까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TemplateData 클래스 안의 메소드를 함수로 하나씩 쓰게 되면 함수를 하나씩 여러번 실행하거나 선언한 함수들을 객체로 따로 저장해 실행하는 방식을 취해야 합니다. |
||
| constructor(mockData) { | ||
| this.cardList = mockData.cardList; | ||
| this.init(); | ||
| } | ||
|
|
||
| init() { | ||
| this.addNavTitle(); | ||
| this.addSlide(); | ||
| this.addDummySlide(); | ||
| } | ||
|
|
||
| addNavTitle() { | ||
| let navButtons = ``; | ||
|
|
||
| this.cardList.forEach(element => { | ||
| navButtons += `<li><button type="button">${element.title}</button></li>`; | ||
| }); | ||
|
|
||
| const slideNav = document.querySelector(".slide-navigation"); | ||
| slideNav.innerHTML = navButtons; | ||
| } | ||
|
|
||
| addSlide() { | ||
| let slides = ``; | ||
|
|
||
| this.cardList.forEach(element => { | ||
| const img = element.image; | ||
| const header = element.header; | ||
| const sentence = element.contents; | ||
|
|
||
| slides += ` | ||
| <li> | ||
| ${this.addImgWrap(img)} | ||
| ${this.addContentsWrap(header, sentence)} | ||
| </li>`; | ||
| }); | ||
|
|
||
| const sliderWrap = document.querySelector(".slider"); | ||
| sliderWrap.innerHTML = slides; | ||
| } | ||
|
|
||
| addImgWrap(img) { | ||
| let imgWrap = ` | ||
| <div class="img-wrap"> | ||
| <img src="${img}"> | ||
| </div>`; | ||
|
|
||
| return imgWrap; | ||
| } | ||
|
|
||
| addContentsWrap(header, sentences) { | ||
| let sentenceList = ``; | ||
| sentences.forEach(el => (sentenceList += `<li>${el}</li>`)); | ||
|
|
||
| let contentsWrap = ` | ||
| <div class="contents-wrap"> | ||
| <h2>${header}</h2> | ||
| <ul> | ||
| ${sentenceList} | ||
| </ul> | ||
| </div>`; | ||
|
|
||
| return contentsWrap; | ||
| } | ||
|
|
||
| addDummySlide() { | ||
| const sliderWrap = document.querySelector(".slider"); | ||
|
|
||
| let firstChild = sliderWrap.firstElementChild; | ||
| let lastChild = sliderWrap.lastElementChild; | ||
|
|
||
| let clonedFirst = firstChild.cloneNode(true); | ||
| let clonedLast = lastChild.cloneNode(true); | ||
|
|
||
| sliderWrap.appendChild(clonedFirst); | ||
| sliderWrap.insertBefore(clonedLast, sliderWrap.firstElementChild); | ||
| } | ||
| } | ||
|
|
||
| export { TemplateData }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| const setTransform = (target, width, currentIndex) => { | ||
| let transformOption = `translateX(${-width * currentIndex}px)`; | ||
| target.style.transform = transformOption; | ||
| }; | ||
|
|
||
| const setTransition = (target, option) => { | ||
| target.style.transition = option; | ||
| }; | ||
|
|
||
| export { setTransform, setTransition }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="ko"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <link rel="stylesheet" href="../css/reset.css" /> | ||
| <link rel="stylesheet" href="../css/style.css" /> | ||
| <title>아마존</title> | ||
| </head> | ||
|
|
||
| <body> | ||
| <div class="wrap"> | ||
| <div class="slide-container"> | ||
| <ul class="slide-navigation clearfix"> | ||
| <!-- addNavTitle --> | ||
| </ul> | ||
| <ul class="slider clearfix"> | ||
| <!-- addSlideImg, addSlideHeader --> | ||
| </ul> | ||
| </div> | ||
| <div class="slide-btn"> | ||
| <button type="button" class="prev-btn"></button> | ||
| <button type="button" class="next-btn"></button> | ||
| </div> | ||
| </div> | ||
| <script type="module" src="../js/main.js"></script> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
es modules 브라우저의 지원범위에 대해서 조사해보세요.
호환성에 대해서 인지하고 개발하면 좋죠.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ES modules 지원 범위
추가적으로 블로그를 찾아봤는데, 지원범위 때문에 webpack같은 모듈 번들러를 사용한다는 것을 알게 되었습니다.