본문 바로가기
코딩

[jQuery] 특정 문자열 포함 요소 선택하기: 실시간 검색 페이지 만들기 예제

by 우월한하루 2023. 12. 13.
728x90
반응형

 

 

 

이번 포스팅은 제이쿼리와 정규식을 활용하여 검색을 하면,

실시간으로 검색내용과 일치하는 메뉴만 보여주는 페이지를 만들어 보도록 하겠습니다.

 

이번 코딩에서 핵심은 :contains()를 사용하여 내가 입력한 검색어와 동일한 내용을 가진 요소를 찾아내는 것입니다.

 

 

오늘 만들 최종 결과물
오늘 만들 최종 결과물

 

 

위의 이미지처럼 검색창에 찾고 싶은 내용을 검색하면 검색한 내용과 일치하는 글을 형광색으로 하이라이트 처리하고,

어떤 탭에 몇 개의 일치하는 결과를 가지고 있는지 해당 탭을 통해서 보여주게 합니다.

 

 

 

반응형

 

 


 

 

 

html 코드 작성

 

 

 

먼저 화면으로 보일 html 코드를 작성해 보겠습니다.

CSS는 취향에 맞게 style 태그를 통해 만들어보세요.

 

<div class="search-box">
    🔎
    <input type="text" id="search-box" placeholder="검색 키워드를 입력해주세요.">
</div>

<section style="min-height: 320px; max-width: 580px;">

    <div class="tab_list">
        <ul style="height:100%; background:#F2F4F7;">
            <li id="tab1" class="tab_li on">
                질문 탭 1
                <span id="search-count" class="off_text"></span>
            </li>
            <li id="tab2" class="tab_li">
                질문 탭 2
                <span id="search-count2" class="off_text"></span>
            </li>
            <li id="tab3" class="tab_li">
                질문 탭 3
                <span id="search-count3" class="off_text"></span>
            </li>
            <li id="tab4" class="tab_li">
                질문 탭 4
                <span id="search-count4" class="off_text"></span>
            </li>
        </ul>
    </div>

    <div class="tab_menu on" id="tab1_menu">
        <ul>
            <li class="menu-item">Q. 첫번째 질문 test.</li>
            <li class="menu-item">Q. 두번째 질문</li>
            <li class="menu-item">Q. 세번째 질문</li>
            <li class="menu-item">Q. 네번째 질분</li>
        </ul>
    </div>

    <div class="tab_menu" id="tab2_menu">
        <ul>
            <li class="menu-item">Q. 일 질문</li>
            <li class="menu-item">Q. 이 질문</li>
            <li class="menu-item">Q. 삼 질문</li>
            <li class="menu-item">Q. 사 질분</li>
        </ul>
    </div>

    <div class="tab_menu" id="tab3_menu">
        <ul>
            <li class="menu-item">Q. 내용유</li>
            <li class="menu-item">Q. 내용무</li>
            <li class="menu-item">Q. ㄱㄴ</li>
            <li class="menu-item">Q. ㄷㄹ</li>
        </ul>
    </div>

    <div class="tab_menu" id="tab4_menu">
        <ul>
            <li class="menu-item">Q. 123</li>
            <li class="menu-item">Q. 456</li>
            <li class="menu-item">Q. 789</li>
        </ul>
    </div>
</section>

 

 

 

가장 상단에 id="search-box"인 텍스트 박스를 만들고, 이 텍스트 박스를 통해 검색어를 입력받도록 하겠습니다.

 

class="tab_list"

tab_list에 이동할 탭들을 여러 개 만들어 줍니다.

이 탭을 클릭하여 클릭한 탭에 해당하는 내용들을 보여주도록 하겠습니다.

지금은 스크립트를 작성하지 않아서 클릭해도 화면에 변경되는 내용은 없습니다.

 

CSS를 활용해서 on 클래스를 가지고 있다면 배경색이 바뀌고,

글자색도 변경되게 하여 현재 선택된 탭이 무엇인지 쉽게 알 수 있도록 합니다.

 

 

html 작성한 화면
html 작성한 화면

 

 

 

html을 작성하고 CSS로 일부분 꾸민다면 대충 이런 느낌의 화면이 완성됩니다.

이제 검색어를 입력받고, 탭을 클릭 시 동작하는 스크립트를 jQuery를 사용하여 작성하겠습니다.

 

 

 

말풍선처럼 보이게 하는 CSS

 

말풍선
말풍선

 

 

 

CSS 중 위의 이미지와 같이 말풍선처럼 보이게 하는 CSS 부분은 코드를 넣어두겠습니다.

 

 

.tab_list ul li .on_text {
    display: inline-block;
    padding: 3px 0 3px 6px;
    background: red;
    color: white;
    border-radius: 10px;
    position: relative;
    bottom: 13px;
    font-size: 0.8em;
}
.tab_list ul li .on_text::after{
    content: '';
    border: 7px solid transparent;
    border-top-color: red;
    border-bottom: 0;
    border-left: 0;
    position: relative;
    top: 22px;
    left: -10px;
}
.tab_list ul li .off_text {
    display:none;
}

 

 

 

 

스크립트 작성

 

 

먼저 검색 텍스트 박스에 입력을 할 때마다 호출되는 이벤트를 작성해 보겠습니다.

 

$(document).ready(function() {
    // 검색 상자에 입력이 있을 때마다 호출되는 이벤트 리스너
    $("#search-box").on("input", function() {
        // 검색어 가져오기
        var searchTerm = $(this).val().toLowerCase();

        // 모든 메뉴 초기화
        $(".menu-item").html(function(_, html) {
            return html.replace(/<span class="highlight">|<\/span>/gi, '');
        });

        // 검색어와 일치하는 메뉴 찾기
        var matched_tab1 = $("#tab1_menu .menu-item:contains('" + searchTerm + "')");
        var matched_tab2 = $("#tab2_menu .menu-item:contains('" + searchTerm + "')");
        var matched_tab3 = $("#tab3_menu .menu-item:contains('" + searchTerm + "')");
        var matched_tab4 = $("#tab4_menu .menu-item:contains('" + searchTerm + "')");

        $(".menu-item:contains('" + searchTerm + "')").html(function(_, html) {
            return html.replace(new RegExp('(' + searchTerm + ')', 'gi'), '<span class="highlight">$1</span>');
        });

        // 검색어와 일치하는 메뉴만 표시
        $(".menu-item").hide();
        $(".menu-item:contains('" + searchTerm + "')").show();

        if(matched_tab1.length && searchTerm) {
            $("#search-count").addClass("on_text");
            $("#search-count").removeClass("off_text");
            $("#search-count").text(matched_tab1.length);
        } else {
            $("#search-count").removeClass("on_text");
            $("#search-count").addClass("off_text");
        }

        if(matched_tab2.length && searchTerm) {
            $("#search-count2").addClass("on_text");
            $("#search-count2").removeClass("off_text");
            $("#search-count2").text(matched_tab2.length);
        } else {
            $("#search-count2").removeClass("on_text");
            $("#search-count2").addClass("off_text");
        }

        if(matched_tab3.length && searchTerm) {
            $("#search-count3").addClass("on_text");
            $("#search-count3").removeClass("off_text");
            $("#search-count3").text(matched_tab3.length);
        } else {
            $("#search-count3").removeClass("on_text");
            $("#search-count3").addClass("off_text");
        }

        if(matched_tab4.length && searchTerm) {
            $("#search-count4").addClass("on_text");
            $("#search-count4").removeClass("off_text");
            $("#search-count4").text(matched_tab4.length);
        } else {
            $("#search-count4").removeClass("on_text");
            $("#search-count4").addClass("off_text");
        }
    });
});

 

 

 

 

728x90

 

 

 

주석을 통해 설명을 추가해 두었지만 아래 추가 설명을 더 적어보겠습니다.

 

var searchTerm = $(this). val(). toLowerCase();

contains은 입력받은 내용의 대문자 소문자를 구분하기 때문에 입력받은 영어를 toLowerCase를 사용하여,

전부 소문자로 통일시켜 줍니다.

 

$("#search-box"). on("input", function()

search-box에 글자를 입력할 때마다 호출되는 함수입니다.

글자를 입력할 때마다 하이라이트 되었던 모든 메뉴를 초기화시키고, 입력된 문구를 새롭게 하이라이트 시킵니다.

 

. menu-item:contains('" + searchTerm + "')"

contains을 활용하여. menu-item 클래스중 검색받은 문구를 가진 요소만 찾아서 가져옵니다.

 

$(". menu-item:contains('" + searchTerm + "')"). html(function(_, html) {
   return html.replace(new RegExp('(' + searchTerm + ')', 'gi'), '<span class="highlight">$1 </span>');
}); 

 

검색어와 일치하는 문구만 <span class="highlight"> 태그 안에 넣어서 하이라이트 시켜줍니다.

( highlight의 CSS를 직접 작성해주셔야 합니다.)

 

이후 해당하는 탭에 말풍선을 추가하며 끝납니다.

 

다음은 탭을 클릭했을 때 동작하는 스크립트입니다.

좀 길고 난잡해 보일 수 있으니 정리해서 쓰시면 될 것 같습니다.

 

$(function() {
    $(".tab_li").click(function() {
        var click_id = $(this).attr("id");
        if ($(".tab_li").hasClass("on") !== false) {
            $(".tab_li").removeClass("on");
            $(this).addClass("on");

            if (click_id == "tab1") {
                $("#tab1_menu").css("display","inline-block");
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else if (click_id == "tab3") {
                $("#tab1_menu").hide();
                $("#tab3_menu").css("display","inline-block");
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else if (click_id == "tab2") {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").css("display","inline-block");
                $("#tab4_menu").hide();
            } else if (click_id == "spare_list") {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").css("display","inline-block");
            }
        } else {
            $(this).addClass("on");

            if (click_id == "tab1") {
                $("#tab1_menu").css("display","inline-block");
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else if (click_id == "tab3") {
                $("#tab1_menu").hide();
                $("#tab3_menu").css("display","inline-block");
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else if (click_id == "tab2") {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").css("display","inline-block");
                $("#tab4_menu").hide();
            } else if (click_id == "spare_list") {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else if (click_id == "product_info") {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").hide();
            } else {
                $("#tab1_menu").hide();
                $("#tab3_menu").hide();
                $("#tab2_menu").hide();
                $("#tab4_menu").css("display","inline-block");
            }
        }
    });
});

 

 

 

간단하게 설명하면 클릭한 아이디를 가져와서 해당아이디와 일치하는 탭의 메뉴를 보여주는 형식입니다.

hide(), show()를 같이 사용하면 간편하지만 show를 사용하면,

display가 block가 되어 좀 보기 좋지 않아서 css의 display를 직접 수정해 주었습니다.

 

 

 

결과물

 

 

여기까지 따라오셨다면 완성입니다.

 

 

완성된 기능 작동
완성된 기능 작동

 

 

위와 같이 탭을 누르면 이동하고, 검색박스에 내용을 입력 시, 실시간으로 검색되어 나타나는 화면을 볼 수 있습니다.

위의 코드를 조금만 변형해서 자신이 원하는 곳에 이곳저곳 활용가능합니다.

 

728x90
반응형

댓글