Javascript
[Javascript] 검색창 자동완성 기능 구현
- 2026.08.27 13:21:26
![]() ![]() 검색 키워드 입력 창에서 키워드 입력하는 경우 자동완성 기능 구현 (방향키, Enter 등도 구현) [!]css[/!] <style>
* { box-sizing: border-box; } body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 30px; background: #f5f7fb; font-family: Arial, "Noto Sans KR", sans-serif; color: #222; } .autocomplete_demo { width: min(100%, 520px); padding: 40px; border-radius: 18px; background: #fff; box-shadow: 0 15px 50px rgba(0, 0, 0, 0.1); } .autocomplete_demo h1 { margin: 0 0 10px; font-size: 26px; } .autocomplete_demo .summary { margin: 0 0 25px; color: #777; font-size: 14px; line-height: 1.6; } .autocomplete_wrap { position: relative; } .autocomplete_input { width: 100%; height: 54px; padding: 0 18px; border: 1px solid #d9dde7; border-radius: 10px; outline: none; font-size: 16px; transition: border-color 0.2s, box-shadow 0.2s; } .autocomplete_input:focus { border-color: #3867f0; box-shadow: 0 0 0 4px rgba(56, 103, 240, 0.12); } .autocomplete_list { position: absolute; top: calc(100% + 8px); left: 0; z-index: 10; display: none; width: 100%; max-height: 250px; margin: 0; padding: 7px; overflow-y: auto; list-style: none; border: 1px solid #e3e6ee; border-radius: 10px; background: #fff; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12); } .autocomplete_list.show { display: block; } .autocomplete_item button { width: 100%; padding: 13px 12px; border: 0; border-radius: 7px; background: transparent; text-align: left; font-size: 15px; cursor: pointer; } .autocomplete_item button:hover, .autocomplete_item.active button { background: #f0f4ff; color: #2453db; } .autocomplete_item strong { color: #2453db; } .result_text { min-height: 24px; margin: 22px 0 0; color: #555; font-size: 14px; } </style> [!]javascript[/!] <script>
const keywords = [ '홈페이지 제작', '홈페이지 유지보수', '홈페이지 리뉴얼', '쇼핑몰 제작', '반응형 웹 제작', '웹 퍼블리싱', 'PHP 개발', 'JavaScript 개발', '기업 홈페이지', '병원 홈페이지' ]; const keyword_input = document.querySelector('#keyword'); const autocomplete_list = document.querySelector('#autocomplete_list'); const result_text = document.querySelector('#result_text'); let active_index = -1; let filtered_keywords = []; const highlight_keyword = (keyword, value) => { const index = keyword.toLowerCase().indexOf(value.toLowerCase()); if (index === -1) return keyword; return ( keyword.slice(0, index) + '<strong>' + keyword.slice(index, index + value.length) + '</strong>' + keyword.slice(index + value.length) ); }; const close_list = () => { autocomplete_list.classList.remove('show'); autocomplete_list.innerHTML = ''; active_index = -1; }; const select_keyword = (keyword) => { keyword_input.value = keyword; result_text.textContent = '선택된 검색어: ' + keyword; close_list(); }; const render_list = () => { const value = keyword_input.value.trim(); autocomplete_list.innerHTML = ''; active_index = -1; if (!value) { close_list(); return; } filtered_keywords = keywords.filter(keyword => keyword.toLowerCase().includes(value.toLowerCase()) ); if (!filtered_keywords.length) { close_list(); return; } filtered_keywords.forEach(keyword => { const item = document.createElement('li'); const button = document.createElement('button'); item.className = 'autocomplete_item'; button.type = 'button'; button.innerHTML = highlight_keyword(keyword, value); button.addEventListener('click', () => { select_keyword(keyword); }); item.appendChild(button); autocomplete_list.appendChild(item); }); autocomplete_list.classList.add('show'); }; const update_active_item = () => { const items = autocomplete_list.querySelectorAll('.autocomplete_item'); items.forEach((item, index) => { item.classList.toggle('active', index === active_index); }); if (items[active_index]) { items[active_index].scrollIntoView({ block: 'nearest' }); } }; keyword_input.addEventListener('input', render_list); keyword_input.addEventListener('keydown', event => { if (!filtered_keywords.length || !autocomplete_list.classList.contains('show')) { return; } if (event.key === 'ArrowDown') { event.preventDefault(); active_index = (active_index + 1) % filtered_keywords.length; update_active_item(); } if (event.key === 'ArrowUp') { event.preventDefault(); active_index = active_index <= 0 ? filtered_keywords.length - 1 : active_index - 1; update_active_item(); } if (event.key === 'Enter' && active_index >= 0) { event.preventDefault(); select_keyword(filtered_keywords[active_index]); } if (event.key === 'Escape') { close_list(); } }); document.addEventListener('click', event => { if (!event.target.closest('.autocomplete_wrap')) { close_list(); } }); </script> [!]html[/!] <div class="autocomplete_demo">
<h1>자동완성 검색</h1> <p class="summary"> 홈페이지, 쇼핑몰, 반응형 등을 입력해보세요.<br> 키보드 방향키와 Enter도 사용할 수 있습니다. </p> <div class="autocomplete_wrap"> <input type="text" id="keyword" class="autocomplete_input" placeholder="검색어를 입력하세요" autocomplete="off" > <ul id="autocomplete_list" class="autocomplete_list"></ul> </div> <p id="result_text" class="result_text">선택된 검색어가 여기에 표시됩니다.</p> </div> |


