Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
# javascript-amazon
레벨3
Binary file added img/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.1/css/all.css" integrity="sha384-v8BU367qNbs/aIZIxuivaU55N5GPF89WBerHoGA4QTcbUjYiLQtKdrfXnqAcXyTv" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>

<body>

<div class="carousel-wrapper">
<div class='carousel__menu'>
<ul class='menu__list'>
</ul>
</div>
<!-- carousel__container start -->
<div class="carousel">
<div class="carousel__container">
<!-- carousel item start-->
<!-- carousel item end -->
</div>
</div>

<!-- carousel__container end -->
<div class="carousel__button--prev">
<i class="fas fa-arrow-left"></i>
</div>
<div class="carousel__button--next">
<i class="fas fa-arrow-right"></i>
</div>
</div>
<script type="module" src="index.js"></script>
<script src="./prac.js"></script>
</body>
</html>
71 changes: 71 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class Carousel {
constructor (menuData,contentData) {
this.menuData=menuData;
this.contentData=contentData;
this.makingMenuList();
this.makingSlider();
this.btnHandler();
this.count = 0;
}
changeLocation (element,index) {
this.count = index;
const width = element.children[0].getBoundingClientRect().width;
element.style.transform = `translateX(${-this.count*width}px)`;
}
scaleMenu (element,index) {
this.count = index;
Array.from(element.parentNode.children).forEach((element)=>element.style.transform=`scale(0.99)`)
element.parentNode.children[this.count].style.transform = 'scale(1.1)';
}
btnHandler () {
const left =document.querySelector('div.carousel__button--prev');
const right =document.querySelector('div.carousel__button--next');
[left,right].forEach((btn,index)=>{
btn.addEventListener('click',()=>{
index === 0 ? this.count-- : this.count++;
if (this.count >3) this.count =0;
if (this.count<0) this.count =3;
const el = document.querySelector('.carousel__container');
this.changeLocation(el,this.count);
this.scaleMenu(document.querySelector('.menu__list>li'),this.count);
});
})
}
makingMenuList () {
const menuConatiner=document.querySelector('.menu__list')
this.menuData.forEach((data)=>{
menuConatiner.innerHTML +=`
<li><a href='#'>${data}</a></li>`
})
Array.from(menuConatiner.children).forEach((li,index)=>{
li.addEventListener('click',()=>{
this.scaleMenu(li,index);
this.changeLocation(document.querySelector('.carousel__container'),index);
})
})
}
makingSlider () {
const carouselContainer = document.querySelector('.carousel__container');
carouselContainer.innerHTML=this.contentData.map((data,index)=>`
<div class='carousel__contents'>
<div class='carousel__text'>
<ul>
<h3>${data.title}</h3>
${data.desc.map((desc)=>`<li>${desc}</li>`).join('')}
</ul>
</div>
<div class='carousel__img'>
<img src=${data.imgUrl} />
</div>
</div>`).join('');
}
}

window.addEventListener('DOMContentLoaded',()=>{
fetch('./localData.json')
.then((data)=>data.json())
.then((data)=>{
const {menuData,contentData}=data;
const carousel=new Carousel(menuData,contentData);
})
});
35 changes: 35 additions & 0 deletions localData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"menuData" : [
"Fast, Free Delivery",
"Exclusive deals and offers",
"Prime Originals, movies and TV shows",
"Over 2 million song ad free"
],
"contentData" : [{
"id" : "1",
"imgUrl" : "https://placedog.net/200/250?id=8",
"title" :"Enjoy exclusive savings and rewards",
"desc" : ["Fast, Free Delivery",
"Exclusive deals and offers","Prime Originals, movies and TV shows","Over 2 million song ad free"]
},{
"id" : "2",
"imgUrl" : "https://placedog.net/200/250?id=12",
"title" :"Code Squad is awesome place",
"desc" : ["Code, Feel JS",
"Do you want to be Front Engeneer?","Come to us Master,Good People","Waiting For you!"]
},{
"id" : "3",
"imgUrl" :"https://placedog.net/200/250?id=14",
"title" :"Learning With practice and enthusiastic people",
"desc" : ["React to ur Mind",
"Es6 class is good for you","We will find answer","As we've done so far"]
},{
"id" : "4",
"imgUrl" : "https://placedog.net/200/250?id=15",
"title" :"Watching Dog makes inner-peace",
"desc" : ["It was hard Day.",
"Do you feel exhausted?","Come to Our good puppy","puppy would be with you"]
}
]
}

70 changes: 70 additions & 0 deletions search.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
* {
margin: 0;
padding: 0;
box-sizing: content-box;
}
body {
font: 16px Arial;
}
header {
padding: 15px;
display: flex;
height: 40px;
justify-content: space-between;
align-items: center;
background-color: #242F40;
}
.logo {
display: block;
width: 70px;
height: 40px;
}
.form-container {
width: 100%;
display: flex;
justify-content: center;
}
.autocomplete {
/*the container must be positioned relative:*/
position: relative;
display: inline-block;
width: 350px;
}
input {
border: 1px solid transparent;
border-radius: 5px;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}
input[type=text] {
background-color: #f1f1f1;
width: 94%;
}
input[type=submit] {
background-color: DodgerBlue;
color: #fff;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.autocomplete-items div:hover {
background-color: #e9e9e9;
}
.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}
26 changes: 26 additions & 0 deletions search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="search.css">
<title>Document</title>
</head>
<body>
<header>
<div>
<a href="#" class="logo"></a>
</div>
<div class='form-container'>
<form action="" autocomplete="off">
<div class='autocomplete'>
<input type="text" id='searchBar' name='myCountry' placeholder="Country">
</div>
<input type="submit" value='Search'>
</form>
</div>
</header>
<script src="./search.js"></script>
</body>
</html>
95 changes: 95 additions & 0 deletions search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
class Search {
constructor (data,{autoComplete,input}) {
this.autoComplete = autoComplete;
this.data = data;
this.input = input;
this.autoCompleteItems;
this.currentTargetIndex=-1;
this.handleInputChange();
this.handleKeyDown();
this.closeAllList()
}
handleInputChange () {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleInputChange 함수 전체를 훑어보면, 들여쓰기가 5단계까지 보입니다.
이 깊이를 줄이는 방법은 무엇인지 생각해보시죠.
함수를 나누는 것도 좋은 방법 중 하나고요.

this.input.addEventListener('input',(e)=>{
const value = this.input.value;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value와 같은 대명서 이름은 쓰지말고, 구체적인 의미로 이름을 지어보세요.
예를들어 inputValue나 searchQueryString 등으로 바꿀 수 있겠죠.

if (!value) return;
const autoCompleteItemsExits = !!document.querySelector('.autocomplete-items');
if (autoCompleteItemsExits) {
this.autoCompleteItems.parentNode.removeChild(this.autoCompleteItems);
}
this.autoCompleteItems = document.createElement('div');
this.autoCompleteItems.classList.add('autocomplete-items')
this.autoComplete.appendChild(this.autoCompleteItems);
const addList =()=>{
this.data.forEach((dataValue)=>{
if (dataValue.substring(0,value.length).toUpperCase()===value.toUpperCase()) {
const contentDiv = document.createElement('div');
contentDiv.innerHTML=`<strong>${dataValue.substring(0,value.length)}</strong>${dataValue.substring(value.length)}<input type='hidden' value='${dataValue}'>`
this.autoCompleteItems.appendChild(contentDiv);
contentDiv.addEventListener('click',(e)=>{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반복문 안에서 이벤트 등록을 하지 말고,
event delegation 방식을 여기에 적용해볼수 있을거 같은데요.

this.input.value = e.target.querySelector('input').value;
})
}
})
}
setTimeout(()=>{
addList();
},300)
})
}
closeAllList () {
document.addEventListener('click',(e)=>{
e.preventDefault();
const itemContainer=document.querySelector('.autocomplete-items');
if (!itemContainer) return;
if (e.target!==this.input && e.target!==itemContainer ) {
itemContainer.parentNode.removeChild(itemContainer);
}
})
}
handleKeyDown () {
this.input.addEventListener('keydown',(e)=>{
if (e.which === 40) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which ?? 이건 jquery 에서 제공되는 속성인거 같은데 맞나요? 표준인가...??

this.currentTargetIndex++;
if (!this.autoCompleteItems) return;
let checkOutOfListIndex=this.currentTargetIndex >= this.autoCompleteItems.children.length;
if (checkOutOfListIndex) this.currentTargetIndex=0;
Array.from(this.autoCompleteItems.children).forEach((item)=>{
item.classList.remove('autocomplete-active')});
let choosedTarget =this.autoCompleteItems.children[this.currentTargetIndex];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.autoCompleteItems.children 과 같이 반복되는 속성값은 변수로 캐시해서 사용하는 게 어떨까요.

const child = this.autoCompleteItems.children; 
let choosedTarget = child[this.currentTargetIndex]

choosedTarget=this.autoCompleteItems.children[this.currentTargetIndex];
choosedTarget.classList.add('autocomplete-active');
this.input.value = choosedTarget.querySelector('input').value
} else if (e.which === 38) {
this.currentTargetIndex--;
if (!this.autoCompleteItems) return;
let checkOutOfListIndex=this.currentTargetIndex < 0;
if (checkOutOfListIndex) this.currentTargetIndex=this.autoCompleteItems.children.length-1;
Array.from(this.autoCompleteItems.children).forEach((item)=>{
item.classList.remove('autocomplete-active')});
let choosedTarget =this.autoCompleteItems.children[this.currentTargetIndex];
choosedTarget=this.autoCompleteItems.children[this.currentTargetIndex];
choosedTarget.classList.add('autocomplete-active');
this.input.value = choosedTarget.querySelector('input').value
} else if (e.which === 13) {
e.preventDefault();
if (this.currentTargetIndex > -1) {
this.autoCompleteItems.children[this.currentTargetIndex].click();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

click() 메서드는 뭔가요?? 표준??

}
}
})
}
}

window.addEventListener('DOMContentLoaded',()=>{
fetch('./searchData.json')
.then((data)=>data.json())
.then((searchData)=>{
const targetElement= {
autoComplete : document.querySelector('.autocomplete'),
input : document.querySelector('input#searchBar')
}
const search = new Search(searchData.data,targetElement);
});
})

3 changes: 3 additions & 0 deletions searchData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"data" :["Korea","Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua &amp; Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia &amp; Herzegovina","Botswana","Brazil","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central Arfrican Republic","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica","Cote D Ivoire","Croatia","Cuba","Curacao","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kiribati","Kosovo","Kuwait","Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Mauritania","Mauritius","Mexico","Micronesia","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Myanmar","Namibia","Nauro","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","North Korea","Norway","Oman","Pakistan","Palau","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre &amp; Miquelon","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Korea","South Sudan","Spain","Sri Lanka","St Kitts &amp; Nevis","St Lucia","St Vincent","Sudan","Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad &amp; Tobago","Tunisia","Turkey","Turkmenistan","Turks &amp; Caicos","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States of America","Uruguay","Uzbekistan","Vanuatu","Vatican City","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"]
}
Loading