티스토리 뷰

WEB/JQuery

폴더 트리메뉴

silverline79 2026. 1. 22. 10:06

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery 검색형 폴더 트리</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        /* 1. CSS 스타일 */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f8f9fa;
            padding: 40px;
        }

        .tree-container {
            background: #fff;
            width: 400px;
            margin: 0 auto;
            padding: 25px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
        }

        h2 {
            font-size: 20px;
            color: #333;
            margin-bottom: 20px;
            text-align: center;
        }

        /* 검색창 스타일 */
        .search-box input {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid #eee;
            border-radius: 8px;
            font-size: 14px;
            box-sizing: border-box;
            transition: border-color 0.3s;
            outline: none;
        }

        .search-box input:focus {
            border-color: #007bff;
        }

        /* 트리 메뉴 구조 */
        ul.tree, ul.tree ul {
            list-style: none;
            margin: 0;
            padding: 0;
            margin-left: 20px;
        }

        .tree li {
            margin: 8px 0;
        }

        .folder, .file {
            padding: 6px 10px;
            cursor: pointer;
            border-radius: 6px;
            display: inline-block;
            transition: background 0.2s;
        }

        .folder:hover, .file:hover {
            background-color: #f1f3f5;
        }

        /* 기본적으로 하위 폴더는 숨김 (active 클래스 시 표시) */
        .folder + ul {
            display: none;
        }

        .folder.active + ul {
            display: block;
        }

        .file {
            color: #495057;
        }

        /* 검색 결과 없음 메시지 */
        #no-result {
            display: none;
            padding: 30px 0;
            text-align: center;
            color: #adb5bd;
            font-size: 14px;
        }
    </style>
</head>
<body>

<div class="tree-container">
    <h2>📂 프로젝트 탐색기</h2>
    
    <div class="search-box">
        <input type="text" id="tree-search" placeholder="폴더나 파일명을 입력하세요...">
    </div>

    <div id="no-result">
        검색 결과가 없습니다. 😅
    </div>

    <ul class="tree" id="main-tree">
        <li>
            <div class="folder active">📂 src</div>
            <ul>
                <li>
                    <div class="folder">📂 components</div>
                    <ul>
                        <li class="file">📄 Header.jsx</li>
                        <li class="file">📄 Footer.jsx</li>
                        <li class="file">📄 Sidebar.css</li>
                    </ul>
                </li>
                <li>
                    <div class="folder">📂 pages</div>
                    <ul>
                        <li class="file">📄 Home.jsx</li>
                        <li class="file">📄 Board.jsx</li>
                        <li class="file">📄 Login.jsx</li>
                    </ul>
                </li>
                <li class="file">📄 App.jsx</li>
            </ul>
        </li>
        <li>
            <div class="folder">📂 public</div>
            <ul>
                <li class="file">📄 index.html</li>
                <li class="file">📄 favicon.ico</li>
            </ul>
        </li>
        <li class="file">📄 package.json</li>
        <li class="file">📄 README.md</li>
    </ul>
</div>

<script>
    // 2. jQuery 로직
    $(document).ready(function() {
        
        // 대소문자 무시를 위한 :contains 커스텀 선택자
        $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function(elem) {
                return $(elem).text().toLowerCase().indexOf(arg.toLowerCase()) >= 0;
            };
        });

        // [1] 폴더 클릭 시 열기/닫기
        $(document).on('click', '.folder', function() {
            $(this).next('ul').slideToggle(200);
            $(this).toggleClass('active');
        });

        // [2] 실시간 검색 기능
        $('#tree-search').on('keyup', function() {
            const value = $(this).val().trim().toLowerCase();
            const $treeItems = $('#main-tree li');
            const $noResult = $('#no-result');

            // 검색어가 없을 때 전체 복원
            if (value === "") {
                $treeItems.show();
                $noResult.hide();
                $('.folder, .file').css('background-color', 'transparent');
                return;
            }

            // 초기화: 모두 숨기고 하이라이트 제거
            $treeItems.hide();
            $('.folder, .file').css('background-color', 'transparent');

            // 검색어 포함된 li 찾기
            const $matchedItems = $("#main-tree li:contains('" + value + "')");

            if ($matchedItems.length > 0) {
                $noResult.hide();
                $matchedItems.each(function() {
                    $(this).show(); // 자신 노출
                    $(this).parents('li').show(); // 부모 리스트 노출
                    $(this).parents('ul').show(); // 부모 그룹 노출
                    
                    // 매칭된 텍스트가 있는 요소에 강조색 입히기
                    $(this).children('.folder, .file').filter(":contains('" + value + "')").css('background-color', '#fff3cd');
                    
                    // 상위 폴더 아이콘들을 active 상태로 (열림 유지)
                    $(this).parents('ul').prev('.folder').addClass('active');
                });
            } else {
                $noResult.show();
            }
        });

        // 파일 클릭 시 액션
        $('.file').on('click', function() {
            alert($(this).text() + " 파일을 엽니다.");
        });
    });
</script>

</body>
</html>

 

 

 

※ 해당 내용은 Google Gmini3.0에서 작성되었습니다.

'WEB > JQuery' 카테고리의 다른 글

폴더 메뉴 한글검색 전체 열기닫기 추가  (1) 2026.01.22
폴더 트리메뉴 한글 검색포함  (1) 2026.01.22
모바일 전체 메뉴  (0) 2026.01.18
배너 좌우 이동 jQuery  (0) 2025.01.10
모바일 메뉴 더보기 클릭 JQuery  (0) 2025.01.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함