// 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);
// --- 创建用于绘制二维码的