如何在网站主目录打开后为子文件夹添加事件监听器并实现点击子文件夹加载文件至select元素
Solution
First, a critical note: browsers block direct access to server file systems for security reasons, so you can't do this with frontend code alone. You'll need a simple backend to handle directory listing requests, then use JavaScript to tie everything together. Let's walk through a complete implementation with Node.js/Express (you can adapt this to other backend languages too).
Step 1: Set Up a Backend Endpoint
This endpoint will read directory contents and return them as JSON.
Install dependencies:
npm install express corsCreate a
server.jsfile:const express = require('express'); const cors = require('cors'); const fs = require('fs'); const path = require('path'); const app = express(); app.use(cors()); app.use(express.static('public')); // Serve your frontend files from a "public" folder // Endpoint to fetch directory contents app.get('/list-directory', (req, res) => { // Resolve the requested path (prevent directory traversal) const requestedPath = req.query.path || ''; const fullPath = path.join(__dirname, 'midifiles', requestedPath); // Validate the path is within our allowed directory const allowedRoot = path.resolve(__dirname, 'midifiles'); if (!fullPath.startsWith(allowedRoot)) { return res.status(403).json({ error: 'Access denied' }); } // Read directory entries fs.readdir(fullPath, { withFileTypes: true }, (err, entries) => { if (err) { return res.status(500).json({ error: 'Failed to read directory' }); } // Format entries for frontend const contents = entries.map(entry => ({ name: entry.name, isDirectory: entry.isDirectory(), path: path.join(requestedPath, entry.name) })); res.json(contents); }); }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Step 2: Update Your Frontend Code
Instead of redirecting to the directory, we'll load contents in-page, add click listeners to subfolders, and populate the select element with files.
Create a public/index.html file (this is where your frontend lives):
<!DOCTYPE html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Datafiles</title> <style> .folder { cursor: pointer; color: #0066cc; text-decoration: underline; margin: 6px 0; } .file { margin: 4px 0; padding-left: 12px; } </style> </head> <body> <button id="loadmfiles">Load Sample Files</button> <div id="directory-view"></div> <select id="playlist_container" style="margin-top: 16px; padding: 4px; min-width: 200px;"></select> <script> const loadBtn = document.getElementById('loadmfiles'); const directoryView = document.getElementById('directory-view'); const playlistSelect = document.getElementById('playlist_container'); // Fetch and render directory contents function renderDirectory(path = '') { fetch(`/list-directory?path=${encodeURIComponent(path)}`) .then(res => res.json()) .then(contents => { // Clear previous content directoryView.innerHTML = ''; playlistSelect.innerHTML = ''; contents.forEach(entry => { const item = document.createElement('div'); item.textContent = entry.name; if (entry.isDirectory) { // Style folders and add click listener item.classList.add('folder'); item.addEventListener('click', () => { renderDirectory(entry.path); }); } else { // Add files as options to the select element item.classList.add('file'); const option = document.createElement('option'); option.value = entry.path; option.textContent = entry.name; playlistSelect.appendChild(option); } directoryView.appendChild(item); }); }) .catch(err => console.error('Error loading directory:', err)); } // Trigger directory load when button is clicked loadBtn.addEventListener('click', () => { renderDirectory(); }); </script> </body> </html>
Step 3: Run the App
- Place your
midifilesfolder in the same directory asserver.js. - Start the server:
node server.js - Visit
http://localhost:3000in your browser. Click the button to load the main directory, then click any subfolder to see its files populate the select element.
Key Notes
- Security: The backend code includes checks to prevent directory traversal attacks (ensuring users can only access files within
midifiles). Never skip these checks in production. - Alternative Backends: If you're using PHP, Python, or another language, the core logic is the same: create an endpoint that reads the directory and returns JSON, then fetch it with frontend JavaScript.
- User Experience: The CSS adds basic styling to distinguish folders from files, making it clear what's clickable.
内容的提问来源于stack exchange,提问作者Josanta

