Make some big updates
This commit is contained in:
159
script.js
159
script.js
@@ -1,137 +1,130 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 1. Initialization
|
||||
const modeSelector = document.getElementById('mode-selector');
|
||||
// --- GLOBALS ---
|
||||
const qrContainer = document.getElementById('qr-container');
|
||||
const downloadBtn = document.getElementById('btn-download');
|
||||
|
||||
// Forms
|
||||
const forms = {
|
||||
text: document.getElementById('form-text'),
|
||||
wifi: document.getElementById('form-wifi'),
|
||||
email: document.getElementById('form-email')
|
||||
};
|
||||
// Inputs
|
||||
const modeSelector = document.getElementById('mode-selector');
|
||||
const optEcc = document.getElementById('opt-ecc');
|
||||
const optSize = document.getElementById('opt-size');
|
||||
const optFg = document.getElementById('opt-fg');
|
||||
const optBg = document.getElementById('opt-bg');
|
||||
|
||||
// Hex Labels (for display)
|
||||
const hexFg = document.getElementById('hex-fg');
|
||||
const hexBg = document.getElementById('hex-bg');
|
||||
|
||||
// Inputs collection for event binding
|
||||
const allInputs = document.querySelectorAll('input, textarea, select');
|
||||
|
||||
// Initialize QR Library
|
||||
// Using CorrectLevel.H (High) as requested
|
||||
let qrcode = new QRCode(qrContainer, {
|
||||
width: 256,
|
||||
height: 256,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRCode.CorrectLevel.H
|
||||
});
|
||||
|
||||
// 2. State & Logic
|
||||
let currentMode = 'text';
|
||||
let qrcodeObj = null;
|
||||
let debounceTimer;
|
||||
|
||||
// Switch Input Forms
|
||||
function switchMode(newMode) {
|
||||
currentMode = newMode;
|
||||
|
||||
// Hide all forms
|
||||
Object.values(forms).forEach(form => form.classList.remove('active'));
|
||||
|
||||
// Show selected form
|
||||
forms[newMode].classList.add('active');
|
||||
// --- LOGIC ---
|
||||
|
||||
// Trigger update immediately
|
||||
function createQRInstance() {
|
||||
qrContainer.innerHTML = '';
|
||||
|
||||
// Validation: Clamp size to prevent crashing browser
|
||||
let size = parseInt(optSize.value);
|
||||
if (isNaN(size) || size < 64) size = 64;
|
||||
if (size > 4000) size = 4000;
|
||||
|
||||
const ecc = QRCode.CorrectLevel[optEcc.value];
|
||||
const colorDark = optFg.value;
|
||||
const colorLight = optBg.value;
|
||||
|
||||
// Update Hex Labels
|
||||
hexFg.textContent = colorDark;
|
||||
hexBg.textContent = colorLight;
|
||||
|
||||
qrcodeObj = new QRCode(qrContainer, {
|
||||
width: size,
|
||||
height: size,
|
||||
colorDark : colorDark,
|
||||
colorLight : colorLight,
|
||||
correctLevel : ecc
|
||||
});
|
||||
|
||||
updateQR();
|
||||
}
|
||||
|
||||
// String Builders
|
||||
function getDataString() {
|
||||
if (currentMode === 'text') {
|
||||
const mode = modeSelector.value;
|
||||
if (mode === 'text') {
|
||||
return document.getElementById('inp-text').value;
|
||||
}
|
||||
|
||||
else if (currentMode === 'wifi') {
|
||||
} else if (mode === 'wifi') {
|
||||
const ssid = document.getElementById('inp-wifi-ssid').value;
|
||||
const pass = document.getElementById('inp-wifi-pass').value;
|
||||
const type = document.getElementById('inp-wifi-type').value;
|
||||
|
||||
if (!ssid) return ''; // SSID is minimum requirement
|
||||
|
||||
// Format: WIFI:S:MyNetwork;T:WPA;P:mypassword;;
|
||||
// Note: Special characters in SSID/Pass should ideally be escaped,
|
||||
// but standard readers handle raw strings well usually.
|
||||
// Adding escape for semicolons/colons is safer practice:
|
||||
if (!ssid) return '';
|
||||
const cleanSSID = ssid.replace(/([\\;,:])/g, '\\$1');
|
||||
const cleanPass = pass.replace(/([\\;,:])/g, '\\$1');
|
||||
|
||||
return `WIFI:S:${cleanSSID};T:${type};P:${cleanPass};;`;
|
||||
}
|
||||
|
||||
else if (currentMode === 'email') {
|
||||
} else if (mode === 'email') {
|
||||
const to = document.getElementById('inp-email-to').value;
|
||||
const sub = document.getElementById('inp-email-sub').value;
|
||||
const body = document.getElementById('inp-email-body').value;
|
||||
|
||||
if (!to) return '';
|
||||
|
||||
return `mailto:${to}?subject=${encodeURIComponent(sub)}&body=${encodeURIComponent(body)}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// QR Update Logic
|
||||
function updateQR() {
|
||||
if (!qrcodeObj) return;
|
||||
const data = getDataString();
|
||||
|
||||
if (!data || data.trim() === '') {
|
||||
qrcode.clear(); // Clear the code
|
||||
qrcodeObj.clear();
|
||||
downloadBtn.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
downloadBtn.disabled = false;
|
||||
|
||||
// Visual Stability: Fade opacity slightly during update logic if desired,
|
||||
// but qrcode.makeCode is instantaneous on small data.
|
||||
// We ensure high performance by not recreating the object.
|
||||
qrcode.makeCode(data);
|
||||
qrcodeObj.makeCode(data);
|
||||
}
|
||||
|
||||
// Debounce Function
|
||||
function handleInput() {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(() => {
|
||||
updateQR();
|
||||
}, 300); // 300ms delay
|
||||
}
|
||||
// --- EVENT LISTENERS ---
|
||||
|
||||
// 3. Event Listeners
|
||||
|
||||
// Mode Switching
|
||||
modeSelector.addEventListener('change', (e) => switchMode(e.target.value));
|
||||
|
||||
// Input Detection (Auto-Update)
|
||||
allInputs.forEach(input => {
|
||||
// Skip mode selector as it has its own handler
|
||||
if(input.id !== 'mode-selector') {
|
||||
input.addEventListener('input', handleInput);
|
||||
}
|
||||
// 1. Config Changes (Re-create instance)
|
||||
// We listen to 'change' for colors (happens when picker closes)
|
||||
// and 'input' (happens while dragging) depending on preference.
|
||||
// 'input' is smoother but more CPU intensive. Let's use 'input'.
|
||||
[optEcc, optSize, optFg, optBg].forEach(el => {
|
||||
el.addEventListener('input', () => {
|
||||
// Debounce the recreation slightly to prevent lag during color dragging
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(createQRInstance, 100);
|
||||
});
|
||||
});
|
||||
|
||||
// Download Logic
|
||||
// 2. Mode Switching
|
||||
modeSelector.addEventListener('change', (e) => {
|
||||
const newMode = e.target.value;
|
||||
document.querySelectorAll('.input-form').forEach(f => f.classList.remove('active'));
|
||||
document.getElementById(`form-${newMode}`).classList.add('active');
|
||||
updateQR();
|
||||
});
|
||||
|
||||
// 3. Data Entry (Text, WiFi, Email)
|
||||
document.querySelectorAll('.input-form').forEach(form => {
|
||||
form.addEventListener('input', () => {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(updateQR, 300);
|
||||
});
|
||||
});
|
||||
|
||||
// 4. Download
|
||||
downloadBtn.addEventListener('click', () => {
|
||||
// Find the image generated by qrcode.js
|
||||
const img = qrContainer.querySelector('img');
|
||||
|
||||
if (img && img.src) {
|
||||
const link = document.createElement('a');
|
||||
link.href = img.src;
|
||||
link.download = `qrcode-${currentMode}-${Date.now()}.png`;
|
||||
link.download = `qrcode-${Date.now()}.png`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
});
|
||||
|
||||
// Initial run
|
||||
switchMode('text');
|
||||
// Init
|
||||
createQRInstance();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user