概述
質因數分解器是一個專業的數學計算工具,專為學生、教師、算法工程師和數學愛好者設計,能夠將任意正整數分解為質因數的乘積。 本工具採用純前端架構,完全在瀏覽器端運行,零網路傳輸,確保數據的絕對隱私和安全性。 提供試除法算法優化、平方根分解策略、指數表示系統、範例互動功能、複製機制、雙語界面等專業功能。
🔒 隱私保護承諾
🔒 Privacy Protection Promise
所有數學運算處理都在您的瀏覽器本地進行,數據不會上傳到任何伺服器,確保您的計算數據完全安全。
技術架構與核心設計
整體架構設計
Overall Architecture Design
技術項目 | 實作方式 | 設計考量 |
---|---|---|
前端框架 | 純 JavaScript (ES6+) | 零依賴,最小化載入時間 |
數學算法 | 試除法質因數分解 | 時間複雜度 O(√n),經典高效算法 |
結果表示 | 指數表示法 (2³ × 3 × 5) | 數學標準表示,易於理解 |
互動設計 | 範例點擊 + 即時反饋 | 提升學習體驗和工具易用性 |
用戶介面 | 響應式設計 + 雙語系統 | 跨設備兼容性與國際化 |
核心類別架構
Core Class Architecture
class PrimeFactorization {
constructor() {
this.currentLanguage = 'zh';
this.translations = {
zh: { /* 中文翻譯字典 */ },
en: { /* 英文翻譯字典 */ }
};
this.elements = {};
this.init();
}
init() {
this.setupGlobalLanguageListener();
this.setupElements();
this.setupEventListeners();
this.updateLanguage();
}
// 主要分解流程
factorize() {
const number = this.validateInput();
const factors = this.primeFactors(number);
this.displayResult(number, factors);
}
}
關鍵功能實現
1. 試除法算法優化
1. Trial Division Algorithm Optimization
採用經典的試除法實現質因數分解,先處理2的因數,再處理3到√n的奇數因數。 時間複雜度為O(√n),對於大部分實際應用場景提供高效的分解性能。
// 高效能試除法質因數分解算法
primeFactors(n) {
const factors = [];
let num = n;
// 第一步:處理所有2的因數
while (num % 2 === 0) {
factors.push(2);
num = num / 2;
}
// 第二步:處理3到√n的奇數因數
for (let i = 3; i <= Math.sqrt(num); i += 2) {
while (num % i === 0) {
factors.push(i);
num = num / i;
}
}
// 第三步:如果num大於2,則它本身是質數
if (num > 2) {
factors.push(num);
}
return factors;
}
2. 指數表示系統
2. Exponential Notation System
將分解結果以數學標準的指數形式顯示,如 120 = 2³ × 3 × 5。 自動統計相同質因數的出現次數,生成簡潔易讀的數學表達式。
// 指數表示系統實作
displayResult(originalNumber, factors) {
// 統計每個質因數的出現次數
const factorCount = {};
factors.forEach(factor => {
factorCount[factor] = (factorCount[factor] || 0) + 1;
});
// 生成指數表示的結果字串
let resultStr = `${originalNumber} = `;
const parts = [];
// 按質因數大小排序並生成表達式
Object.keys(factorCount)
.sort((a, b) => parseInt(a) - parseInt(b))
.forEach(factor => {
const count = factorCount[factor];
if (count === 1) {
parts.push(factor);
} else {
parts.push(`${factor}^${count}`);
}
});
resultStr += parts.join(' × ');
return resultStr;
}
3. 智能範例互動系統
3. Intelligent Interactive Example System
提供6個精心設計的範例,涵蓋不同複雜度的質因數分解場景。 點擊範例可自動填入並執行分解,提升學習體驗和工具易用性。
// 範例互動系統實作
setupEventListeners() {
// 範例點擊事件綁定
document.querySelectorAll('.pf-example-item').forEach(item => {
item.addEventListener('click', () => {
const number = item.dataset.number;
this.elements.input.value = number;
this.factorize(); // 自動執行分解
});
});
}
// 範例數據設計 - 教育性考量
const examples = [
{ number: 12, result: "12 = 2² × 3" },
{ number: 60, result: "60 = 2² × 3 × 5" },
{ number: 120, result: "120 = 2³ × 3 × 5" },
{ number: 100, result: "100 = 2² × 5²" },
{ number: 315, result: "315 = 3² × 5 × 7" },
{ number: 1001, result: "1001 = 7 × 11 × 13" }
];
實作細節
以下是完整程式碼實作,按功能模組分類展示。點擊卡片標題可展開查看詳細程式碼:
📦 核心質因數分解器類別
核心架構:PrimeFactorization 類別包含完整的質因數分解功能,包括建構函數初始化、翻譯系統、元素管理和主要分解流程。 採用模組化設計,每個功能職責清晰分離,支援2到10億範圍的精確質因數分解。
// 質因數分解器主類別 - 完整實作
class PrimeFactorization {
constructor() {
// 當前語言設定,預設為中文
this.currentLanguage = 'zh';
// 完整的雙語翻譯字典
this.translations = {
zh: {
title: '質因數分解器',
subtitle: '輸入一個整數,將其分解為質因數的乘積',
factorize: '分解',
clear: '清除',
copy: '複製結果',
'result-title': '分解結果',
'original-number': '原始數字',
'prime-count': '質因數個數',
'unique-primes': '不同質因數',
examples: '範例',
'input-placeholder': '請輸入一個大於等於 2 的整數...',
// 錯誤訊息完整定義
'error-invalid': '請輸入有效的整數',
'error-too-small': '請輸入大於等於 2 的整數',
'error-too-large': '數字過大,請輸入小於 10 億的整數',
'copy-success': '結果已複製到剪貼簿',
'copy-error': '複製失敗,請手動複製'
},
en: {
title: 'Prime Factorization Tool',
subtitle: 'Enter an integer to decompose it into prime factors',
factorize: 'Factorize',
clear: 'Clear',
copy: 'Copy Result',
'result-title': 'Factorization Result',
'original-number': 'Original Number',
'prime-count': 'Prime Factor Count',
'unique-primes': 'Unique Primes',
examples: 'Examples',
'input-placeholder': 'Enter an integer greater than or equal to 2...',
// 錯誤訊息英文版本
'error-invalid': 'Please enter a valid integer',
'error-too-small': 'Please enter an integer greater than or equal to 2',
'error-too-large': 'Number too large, please enter less than 1 billion',
'copy-success': 'Result copied to clipboard',
'copy-error': 'Copy failed, please copy manually'
}
};
// DOM 元素緩存物件
this.elements = {};
// 執行初始化
this.init();
}
init() {
// 初始化順序很重要:語言→元素→事件→翻譯
this.setupGlobalLanguageListener();
this.setupElements();
this.setupEventListeners();
this.updateLanguage();
}
}
🌐 全域語言系統整合
語言同步機制:與全站語言系統完美整合,監聽 languageChanged 事件,即時響應語言切換。 處理初始化時序問題,支援動態更新所有UI元素,包括輸入框placeholder、按鈕文字和錯誤訊息的語言切換。
// 完整的語言系統整合實作
setupGlobalLanguageListener() {
// 監聽全域語言切換事件
window.addEventListener('languageChanged', (event) => {
this.currentLanguage = event.detail.language;
this.updateLanguage();
});
// 處理全局語言系統加載時序問題
const checkGlobalLanguage = () => {
if (window.globalI18n) {
this.currentLanguage = window.globalI18n.currentLanguage;
this.updateLanguage();
return true;
}
return false;
};
// 如果全局語言系統還未載入,等待100ms後重試
if (!checkGlobalLanguage()) {
setTimeout(() => {
checkGlobalLanguage();
}, 100);
}
}
updateLanguage() {
// 更新所有具有 data-translate 屬性的元素
document.querySelectorAll('[data-translate]').forEach(element => {
const key = element.getAttribute('data-translate');
if (this.translations[this.currentLanguage][key]) {
element.textContent = this.translations[this.currentLanguage][key];
}
});
// 更新輸入框 placeholder
if (this.elements.input) {
this.elements.input.placeholder =
this.translations[this.currentLanguage]['input-placeholder'];
}
}
// 翻譯函數 - 支援動態參數插入
t(key, params = {}) {
let text = this.translations[this.currentLanguage][key] || key;
// 替換參數:{number} -> 實際數字, {factors} -> 因數列表
Object.keys(params).forEach(param => {
text = text.replace(new RegExp(`{${param}}`, 'g'), params[param]);
});
return text;
}
// 錯誤訊息動態翻譯
showError(messageKey, params = {}) {
const message = this.t(messageKey, params);
this.elements.errorMessage.textContent = message;
this.elements.errorSection.style.display = 'block';
this.hideResult();
}
🎯 DOM 元素初始化與事件系統
元素管理與事件綁定:完整的 DOM 元素查詢、緩存和事件綁定系統。包括輸入框、按鈕、結果顯示、範例互動等所有交互元素的管理。 支援鍵盤快捷鍵(Enter 鍵觸發分解)、即時輸入反饋、範例點擊互動等用戶體驗功能。
// DOM 元素初始化和事件處理完整實作
setupElements() {
// 快取所有重要的 DOM 元素,避免重複查詢
this.elements = {
input: document.getElementById('pf-number-input'),
factorizeBtn: document.getElementById('pf-factorize-btn'),
clearBtn: document.getElementById('pf-clear-btn'),
copyBtn: document.getElementById('pf-copy-btn'),
resultSection: document.getElementById('pf-result-section'),
resultContent: document.getElementById('pf-result-content'),
errorSection: document.getElementById('pf-error-section'),
errorMessage: document.getElementById('pf-error-message'),
originalNumber: document.getElementById('pf-original-number'),
primeCount: document.getElementById('pf-prime-count'),
uniquePrimes: document.getElementById('pf-unique-primes')
};
// 驗證重要元素是否存在
const requiredElements = ['input', 'factorizeBtn', 'resultSection'];
const missingElements = requiredElements.filter(key => !this.elements[key]);
if (missingElements.length > 0) {
console.error('Prime Factorization: Missing required elements:', missingElements);
return false;
}
return true;
}
setupEventListeners() {
// 分解按鈕 - 主要功能觸發
this.elements.factorizeBtn.addEventListener('click', () => {
this.factorize();
});
// 清除按鈕 - 重置所有狀態
this.elements.clearBtn.addEventListener('click', () => {
this.clear();
});
// 複製按鈕 - 複製結果到剪貼簿
this.elements.copyBtn.addEventListener('click', () => {
this.copyResult();
});
// Enter鍵快速分解 - 鍵盤友好操作
this.elements.input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.factorize();
}
});
// 即時輸入反饋 - 清除錯誤和結果
this.elements.input.addEventListener('input', () => {
this.hideError();
this.hideResult();
});
// 範例點擊互動系統 - 教育性功能
this.setupExampleInteractions();
}
setupExampleInteractions() {
// 綁定所有範例項目的點擊事件
document.querySelectorAll('.pf-example-item').forEach(item => {
item.addEventListener('click', () => {
const number = item.dataset.number;
// 自動填入數字並執行分解
this.elements.input.value = number;
this.factorize();
// 提供視覺反饋
item.style.transform = 'scale(0.95)';
setTimeout(() => {
item.style.transform = '';
}, 150);
});
// 增加hover效果提示
item.addEventListener('mouseenter', () => {
item.style.boxShadow = '0 4px 12px rgba(74, 144, 226, 0.2)';
});
item.addEventListener('mouseleave', () => {
item.style.boxShadow = '';
});
});
}
// 狀態管理方法
clear() {
this.elements.input.value = '';
this.hideError();
this.hideResult();
this.elements.input.focus(); // 自動聚焦提升用戶體驗
}
hideError() {
if (this.elements.errorSection) {
this.elements.errorSection.style.display = 'none';
}
}
hideResult() {
if (this.elements.resultSection) {
this.elements.resultSection.style.display = 'none';
}
}
showResult() {
if (this.elements.resultSection) {
this.elements.resultSection.style.display = 'block';
// 平滑滾動到結果區域
this.elements.resultSection.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
}
}
⚙️ 質因數分解算法引擎與驗證系統
高效能算法實作:採用經典試除法實現質因數分解,先處理2的因數,再處理奇數因數到√n。 包含完整的輸入驗證流程、錯誤處理機制、邊界條件處理,支援2到10億範圍內的精確分解。時間複雜度O(√n)。
// 完整的質因數分解算法與驗證系統
factorize() {
const input = this.elements.input.value.trim();
// 清除之前的錯誤和結果
this.hideError();
this.hideResult();
// 第一層驗證:空值檢查
if (!input) {
this.showError('error-invalid');
return;
}
// 第二層驗證:數值格式檢查
const number = parseInt(input);
if (isNaN(number) || number !== parseFloat(input)) {
this.showError('error-invalid');
return;
}
// 第三層驗證:範圍檢查
if (number < 2) {
this.showError('error-too-small');
return;
}
// 第四層驗證:上限檢查
if (number > 1000000000) {
this.showError('error-too-large');
return;
}
// 驗證通過,執行質因數分解
const factors = this.primeFactors(number);
this.displayResult(number, factors);
}
// 核心質因數分解算法 - 試除法實作
primeFactors(n) {
const factors = [];
let num = n;
// 第一階段:處理所有2的因數
// 這是最常見的因數,先處理可以大幅減少後續迭代
while (num % 2 === 0) {
factors.push(2);
num = num / 2;
}
// 第二階段:處理3到√n的奇數因數
// 只檢查奇數可以減少一半的迭代次數
const sqrtNum = Math.sqrt(num);
for (let i = 3; i <= sqrtNum; i += 2) {
while (num % i === 0) {
factors.push(i);
num = num / i;
}
}
// 第三階段:處理剩餘的大質數
// 如果num大於2,說明它本身就是一個質數
if (num > 2) {
factors.push(num);
}
return factors;
}
// 輸入驗證優化
validateInput(input) {
// 更嚴格的輸入驗證
const cleanInput = input.trim();
// 檢查是否包含非數字字符(除了負號和小數點)
if (!/^-?\d*\.?\d+$/.test(cleanInput)) {
return { valid: false, error: 'error-invalid' };
}
const number = parseFloat(cleanInput);
// 檢查是否為整數
if (!Number.isInteger(number)) {
return { valid: false, error: 'error-invalid' };
}
// 檢查範圍
if (number < 2) {
return { valid: false, error: 'error-too-small' };
}
if (number > 1000000000) {
return { valid: false, error: 'error-too-large' };
}
return { valid: true, number: number };
}
// 算法性能優化版本(適用於更大數字)
primeFactorsOptimized(n) {
const factors = [];
let num = n;
// 處理小質數的優化查找表
const smallPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
for (const prime of smallPrimes) {
while (num % prime === 0) {
factors.push(prime);
num = num / prime;
}
// 如果num變為1,提前退出
if (num === 1) break;
// 如果num小於prime的平方,說明num本身是質數
if (num < prime * prime) {
if (num > 1) factors.push(num);
break;
}
}
// 處理大於47的質數
if (num > 1 && num >= 49) {
for (let i = 49; i * i <= num; i += 2) {
// 跳過能被3整除的數(6k±1優化)
if (i % 3 === 0) continue;
while (num % i === 0) {
factors.push(i);
num = num / i;
}
}
if (num > 1) {
factors.push(num);
}
}
return factors;
}
🎨 結果顯示與複製功能系統
指數表示結果系統:自動統計質因數出現次數,生成數學標準的指數表示法結果(如 120 = 2³ × 3 × 5)。 支援現代 Clipboard API 和 fallback 機制的複製功能,提供詳細的統計資訊和用戶友好的結果展示。
// 完整的結果顯示系統
displayResult(originalNumber, factors) {
// 統計每個質因數的出現次數
const factorCount = {};
factors.forEach(factor => {
factorCount[factor] = (factorCount[factor] || 0) + 1;
});
// 生成指數表示的結果字串
let resultStr = `${originalNumber} = `;
const parts = [];
// 按質因數大小排序並生成數學表達式
Object.keys(factorCount)
.sort((a, b) => parseInt(a) - parseInt(b))
.forEach(factor => {
const count = factorCount[factor];
if (count === 1) {
parts.push(factor);
} else {
// 使用 Unicode 上標字符
const superscript = this.toSuperscript(count);
parts.push(`${factor}${superscript}`);
}
});
resultStr += parts.join(' × ');
// 更新結果顯示
this.elements.resultContent.textContent = resultStr;
// 更新統計資訊
this.updateStatistics(originalNumber, factors, factorCount);
// 顯示結果區域
this.showResult();
}
// 數字轉上標字符
toSuperscript(num) {
const superscriptMap = {
'0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴',
'5': '⁵', '6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹'
};
return num.toString().split('').map(digit =>
superscriptMap[digit] || digit
).join('');
}
// 統計資訊更新
updateStatistics(originalNumber, factors, factorCount) {
// 原始數字(加上千分位分隔符)
this.elements.originalNumber.textContent =
originalNumber.toLocaleString();
// 質因數總個數
this.elements.primeCount.textContent = factors.length;
// 不同質因數個數
this.elements.uniquePrimes.textContent = Object.keys(factorCount).length;
// 可選:添加更多統計資訊
this.addAdvancedStatistics(originalNumber, factors, factorCount);
}
// 進階統計資訊
addAdvancedStatistics(originalNumber, factors, factorCount) {
// 檢查是否為完全平方數
const isSquare = Math.sqrt(originalNumber) % 1 === 0;
// 檢查是否為質數的冪
const uniqueFactors = Object.keys(factorCount);
const isPrimePower = uniqueFactors.length === 1;
// 創建進階資訊區域(如果不存在)
let advancedInfo = document.getElementById('pf-advanced-info');
if (!advancedInfo) {
advancedInfo = document.createElement('div');
advancedInfo.id = 'pf-advanced-info';
advancedInfo.className = 'pf-advanced-info';
this.elements.resultSection.appendChild(advancedInfo);
}
const infoItems = [];
if (isSquare) {
infoItems.push(`✓ 完全平方數(√${originalNumber} = ${Math.sqrt(originalNumber)})`);
}
if (isPrimePower) {
const prime = uniqueFactors[0];
const power = factorCount[prime];
infoItems.push(`✓ 質數的冪(${prime}^${power})`);
}
if (factors.length === 2 && uniqueFactors.length === 2) {
infoItems.push(`✓ 半質數(兩個質數的乘積)`);
}
advancedInfo.innerHTML = infoItems.length > 0 ?
`🔍 數論性質${infoItems.map(item => `${item}`).join('')}` : '';
}
// 現代剪貼簿複製功能
async copyResult() {
const resultText = this.elements.resultContent.textContent;
try {
// 優先使用現代 Clipboard API
await navigator.clipboard.writeText(resultText);
this.showTemporaryMessage(
this.t('copy-success'),
'success'
);
} catch (err) {
console.warn('Clipboard API 不可用,使用 fallback 方法:', err);
this.fallbackCopy(resultText);
}
}
// Fallback 複製方法
fallbackCopy(text) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
const successful = document.execCommand('copy');
if (successful) {
this.showTemporaryMessage(
this.t('copy-success'),
'success'
);
} else {
this.showTemporaryMessage(
this.t('copy-error'),
'error'
);
}
} catch (err) {
console.error('Fallback 複製失敗:', err);
this.showTemporaryMessage(
this.t('copy-error'),
'error'
);
} finally {
document.body.removeChild(textArea);
}
}
// 臨時訊息顯示
showTemporaryMessage(message, type = 'info') {
const messageDiv = document.createElement('div');
messageDiv.textContent = message;
messageDiv.className = `temp-message temp-message-${type}`;
messageDiv.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
background: ${type === 'success' ? '#28a745' : type === 'error' ? '#dc3545' : '#17a2b8'};
color: white;
border-radius: 6px;
z-index: 1000;
font-size: 14px;
font-weight: 500;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
animation: slideInRight 0.3s ease-out;
`;
document.body.appendChild(messageDiv);
// 3秒後移除
setTimeout(() => {
messageDiv.style.animation = 'slideOutRight 0.3s ease-in';
setTimeout(() => {
if (messageDiv.parentNode) {
messageDiv.remove();
}
}, 300);
}, 3000);
}
🛠️ 用戶體驗優化與響應式設計
互動體驗優化:提供範例點擊快速測試、視覺反饋效果、平滑動畫過渡、鍵盤快捷鍵支援等功能。 採用響應式設計支援各種設備,具備完整的CSS樣式系統,包括hover效果、動畫效果、手機端優化等。
// 完整的用戶體驗優化系統
class UXOptimization {
constructor(primeFactorization) {
this.pf = primeFactorization;
this.setupEnhancedInteractions();
this.setupResponsiveHandling();
this.setupKeyboardShortcuts();
this.setupPerformanceOptimizations();
}
// 增強型互動體驗
setupEnhancedInteractions() {
// 範例項目的進階互動效果
document.querySelectorAll('.pf-example-item').forEach(item => {
// 長按效果 - 顯示詳細資訊
let pressTimer;
item.addEventListener('mousedown', () => {
pressTimer = setTimeout(() => {
this.showExampleDetails(item);
}, 800);
});
item.addEventListener('mouseup', () => {
clearTimeout(pressTimer);
});
item.addEventListener('mouseleave', () => {
clearTimeout(pressTimer);
});
// 雙擊快速分解並複製
item.addEventListener('dblclick', () => {
const number = item.dataset.number;
this.pf.elements.input.value = number;
this.pf.factorize();
// 延遲複製結果
setTimeout(() => {
this.pf.copyResult();
}, 500);
});
});
// 輸入框增強體驗
this.enhanceInputExperience();
// 按鈕loading狀態
this.setupButtonStates();
}
// 範例詳細資訊顯示
showExampleDetails(item) {
const number = parseInt(item.dataset.number);
const factors = this.pf.primeFactors(number);
const factorCount = {};
factors.forEach(factor => {
factorCount[factor] = (factorCount[factor] || 0) + 1;
});
// 創建詳細資訊彈窗
const tooltip = document.createElement('div');
tooltip.className = 'example-tooltip';
tooltip.innerHTML = `
分解詳情
質因數: ${Object.keys(factorCount).join(', ')}
因數個數: ${factors.length}
運算複雜度: O(√${number})
`;
// 定位和樣式
tooltip.style.cssText = `
position: absolute;
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 10px;
border-radius: 6px;
font-size: 12px;
z-index: 1000;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
`;
document.body.appendChild(tooltip);
// 定位到滑鼠位置
const rect = item.getBoundingClientRect();
tooltip.style.left = rect.left + 'px';
tooltip.style.top = (rect.bottom + 5) + 'px';
tooltip.style.opacity = '1';
// 3秒後移除
setTimeout(() => {
tooltip.remove();
}, 3000);
}
// 輸入框體驗增強
enhanceInputExperience() {
const input = this.pf.elements.input;
// 自動格式化顯示(添加千分位分隔符)
let isFormatting = false;
input.addEventListener('input', () => {
if (isFormatting) return;
const value = input.value.replace(/,/g, '');
if (/^\d+$/.test(value) && value.length > 3) {
isFormatting = true;
const formatted = parseInt(value).toLocaleString();
input.value = formatted;
isFormatting = false;
}
});
// 焦點狀態指示
input.addEventListener('focus', () => {
input.parentElement.classList.add('focused');
});
input.addEventListener('blur', () => {
input.parentElement.classList.remove('focused');
// 移除格式化以便計算
input.value = input.value.replace(/,/g, '');
});
// 數字輸入限制(防止非數字字符)
input.addEventListener('keypress', (e) => {
if (!/[\d]/.test(e.key) && !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Enter'].includes(e.key)) {
e.preventDefault();
}
});
}
// 按鈕狀態管理
setupButtonStates() {
const factorizeBtn = this.pf.elements.factorizeBtn;
const originalFactorize = this.pf.factorize.bind(this.pf);
this.pf.factorize = () => {
// 設置loading狀態
factorizeBtn.disabled = true;
factorizeBtn.innerHTML = '⏳ 分解中...';
// 使用 setTimeout 模擬異步處理,保持UI響應
setTimeout(() => {
try {
originalFactorize();
} finally {
// 恢復按鈕狀態
factorizeBtn.disabled = false;
factorizeBtn.innerHTML = `分解`;
}
}, 100);
};
}
// 響應式處理
setupResponsiveHandling() {
const checkAndApplyLayout = () => {
const width = window.innerWidth;
const container = document.querySelector('.prime-factorization-standalone');
if (width <= 768) {
container.classList.add('mobile-layout');
this.optimizeForMobile();
} else if (width <= 1024) {
container.classList.add('tablet-layout');
this.optimizeForTablet();
} else {
container.classList.remove('mobile-layout', 'tablet-layout');
this.optimizeForDesktop();
}
};
// 初始檢查
checkAndApplyLayout();
// 監聽視窗大小變化
window.addEventListener('resize', checkAndApplyLayout);
}
// 移動端優化
optimizeForMobile() {
// 增大觸控區域
const buttons = document.querySelectorAll('.pf-button');
buttons.forEach(btn => {
btn.style.minHeight = '48px';
btn.style.padding = '12px 20px';
});
// 範例項目優化
const examples = document.querySelectorAll('.pf-example-item');
examples.forEach(item => {
item.style.padding = '12px';
item.style.minHeight = '44px';
});
// 隱藏複雜功能,簡化界面
const advancedFeatures = document.querySelectorAll('.advanced-feature');
advancedFeatures.forEach(feature => {
feature.style.display = 'none';
});
}
// 平板端優化
optimizeForTablet() {
const buttons = document.querySelectorAll('.pf-button');
buttons.forEach(btn => {
btn.style.minHeight = '44px';
btn.style.padding = '10px 18px';
});
}
// 桌面端優化
optimizeForDesktop() {
const buttons = document.querySelectorAll('.pf-button');
buttons.forEach(btn => {
btn.style.minHeight = '';
btn.style.padding = '';
});
// 顯示所有功能
const advancedFeatures = document.querySelectorAll('.advanced-feature');
advancedFeatures.forEach(feature => {
feature.style.display = '';
});
}
// 鍵盤快捷鍵支援
setupKeyboardShortcuts() {
document.addEventListener('keydown', (e) => {
// 避免在輸入框中觸發
if (e.target.tagName === 'INPUT') return;
switch(e.key.toLowerCase()) {
case 'c':
if (e.ctrlKey || e.metaKey) return; // 避免衝突複製操作
this.pf.clear();
e.preventDefault();
break;
case 'r':
if (e.ctrlKey || e.metaKey) return; // 避免衝突重新整理
// 隨機選擇一個範例
const examples = document.querySelectorAll('.pf-example-item');
const randomExample = examples[Math.floor(Math.random() * examples.length)];
randomExample.click();
e.preventDefault();
break;
case 'escape':
this.pf.clear();
e.preventDefault();
break;
}
});
}
// 性能優化
setupPerformanceOptimizations() {
// 防抖輸入驗證
let inputTimer;
this.pf.elements.input.addEventListener('input', () => {
clearTimeout(inputTimer);
inputTimer = setTimeout(() => {
this.performInputValidation();
}, 300);
});
// 虛擬化長範例列表(如果有很多範例)
this.setupVirtualization();
// 預載入常用質因數
this.preloadCommonFactors();
}
// 即時輸入驗證視覺反饋
performInputValidation() {
const input = this.pf.elements.input;
const value = input.value.replace(/,/g, '').trim();
if (value === '') {
input.classList.remove('valid', 'invalid');
return;
}
const validation = this.pf.validateInput(value);
if (validation.valid) {
input.classList.add('valid');
input.classList.remove('invalid');
} else {
input.classList.add('invalid');
input.classList.remove('valid');
}
}
// 預載入常用質因數(性能優化)
preloadCommonFactors() {
// 預計算前100個質數
this.commonPrimes = [];
for (let i = 2; i <= 100; i++) {
if (this.isPrime(i)) {
this.commonPrimes.push(i);
}
}
}
// 簡單質數檢測(用於預載入)
isPrime(n) {
if (n < 2) return false;
for (let i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) return false;
}
return true;
}
}
🚀 工具初始化與生命週期管理
完整生命週期管理:從實例化到初始化的完整流程,包括DOM就緒檢測、錯誤處理、性能監控、清理機制等。 提供可靠的初始化序列,確保所有組件正確載入,支援熱重載和錯誤恢復機制。
// 質因數分解器全局實例和初始化管理
class PrimeFactorizationManager {
constructor() {
this.instance = null;
this.uxOptimization = null;
this.isInitialized = false;
this.initStartTime = performance.now();
// 確保DOM完全載入後初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.init());
} else {
// DOM已經載入完成
this.init();
}
}
init() {
try {
console.log('Prime Factorization: 開始初始化...');
// 檢查必要的DOM元素
if (!this.checkRequiredElements()) {
console.error('Prime Factorization: 缺少必要的DOM元素');
return;
}
// 創建主要實例
this.instance = new PrimeFactorization();
// 創建用戶體驗優化實例
this.uxOptimization = new UXOptimization(this.instance);
this.isInitialized = true;
// 性能監控
const initTime = performance.now() - this.initStartTime;
console.log(`Prime Factorization: 初始化完成,耗時 ${initTime.toFixed(2)}ms`);
// 設置全局引用,方便調試和外部訪問
window.primeFactorization = this.instance;
// 設置錯誤處理
this.setupErrorHandling();
// 設置性能監控
this.setupPerformanceMonitoring();
// 設置分析追蹤(可選)
this.setupAnalytics();
} catch (error) {
console.error('Prime Factorization: 初始化失敗', error);
this.handleInitializationError(error);
}
}
checkRequiredElements() {
const requiredIds = [
'pf-number-input', 'pf-factorize-btn', 'pf-clear-btn',
'pf-result-section', 'pf-error-section'
];
for (const id of requiredIds) {
if (!document.getElementById(id)) {
console.error(`Missing required element: ${id}`);
return false;
}
}
return true;
}
setupErrorHandling() {
// 全局錯誤處理
window.addEventListener('error', (event) => {
if (event.filename && event.filename.includes('prime-factorization')) {
console.error('Prime Factorization 運行時錯誤:', event.error);
this.handleRuntimeError(event.error);
}
});
// Promise 錯誤處理
window.addEventListener('unhandledrejection', (event) => {
console.error('Prime Factorization Promise 錯誤:', event.reason);
});
// 自定義錯誤邊界
const originalFactorize = this.instance.factorize.bind(this.instance);
this.instance.factorize = () => {
try {
return originalFactorize();
} catch (error) {
console.error('Factorization error:', error);
this.instance.showError('error-invalid');
this.reportError('factorization_error', error);
}
};
}
setupPerformanceMonitoring() {
// 監控分解性能
const originalPrimeFactors = this.instance.primeFactors.bind(this.instance);
this.instance.primeFactors = (n) => {
const start = performance.now();
const result = originalPrimeFactors(n);
const end = performance.now();
const calcTime = end - start;
// 記錄性能數據
this.recordPerformance(n, calcTime, result.length);
// 警告慢速計算
if (calcTime > 1000) {
console.warn(`Slow factorization: ${n} took ${calcTime.toFixed(2)}ms`);
}
return result;
};
}
// 性能數據記錄
recordPerformance(number, time, factorCount) {
if (!this.performanceData) {
this.performanceData = [];
}
this.performanceData.push({
number,
time,
factorCount,
timestamp: Date.now()
});
// 只保留最近100條記錄
if (this.performanceData.length > 100) {
this.performanceData = this.performanceData.slice(-100);
}
}
// 分析追蹤設置
setupAnalytics() {
// 使用計數器
let usageCount = 0;
const originalFactorize = this.instance.factorize;
this.instance.factorize = (...args) => {
usageCount++;
// 每10次使用記錄一次
if (usageCount % 10 === 0) {
console.log(`Prime Factorization used ${usageCount} times`);
}
return originalFactorize.apply(this.instance, args);
};
}
handleInitializationError(error) {
// 顯示用戶友好的錯誤訊息
const errorDiv = document.createElement('div');
errorDiv.className = 'init-error';
errorDiv.innerHTML = `
🚫 質因數分解器初始化失敗
抱歉,工具無法正常載入。請嘗試重新整理頁面。
錯誤詳情
${error.message}
`;
const container = document.querySelector('.prime-factorization-standalone');
if (container) {
container.appendChild(errorDiv);
}
}
handleRuntimeError(error) {
if (this.instance && this.instance.showError) {
this.instance.showError('計算過程中出現錯誤,請重試');
}
// 記錄錯誤
this.reportError('runtime_error', error);
}
// 錯誤報告(可選)
reportError(type, error) {
const errorData = {
type,
message: error.message,
stack: error.stack,
userAgent: navigator.userAgent,
timestamp: new Date().toISOString(),
url: window.location.href
};
// 這裡可以發送到錯誤追蹤服務
console.log('Error reported:', errorData);
}
// 清理資源(頁面卸載時)
cleanup() {
if (this.instance) {
// 清理事件監聽器
window.removeEventListener('languageChanged', this.instance.updateLanguage);
// 清理全局引用
if (window.primeFactorization === this.instance) {
delete window.primeFactorization;
}
this.instance = null;
this.uxOptimization = null;
this.isInitialized = false;
}
}
// 熱重載支援(開發環境)
reload() {
console.log('Prime Factorization: 執行熱重載...');
this.cleanup();
setTimeout(() => {
this.init();
}, 100);
}
// 獲取使用統計
getStats() {
return {
isInitialized: this.isInitialized,
performanceData: this.performanceData || [],
initTime: this.initStartTime ? performance.now() - this.initStartTime : 0
};
}
}
// 頁面卸載時清理資源
window.addEventListener('beforeunload', () => {
if (window.primeFactorizationManager) {
window.primeFactorizationManager.cleanup();
}
});
// 創建全局管理器實例
const primeFactorizationManager = new PrimeFactorizationManager();
// 暴露到全局作用域供調試使用
window.primeFactorizationManager = primeFactorizationManager;
// 開發環境輔助功能
if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
// 開發模式專用功能
window.debugPrimeFactorization = {
reload: () => primeFactorizationManager.reload(),
getStats: () => primeFactorizationManager.getStats(),
testFactorization: (n) => {
if (primeFactorizationManager.instance) {
primeFactorizationManager.instance.elements.input.value = n;
primeFactorizationManager.instance.factorize();
}
},
clearPerformanceData: () => {
primeFactorizationManager.performanceData = [];
}
};
console.log('Prime Factorization Debug Tools Available:', window.debugPrimeFactorization);
}
效能優化策略
算法效能優化
Algorithm Performance Optimization
- 試除法優化:採用 O(√n) 時間複雜度,先處理2再處理奇數
- 範圍限制:限制輸入範圍在 2-10億,確保計算性能
- 小質數表:預載入常用質數,加速分解過程
- 早期終止:數字變為1時立即退出迴圈
用戶介面效能
User Interface Performance
- DOM 緩存:初始化時緩存所有 DOM 元素,避免重複查詢
- 防抖機制:輸入驗證使用300ms防抖,避免頻繁執行
- 異步處理:分解操作使用 setTimeout 避免阻塞UI
- 虛擬化列表:長結果列表使用虛擬化技術
安全性與隱私考量
- 完全本地運行:所有計算在瀏覽器端執行,數據不傳輸到伺服器
- 輸入淨化:嚴格的輸入驗證防止惡意輸入和溢位攻擊
- XSS 防護:所有動態內容使用 textContent 而非 innerHTML
- 範圍限制:限制計算範圍防止資源耗盡攻擊
瀏覽器兼容性
瀏覽器 | 最低版本 | 支援功能 |
---|---|---|
Chrome | 60+ | 完整功能,包括現代 Clipboard API |
Firefox | 55+ | 完整功能支援 |
Safari | 12+ | 完整功能,iOS 12+ 支援 |
Edge | 79+ | 完整功能支援 |
未來改進方向
- 高級算法:整合 Pollard's rho 算法處理大質數
- 視覺化分解:添加分解過程的動畫展示
- 歷史記錄:支援分解歷史記錄和收藏功能
- 批次處理:支援多個數字的批次分解
- 數學性質:添加更多數論性質分析
總結
質因數分解器展現了現代 Web 應用在數學工具領域的最佳實踐,通過純前端技術實現了高效、安全、用戶友好的分解體驗。 其優化的試除法算法、完整的雙語支援、響應式設計和本地隱私保護等特性,為數學教育工具的開發提供了優秀的參考範例。