// main.js // 当整个页面的HTML内容加载完成后,执行此函数 document.addEventListener('DOMContentLoaded', () => { // 获取页面上的关键元素 const textInput = document.getElementById('text-input'); const generateBtn = document.getElementById('generate-btn'); const qrcodeContainer = document.getElementById('qrcode-container'); // 为“生成二维码”按钮添加点击事件监听器 generateBtn.addEventListener('click', () => { // 获取输入框中的文本,并用 trim() 清除前后的空白字符 const text = textInput.value.trim(); // 在生成新的二维码之前,清空之前可能存在的旧二维码 qrcodeContainer.innerHTML = ''; // 如果文本为空,则不执行任何操作 if (!text) { console.log('输入内容为空,已中止生成。'); return; } // --- 智能分割逻辑 --- // 我们使用一个固定的字节数上限。这是二维码国标(GB/T 18284-2000)规定的, // 在版本40、纠错等级H(最高)的情况下,最大可容纳的字节数。 const MAX_BYTES_PER_QR = 1273; const textEncoder = new TextEncoder(); // 用于计算字符串的UTF-8字节长度 const chunks = []; let currentPos = 0; while (currentPos < text.length) { // 使用二分查找来高效地找到当前位置后,能容纳在单个二维码中的最长子字符串 let low = currentPos; let high = text.length; let bestEnd = currentPos; while (low <= high) { const mid = Math.floor((low + high) / 2); // mid不能停在原点,否则会死循环 if (mid === currentPos) { low = mid + 1; continue; } const substring = text.substring(currentPos, mid); const byteLength = textEncoder.encode(substring).length; if (byteLength <= MAX_BYTES_PER_QR) { // 如果当前子字符串的字节长度在限制内,说明它是一个有效的块 // 我们记录下这个有效的终点,并尝试寻找更长的块 bestEnd = mid; low = mid + 1; } else { // 如果超出了字节限制,则需要缩短子字符串的长度 high = mid - 1; } } // 处理极端情况:如果单个字符的字节数就超过了上限,我们也只能把它单独作为一个块 if (bestEnd === currentPos && currentPos < text.length) { bestEnd = currentPos + 1; } // 将找到的最佳块添加到数组中 chunks.push(text.substring(currentPos, bestEnd)); // 从新的位置继续寻找下一个块 currentPos = bestEnd; } const totalChunks = chunks.length; console.log(`总字符数: ${text.length},通过智能分割,将生成 ${totalChunks} 个二维码。`); // --- 循环生成二维码 --- chunks.forEach((chunk, i) => { // --- 创建包裹单个二维码及其标签的容器 --- const itemDiv = document.createElement('div'); itemDiv.className = 'qrcode-item'; // --- 创建并添加序号标签 --- const label = document.createElement('p'); label.className = 'qrcode-label'; label.textContent = totalChunks > 1 ? `二维码 ${i + 1}/${totalChunks}` : '二维码'; itemDiv.appendChild(label); // --- 创建用于绘制二维码的 元素 --- const canvas = document.createElement('canvas'); itemDiv.appendChild(canvas); qrcodeContainer.appendChild(itemDiv); // --- 使用 QRCode.toCanvas 方法将二维码绘制到指定的 canvas 上 --- QRCode.toCanvas( canvas, chunk, { margin: 2, // 二维码边距 color: { dark: '#000000', // 二维码深色部分 light: '#ffffff', // 二维码浅色部分 }, errorCorrectionLevel: 'H', // 纠错级别: 'L', 'M', 'Q', 'H' }, function (error) { if (error) { console.error(`为第 ${i + 1} 块内容生成二维码时出错:`, error); // 如果生成失败,在 canvas 上显示错误信息 const ctx = canvas.getContext('2d'); if (ctx) { // 设置一个基础尺寸,以防canvas没有宽高 canvas.width = 400; canvas.height = 400; ctx.font = '20px Arial'; ctx.fillStyle = 'red'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText('二维码生成失败', canvas.width / 2, canvas.height / 2); } } else { console.log(`已成功为第 ${i + 1} 块内容生成二维码。`); } } ); }); }); });