You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ajax与jQuery读取目录文件,实现目录及子目录文件的手风琴式折叠展示

How to Read Directory & Subdirectories via Ajax/jQuery and Display as Collapsible Accordion

Hey there! Let's break down how to build this feature—reading a target directory (and all its subfolders) with Ajax/jQuery, then showing everything in a nice collapsible accordion layout. First, a quick critical note: front-end code can't directly access local file systems for security reasons, so we'll need a simple backend script to handle the directory traversal. I'll use PHP for the backend since it's widely supported, but you can adapt this logic to Node.js, Python, etc.


Step 1: Backend Script (list-files.php)

This script will take a directory path as a parameter, recursively scan it, and return the structure as JSON. Make sure your server has read permissions for the target folder!

<?php
header('Content-Type: application/json');

// Set your base target directory (adjust this to your actual folder path)
$baseDir = __DIR__ . '/your-target-folder';
$requestedDir = isset($_GET['dir']) ? $_GET['dir'] : '';
$currentDir = realpath($baseDir . '/' . $requestedDir);

// Security check: Ensure we only access directories within our base folder
if (!$currentDir || strpos($currentDir, $baseDir) !== 0) {
    echo json_encode(['error' => 'Invalid directory or permission denied']);
    exit;
}

// Recursive function to build nested file/folder structure
function scanDirectory($dir, $baseDir) {
    $items = [];
    $dirContents = scandir($dir);
    
    foreach ($dirContents as $item) {
        if ($item === '.' || $item === '..') continue;
        
        $itemPath = $dir . '/' . $item;
        $relativePath = str_replace($baseDir . '/', '', $itemPath);
        
        if (is_dir($itemPath)) {
            $items[] = [
                'type' => 'directory',
                'name' => $item,
                'path' => $relativePath,
                'children' => scanDirectory($itemPath, $baseDir)
            ];
        } else {
            $items[] = [
                'type' => 'file',
                'name' => $item,
                'path' => $relativePath,
                'size' => filesize($itemPath) // Optional: Include file size for context
            ];
        }
    }
    
    return $items;
}

// Generate and return the final structure as JSON
$structure = scanDirectory($currentDir, $baseDir);
echo json_encode([
    'directory' => str_replace($baseDir . '/', '', $currentDir),
    'items' => $structure
]);
?>

Step 2: Frontend Setup (HTML & jQuery)

We'll use jQuery for Ajax calls and implement a collapsible accordion—you can choose between a custom lightweight version or the polished jQuery UI Accordion (both options included below).

Basic HTML & Script

<!DOCTYPE html>
<html>
<head>
    <title>Directory Accordion Viewer</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <!-- Optional: Include jQuery UI for pre-built accordion styling -->
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
    
    <style>
        /* Custom styling for our lightweight accordion */
        .directory-accordion {
            max-width: 800px;
            margin: 2rem auto;
            font-family: 'Arial', sans-serif;
        }
        .folder-item {
            background: #f5f5f5;
            padding: 0.8rem 1rem;
            margin: 0.3rem 0;
            cursor: pointer;
            border-radius: 4px;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        .file-item {
            padding: 0.6rem 1rem 0.6rem 2.5rem;
            margin: 0.2rem 0;
            border-left: 2px solid #ddd;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        .children {
            display: none;
            margin-left: 1.5rem;
        }
        .folder-item.open + .children {
            display: block;
        }
    </style>
</head>
<body>
    <div class="directory-accordion" id="directoryAccordion"></div>

    <script>
        $(document).ready(function() {
            // Load the root directory on page load
            loadDirectory('');

            // Fetch directory contents via Ajax
            function loadDirectory(dirPath) {
                $.ajax({
                    url: 'list-files.php',
                    method: 'GET',
                    data: { dir: dirPath },
                    dataType: 'json',
                    success: function(response) {
                        if (response.error) {
                            $('#directoryAccordion').html(`<p style="color: #dc3545;">Error: ${response.error}</p>`);
                            return;
                        }
                        
                        // Generate nested accordion HTML
                        const accordionHtml = generateAccordionHtml(response.items);
                        $('#directoryAccordion').html(accordionHtml);
                        
                        // Option 1: Use jQuery UI Accordion (uncomment below for polished pre-built style)
                        // $('#directoryAccordion').accordion({
                        //     collapsible: true,
                        //     active: false,
                        //     heightStyle: 'content'
                        // });

                        // Option 2: Custom fold/unfold logic (lightweight, no extra dependencies)
                        $('.folder-item').on('click', function() {
                            $(this).toggleClass('open');
                        });
                    },
                    error: function() {
                        $('#directoryAccordion').html('<p style="color: #dc3545;">Failed to load directory contents. Check your backend script or permissions.</p>');
                    }
                });
            }

            // Recursive function to build nested HTML structure
            function generateAccordionHtml(items) {
                let html = '<ul>';
                items.forEach(item => {
                    if (item.type === 'directory') {
                        html += `
                            <li>
                                <div class="folder-item">📁 ${item.name}</div>
                                <div class="children">${generateAccordionHtml(item.children)}</div>
                            </li>
                        `;
                    } else {
                        html += `<li><div class="file-item">📄 ${item.name} (${formatFileSize(item.size)})</div></li>`;
                    }
                });
                html += '</ul>';
                return html;
            }

            // Helper: Format file sizes into readable units
            function formatFileSize(bytes) {
                if (bytes < 1024) return `${bytes} B`;
                else if (bytes < 1048576) return `${(bytes / 1024).toFixed(2)} KB`;
                else return `${(bytes / 1048576).toFixed(2)} MB`;
            }
        });
    </script>
</body>
</html>

Key Tips & Considerations

  • Security: Never skip the directory validation in the backend—it prevents malicious users from accessing sensitive server files via directory traversal attacks.
  • Permissions: Ensure your web server user (e.g., www-data on Apache) has read access to the target directory and all its subfolders.
  • Customization: Tweak the CSS to match your site's design, or extend the code to add features like file download links, sorting, or file previews.
  • Alternative Backends: If you don't use PHP, adapt the recursive directory scan logic to your preferred language (Node.js's fs module, Python's os.walk, etc.)

内容的提问来源于stack exchange,提问作者GeorgeT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:12:10