Muscardinus
Search bar 본문
728x90
Search bar에서 입력 시, input 변화에 따른 연다른 api 호출이 아닌 debounce(이번에는 lodash 라이브러리 사용)를 사용한 api 호출의 최소화로 구현
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<style>
.container {
width: 400px;
}
.dropdown-menu {
overflow-y: scroll;
width: 100%;
max-height: 500px;
}
.dropdown-item {
display: flex;
align-items: center;
}
.dropdown-item img {
height: 50px;
margin-right: 10px;
}
.dropdown-item span {
overflow: hidden;
display: block;
width: calc(100% - 60px);
text-overflow: ellipsis;
white-space: nowrap;
}
.image-info {
width: 100%;
}
</style>
</head>
<body>
<main style="padding-top: 50px;">
<div class="container">
<div class="row">
<div class="col">
<div class="dropdown">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Search">
</div>
<ul class="dropdown-menu">
</ul>
<!-- 검색 리스트 HTML 코드 -->
<!--
<ul class="dropdown-menu show">
<li class="dropdown-item">
<img src="https://images.unsplash.com/photo-1543147081-393fc92e1af9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwxfHxhfGVufDB8fHw&ixlib=rb-1.2.1&q=80&w=1080" alt="selective focus photo of brown table lot">
<span>selective focus photo of brown table lot</span>
</li>
<li class="dropdown-item">
<img src="https://images.unsplash.com/photo-1544401346-c7c3f874d7b3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwyfHxhfGVufDB8fHw&ixlib=rb-1.2.1&q=80&w=1080" alt="ART LED signage">
<span>ART LED signage</span>
</li>
<li class="dropdown-item">
<img src="https://images.unsplash.com/photo-1564086315895-f3f695934f3a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwzfHxhfGVufDB8fHw&ixlib=rb-1.2.1&q=80&w=1080" alt="house near lake">
<span>house near lake</span>
</li>
</div>
-->
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="p-t-50">
<img class="image-info" src="" alt="">
</div>
</div>
</div>
</div>
</main>
<script src="axios/axios.js"></script>
<script src="lodash.js"></script>
<script src="main.js"></script>
</body>
</html>
// unsplash : https://unsplash.com/documentation#search-photos
// debounce : https://lodash.com/docs/4.17.15#debounce
const accessKey = "hPyF-tz9tHnxeaoTwb7q0GTw10Wxwr85cD63lk7d7UE";
const input = document.querySelector('input');
const dropdownMenu = document.querySelector('.dropdown-menu');
const imageInfo = document.querySelector('.image-info');
// 검색 이미지 리스트 가져오기
// https://unsplash.com/documentation#search-photos
const fetchImages = async search => {
// Do Something here!
const res = await axios.get("https://api.unsplash.com/search/photos/", {
params: {
client_id: accessKey,
query: search
}
});
return res.data.results;
};
// 하나의 이미지 정보만 가져오기
// https://unsplash.com/documentation#get-a-photo
const fetchImage = async id => {
// Do Something here!
const res = await axios.get(`https://api.unsplash.com/photos/${id}`, {
params: {
client_id: accessKey,
}
});
return res.data;
}
// 검색 드랍다운 표기
const onSearch = async e => {
// Do Something Here!
const images = await fetchImages(e.target.value);
dropdownMenu.innerHTML = "";
if (!images.length) {
dropdownMenu.classList.remove("show");
} else {
dropdownMenu.classList.add("show");
listTemplate(images);
}
}
// input.addEventListener("input", onSearch);
input.addEventListener("input", _.debounce(onSearch, 600));
// 검색 드랍다운 리스트 표기
const listTemplate = (images) => {
// Do Something Here!
for (const image of images) {
const { id, alt_description, urls } = image;
const li = document.createElement("li");
li.classList.add("dropdown-item");
li.innerHTML = `
<img src="${urls.regular}" alt="${alt_description}">
<span>${alt_description}</span>
`;
li.addEventListener("click", async () => {
dropdownMenu.classList.remove("show");
input.value = alt_description;
imageTemplate(await fetchImage(id));
})
dropdownMenu.insertAdjacentElement("beforeend", li);
}
}
// 선택된 이미지 정보 표기
const imageTemplate = (image) => {
// Do Something here!
const { urls, alt_description } = image;
imageInfo.src = urls.regular;
imageInfo.alt = alt_description;
}
728x90
'FrontEnd > Basic Skills' 카테고리의 다른 글
Dropdown Menu (0) | 2022.03.13 |
---|---|
Auto Complete (0) | 2022.03.13 |
Scroll Top (0) | 2022.01.31 |
Scroll Spy (0) | 2022.01.31 |
Infinite Scroll (0) | 2022.01.31 |
Comments