使用Ajax与jQuery读取目录文件,实现目录及子目录文件的手风琴式折叠展示
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
fsmodule, Python'sos.walk, etc.)
内容的提问来源于stack exchange,提问作者GeorgeT

