pdf.js无法渲染PDF且模态框不加载,求文本选中日志实现方案
解决模态框加载、PDF渲染验证及选中文本日志问题
一、修复模态框加载与PDF渲染验证
1. 排查模态框基础触发逻辑
如果用原生JS实现模态框,确保触发按钮的点击事件绑定正确,且模态框的显示/隐藏逻辑无错误:
// 原生JS模态框触发示例 const openModalBtn = document.getElementById('open-modal'); const modal = document.getElementById('pdf-modal'); const closeModalBtn = document.getElementById('close-modal'); openModalBtn.addEventListener('click', () => { modal.style.display = 'block'; }); closeModalBtn.addEventListener('click', () => { modal.style.display = 'none'; }); // 点击遮罩层关闭模态框 window.addEventListener('click', (e) => { if (e.target === modal) { modal.style.display = 'none'; } });
如果用Bootstrap等框架,确保正确引入框架JS/CSS,或手动初始化模态框:
// Bootstrap 5 手动初始化模态框 const modal = new bootstrap.Modal(document.getElementById('pdf-modal')); openModalBtn.addEventListener('click', () => modal.show());
2. 验证PDF渲染流程
第一步:确保上传的PDF生成有效Blob URL
上传文件后必须将File对象转为Blob URL,才能嵌入页面:
const fileInput = document.getElementById('pdf-upload'); const pdfEmbed = document.getElementById('pdf-embed'); fileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (!file || file.type !== 'application/pdf') return; // 生成Blob URL并验证有效性 const blobUrl = URL.createObjectURL(file); console.log('生成的Blob URL:', blobUrl); // 复制到地址栏确认能否打开PDF // 赋值给embed元素并打开模态框 pdfEmbed.src = blobUrl; modal.style.display = 'block'; });
第二步:验证PDF容器配置
确保<embed>或<iframe>属性正确设置:
<!-- 模态框内的PDF容器 --> <div id="pdf-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5);"> <div style="width:80%; height:80%; margin:5% auto; background:white; padding:20px;"> <button id="close-modal">关闭</button> <embed id="pdf-embed" type="application/pdf" width="100%" height="90%"> </div> </div>
若原生embed无法渲染,可换用<iframe>,或直接使用PDF.js(更稳定且支持文本选择监听)。
二、实现PDF选中文本的控制台日志功能
原生PDF嵌入(embed/iframe)无法直接监听文本选择事件,建议使用PDF.js实现,它会将PDF渲染为可交互DOM元素,便于捕获选择:
1. 基础实现步骤
第一步:引入PDF.js
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
第二步:用PDF.js渲染上传的PDF
const pdfContainer = document.getElementById('pdf-container'); // 模态框内的空容器 let pdfDoc = null; fileInput.addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file || file.type !== 'application/pdf') return; // 读取文件为ArrayBuffer const arrayBuffer = await file.arrayBuffer(); // 加载PDF文档 pdfDoc = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; // 渲染第一页(如需全页渲染,循环调用renderPage即可) renderPage(1); // 打开模态框 modal.style.display = 'block'; }); // 渲染单页PDF async function renderPage(pageNum) { const page = await pdfDoc.getPage(pageNum); const viewport = page.getViewport({ scale: 1.5 }); // 创建canvas元素并设置尺寸 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = viewport.width; canvas.height = viewport.height; pdfContainer.appendChild(canvas); // 将页面渲染到canvas await page.render({ canvasContext: ctx, viewport }).promise; // 绑定文本选择监听 setupTextSelectionListener(); }
第三步:监听文本选择并打印到控制台
function setupTextSelectionListener() { document.addEventListener('selectionchange', () => { const selection = window.getSelection(); const selectedText = selection.toString().trim(); if (selectedText) { console.log('选中的PDF文本:', selectedText); } }); }
若仅需监听PDF区域内的选择,可给pdfContainer绑定mouseup事件:
pdfContainer.addEventListener('mouseup', () => { const selection = window.getSelection(); const selectedText = selection.toString().trim(); if (selectedText) { console.log('选中的PDF文本:', selectedText); } });
三、额外排查点
- 检查浏览器控制台的警告信息,比如PDF损坏、跨域问题(本地测试需用服务器打开HTML,不要直接双击打开)。
- 测试不同PDF文件,排除上传文件本身损坏的可能。
- 检查模态框的
z-index是否被其他元素覆盖,导致看不见但实际已加载。
内容的提问来源于stack exchange,提问作者ItsCoder1092
相关产品推荐
相关产品推荐

