Muscardinus

Search bar 본문

FrontEnd/Basic Skills

Search bar

Muscardinus 2022. 2. 9. 00:02
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&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwxfHxhfGVufDB8fHw&amp;ixlib=rb-1.2.1&amp;q=80&amp;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&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwyfHxhfGVufDB8fHw&amp;ixlib=rb-1.2.1&amp;q=80&amp;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&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MXwxOTg1MzV8MHwxfHNlYXJjaHwzfHxhfGVufDB8fHw&amp;ixlib=rb-1.2.1&amp;q=80&amp;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