コード
JavaScript
const input = document.getElementById('input'); // 元文
const output = document.getElementById('output'); // 結果
const status = document.getElementById('status'); // ステータス
const srcLang = document.getElementById('srcLang');
/**
* Translator オブジェクトを生成
*
* @param {string} src - ソース言語コード(BCP-47形式)
* @param {string} tgt - ターゲット言語コード(BCP-47形式)
* @returns {Promise} - Translator オブジェクト
*/
async function createTranslator(src, tgt) {
// ① 言語ペア対応状況を確認
const availability = await Translator.availability({ sourceLanguage: src, targetLanguage: tgt });
if (availability === 'unavailable') throw new Error('この言語ペアは未対応です。');
// ② Translator オブジェクト生成(モデル DL 進捗を監視)
return await Translator.create({
sourceLanguage: src,
targetLanguage: tgt,
monitor(m) {
m.addEventListener('downloadprogress', e => {
status.textContent = `モデルをダウンロード中… ${(e.loaded * 100).toFixed(0)} %`;
});
}
});
}
// 大量テキストを 2 kB ごとにチャンクして逐次翻訳
/*
async function translateLarge(text, translator, size = 2048) {
for (const chunk of text.match(new RegExp(`(.|[\\r\\n]){1,${size}}`, 'g'))) {
document.getElementById('output').value += await translator.translate(chunk);
}
}
*/
// localhost以外でのHTTPアクセス時の早期リジェクト
/*
if (location.protocol === 'http:') {
alert('HTTPS でアクセスしてください');
}
*/
document.getElementById('translateBtn').addEventListener('click', async () => {
const src = document.getElementById('srcLang').value.trim();
const tgt = document.getElementById('tgtLang').value.trim();
const text = document.getElementById('input').value;
if (!('Translator' in self)) {
alert('このブラウザは Translator API をサポートしていません。Chrome 138 以降をご利用ください。');
return;
}
try {
status.textContent = '準備中…';
const translator = await createTranslator(src, tgt);
status.textContent = '翻訳中…';
document.getElementById('output').value = await translator.translate(text); // ③ 翻訳実行
// translateLarge(text, translator); // 大量テキストはチャンク化して翻訳
status.textContent = '完了';
} catch (err) {
console.error(err);
alert(err.message);
status.textContent = '';
}
});