<body>
<div class="container">
<h1>PDF搜索</h1>
<div class="control-panel">
<button id="selectFolderBtn" class="btn">选择文件夹</button>
<input type="file" id="folderInput" webkitdirectory directory multiple>
<input type="text" id="searchInput" placeholder="输入关键词搜索...">
<button id="clearBtn" class="btn">清除</button>
</div>
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="status-area" id="status">
准备就绪,请选择包含PDF的文件夹
</div>
<div id="results">
<div class="no-results">没有找到PDF文件</div>
</div>
<div id="pdfPreview">
<div class="preview-header">
<h3 id="previewTitle"></h3>
<button id="closePreview">×</button>
</div>
<iframe id="pdfViewer"></iframe>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', async function() {
const selectFolderBtn = document.getElementById('selectFolderBtn');
const folderInput = document.getElementById('folderInput');
const searchInput = document.getElementById('searchInput');
const clearBtn = document.getElementById('clearBtn');
const resultsDiv = document.getElementById('results');
const statusDiv = document.getElementById('status');
const progressBar = document.getElementById('progressBar');
const pdfPreview = document.getElementById('pdfPreview');
const previewTitle = document.getElementById('previewTitle');
const pdfViewer = document.getElementById('pdfViewer');
const closePreview = document.getElementById('closePreview');
let allFiles = [];
let currentWorker = null;
// 打开或创建 IndexedDB
function openDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open("PDFCacheDB", 1);
request.onupgradeneeded = function(event) {
const db = event.target.result;
if (!db.objectStoreNames.contains("pdfFiles")) {
db.createObjectStore("pdfFiles", { keyPath: "path" });
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
// 从缓存中加载数据(仅加载PDF文件)
async function loadFromCache() {
const db = await openDB();
const tx = db.transaction("pdfFiles", "readonly");
const store = tx.objectStore("pdfFiles");
const request = store.getAll();
return new Promise((resolve, reject) => {
request.onsuccess = () => {
const allFiles = request.result;
// 过滤出PDF文件
const pdfFiles = allFiles.filter(file => file.name.toLowerCase().endsWith('.pdf'));
db.close();
resolve(pdfFiles); // 只返回PDF文件
};
request.onerror = () => reject(request.error);
});
}
// 保存数据到缓存
async function saveToCache(files) {
const db = await openDB();
const tx = db.transaction("pdfFiles", "readwrite");
const store = tx.objectStore("pdfFiles");
await Promise.all(files.map(file => store.put(file)));
await tx.complete;
db.close();
}
// 显示文件列表(仅显示PDF文件)
function displayFiles(files) {
if (files.length === 0) {
resultsDiv.innerHTML = '<div class="no-results">没有找到匹配的PDF文件</div>';
return;
}
const fileList = document.createElement('ul');
fileList.className = 'file-list';
files.forEach(file => {
const fileItem = document.createElement('li');
fileItem.className = 'file-item';
fileItem.innerHTML = `
<div class="file-info">
<div class="file-name">${file.name}</div>
<div class="file-path">${file.path}</div>
</div>
<div class="file-size">${formatFileSize(file.size)}</div>
`;
fileItem.addEventListener('click', () => previewPDF(file));
fileList.appendChild(fileItem);
});
resultsDiv.innerHTML = '';
resultsDiv.appendChild(fileList);
}
// 格式化文件大小
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const units = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${parseFloat((bytes / Math.pow(1024, i)).toFixed(2))} ${units[i]}`;
}
// 预览PDF文件
function previewPDF(file) {
previewTitle.textContent = file.name;
pdfViewer.src = URL.createObjectURL(file.fileObject);
pdfPreview.style.display = 'block';
}
// 重置应用
function resetApp() {
allFiles = [];
searchInput.value = '';
resultsDiv.innerHTML = '<div class="no-results">没有找到PDF文件</div>';
statusDiv.textContent = '准备就绪,请选择包含PDF的文件夹';
progressBar.style.width = '0%';
pdfPreview.style.display = 'none';
folderInput.value = '';
updateUI();
}
// 更新UI状态
function updateUI() {
const hasFiles = allFiles.length > 0;
searchInput.disabled = !hasFiles;
clearBtn.disabled = !hasFiles;
}
// 事件监听
selectFolderBtn.addEventListener('click', () => folderInput.click());
folderInput.addEventListener('change', handleFolderSelection);
searchInput.addEventListener('input', filterFiles);
clearBtn.addEventListener('click', async () => {
resetApp();
await clearCache();
});
closePreview.addEventListener('click', () => pdfPreview.style.display = 'none');
// 文件夹选择
async function handleFolderSelection(event) {
const files = event.target.files;
const pdfFiles = Array.from(files).filter(file => file.name.toLowerCase().endsWith('.pdf')).map(file => ({
name: file.name,
path: file.webkitRelativePath || file.name,
size: file.size,
fileObject: file
}));
statusDiv.textContent = `已选择 ${pdfFiles.length} 个PDF文件`;
allFiles = pdfFiles;
saveToCache(allFiles);
filterFiles();
updateUI();
}
// 过滤文件
function filterFiles() {
const query = searchInput.value.toLowerCase();
const filtered = allFiles.filter(file => file.name.toLowerCase().includes(query));
displayFiles(filtered);
}
// 加载缓存数据并显示
const cachedFiles = await loadFromCache(); // 只加载PDF缓存文件
if (cachedFiles.length > 0) {
allFiles = cachedFiles;
statusDiv.textContent = `已加载缓存PDF文件,共 ${cachedFiles.length} 个PDF`;
filterFiles(); // 显示缓存中的PDF文件
updateUI();
} else {
statusDiv.textContent = '没有缓存的PDF文件';
}
});
</script>
</body>
版权属于:
wehg489
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
评论 (0)