Last active
July 23, 2025 07:46
-
-
Save Shinichi-Ohki/adea3b119c1908f910e27191a79be84e to your computer and use it in GitHub Desktop.
ページ内の全角英数字・記号を半角に自動変換
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>全角英数字テストページ</title> | |
<style> | |
body { | |
font-family: 'Hiragino Sans', 'Yu Gothic', sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
line-height: 1.6; | |
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
} | |
.newspaper-article { | |
background: white; | |
padding: 30px; | |
margin: 20px 0; | |
border-radius: 8px; | |
box-shadow: 0 4px 12px rgba(0,0,0,0.1); | |
} | |
.headline { | |
font-size: 24px; | |
font-weight: bold; | |
margin-bottom: 15px; | |
color: #333; | |
border-bottom: 3px solid #007acc; | |
padding-bottom: 10px; | |
} | |
.dateline { | |
color: #666; | |
font-size: 14px; | |
margin-bottom: 20px; | |
} | |
.test-section { | |
margin: 25px 0; | |
padding: 20px; | |
background: #f9f9f9; | |
border-left: 4px solid #007acc; | |
} | |
.test-section h3 { | |
color: #007acc; | |
margin-top: 0; | |
} | |
input, textarea { | |
width: 100%; | |
padding: 10px; | |
margin: 10px 0; | |
border: 2px solid #ddd; | |
border-radius: 4px; | |
font-size: 16px; | |
} | |
.url-sample { | |
background: #e8f4f8; | |
padding: 15px; | |
border-radius: 4px; | |
font-family: monospace; | |
word-break: break-all; | |
} | |
.dynamic-content { | |
background: #fff3cd; | |
padding: 15px; | |
border-radius: 4px; | |
margin: 10px 0; | |
} | |
.add-content-btn { | |
background: #007acc; | |
color: white; | |
padding: 10px 20px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 16px; | |
} | |
.add-content-btn:hover { | |
background: #005fa3; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>📰 全角英数字テストページ</h1> | |
<p>このページは、全角→半角変換スクリプトの動作確認用です〜♪</p> | |
<div class="newspaper-article"> | |
<div class="headline"> | |
AI技術の進歩が止まらない!2025年の最新動向 | |
</div> | |
<div class="dateline"> | |
2025年7月23日 午後3時30分 | |
</div> | |
<p> | |
人工知能(AI)の発展が目覚ましい勢いで進んでいる。特にGPT-4やClaudeなどの大規模言語モデルは、 | |
従来のIT業界の常識を覆している。 | |
</p> | |
<p> | |
調査によると、2024年から2025年にかけて、AI関連の投資額は約30%増加。 | |
特にスタートアップ企業への投資が活発で、シリーズAラウンドでの調達額は平均500万ドルに達している。 | |
</p> | |
</div> | |
<div class="test-section"> | |
<h3>🔗 URLテスト</h3> | |
<div class="url-sample"> | |
https://www.example.com/article/2025/07/23/ai-news.html | |
</div> | |
<div class="url-sample"> | |
http://localhost:8080/api/v1/data?id=123&type=json | |
</div> | |
</div> | |
<div class="test-section"> | |
<h3>💻 コードサンプル</h3> | |
<pre><code>function convertText(str) { | |
return str.replace(/[A-Za-z0-9]/g, function(c) { | |
return String.fromCharCode(c.charCodeAt(0) - 0xFEE0); | |
}y; | |
}</code></pre> | |
</div> | |
<div class="test-section"> | |
<h3>📊 数値・記号テスト</h3> | |
<p> | |
売上高:¥1,234,567,890円(前年比+15.3%)<br> | |
ユーザー数:10,000,000人(#1シェア)<br> | |
評価:★★★★☆(4.2/5.0)<br> | |
メール:info@example.com | |
</p> | |
</div> | |
<div class="test-section"> | |
<h3>✍️ 入力フィールドテスト</h3> | |
<p>以下のフィールドに全角英数字を入力してリアルタイム変換をテスト!</p> | |
<input type="text" placeholder="ここに全角英数字を入力してね(例:HELLO123)"> | |
<textarea rows="3" placeholder="長い文章のテスト用 | |
https://example.comなどのURLも試してみて!"></textarea> | |
</div> | |
<div class="test-section"> | |
<h3>🔄 動的コンテンツテスト</h3> | |
<button class="add-content-btn" onclick="addDynamicContent()">全角コンテンツを追加</button> | |
<div id="dynamic-area"></div> | |
</div> | |
<script> | |
let counter = 1; | |
function addDynamicContent() { | |
const area = document.getElementById('dynamic-area'); | |
const newContent = document.createElement('div'); | |
newContent.className = 'dynamic-content'; | |
newContent.innerHTML = ` | |
<strong>動的追加コンテンツ #${counter}</strong><br> | |
追加時刻:2025年07月23日 15:30:${String(counter).padStart(2, '0')}<br> | |
URL:https://example.com/dynamic-${counter} | |
`; | |
area.appendChild(newContent); | |
counter++; | |
} | |
// ページ読み込み完了後のメッセージ | |
window.addEventListener('load', function() { | |
console.log('🚀 テストページ読み込み完了!スクリプトの動作を確認してね〜'); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 全角英数字→半角変換 | |
// @namespace http://tampermonkey.net/ | |
// @version 2.01 | |
// @description ページ内の全角英数字・記号を半角に自動変換 | |
// @author You | |
// @match *://*/* | |
// @grant none | |
// @run-at document-end | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// 全角→半角変換関数 | |
function convertFullwidthToHalfwidth(text) { | |
return text | |
// 全角英数字(安全な範囲のみ) | |
.replace(/[A-Za-z0-9]/g, char => | |
String.fromCharCode(char.charCodeAt(0) - 0xFEE0)) | |
// 全角記号(個別に安全に変換) | |
.replace(/!/g, '!') | |
.replace(/?/g, '?') | |
.replace(/./g, '.') | |
.replace(/,/g, ',') | |
.replace(/:/g, ':') | |
.replace(/;/g, ';') | |
.replace(/"/g, '"') | |
.replace(/{/g, '{') | |
.replace(/}/g, '}') | |
.replace(/[/g, '[') | |
.replace(/]/g, ']') | |
.replace(/(/g, '(') | |
.replace(/)/g, ')') | |
.replace(/%/g, '%') | |
.replace(/&/g, '&') | |
.replace(/@/g, '@') | |
.replace(/#/g, '#') | |
.replace(/$/g, '$') | |
// テキストノードを処理 | |
function processTextNodes(node) { | |
if (node.nodeType === Node.TEXT_NODE) { | |
const original = node.textContent; | |
const converted = convertFullwidthToHalfwidth(original); | |
if (original !== converted) { | |
node.textContent = converted; | |
} | |
} else if (node.nodeType === Node.ELEMENT_NODE) { | |
// スクリプト・スタイル・入力欄は除外 | |
if (!['SCRIPT', 'STYLE', 'INPUT', 'TEXTAREA'].includes(node.tagName)) { | |
Array.from(node.childNodes).forEach(processTextNodes); | |
} | |
} | |
} | |
// 入力フィールドのリアルタイム変換 | |
function setupInputConversion() { | |
document.querySelectorAll('input[type="text"], input[type="search"], textarea') | |
.forEach(input => { | |
input.addEventListener('input', function() { | |
const pos = this.selectionStart; | |
const original = this.value; | |
const converted = convertFullwidthToHalfwidth(original); | |
if (original !== converted) { | |
this.value = converted; | |
this.setSelectionRange(pos, pos); | |
} | |
}); | |
}); | |
} | |
// 初期実行 | |
processTextNodes(document.body); | |
setupInputConversion(); | |
// 動的コンテンツ監視 | |
new MutationObserver(mutations => { | |
mutations.forEach(mutation => { | |
mutation.addedNodes.forEach(node => { | |
if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE) { | |
processTextNodes(node); | |
} | |
}); | |
}); | |
}).observe(document.body, { childList: true, subtree: true }); | |
// 新しい入力フィールド監視 | |
new MutationObserver(() => setupInputConversion()) | |
.observe(document.body, { childList: true, subtree: true }); | |
// デバッグ用 | |
window.convertFullwidth = () => { | |
processTextNodes(document.body); | |
console.log('🔄 手動変換完了'); | |
}; | |
})();) | |
.replace(/+/g, '+') | |
.replace(/-/g, '-') | |
.replace(/=/g, '=') | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(///g, '/') | |
.replace(/\/g, '\\') | |
.replace(/|/g, '|') | |
.replace(/~/g, '~') | |
.replace(/^/g, '^') | |
.replace(/`/g, '`') | |
// 全角スペース | |
.replace(/ /g, ' '); | |
} | |
// テキストノードを処理 | |
function processTextNodes(node) { | |
if (node.nodeType === Node.TEXT_NODE) { | |
const original = node.textContent; | |
const converted = convertFullwidthToHalfwidth(original); | |
if (original !== converted) { | |
node.textContent = converted; | |
} | |
} else if (node.nodeType === Node.ELEMENT_NODE) { | |
// スクリプト・スタイル・入力欄は除外 | |
if (!['SCRIPT', 'STYLE', 'INPUT', 'TEXTAREA'].includes(node.tagName)) { | |
Array.from(node.childNodes).forEach(processTextNodes); | |
} | |
} | |
} | |
// 入力フィールドのリアルタイム変換 | |
function setupInputConversion() { | |
document.querySelectorAll('input[type="text"], input[type="search"], textarea') | |
.forEach(input => { | |
input.addEventListener('input', function() { | |
const pos = this.selectionStart; | |
const original = this.value; | |
const converted = convertFullwidthToHalfwidth(original); | |
if (original !== converted) { | |
this.value = converted; | |
this.setSelectionRange(pos, pos); | |
} | |
}); | |
}); | |
} | |
// 初期実行 | |
processTextNodes(document.body); | |
setupInputConversion(); | |
// 動的コンテンツ監視 | |
new MutationObserver(mutations => { | |
mutations.forEach(mutation => { | |
mutation.addedNodes.forEach(node => { | |
if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE) { | |
processTextNodes(node); | |
} | |
}); | |
}); | |
}).observe(document.body, { childList: true, subtree: true }); | |
// 新しい入力フィールド監視 | |
new MutationObserver(() => setupInputConversion()) | |
.observe(document.body, { childList: true, subtree: true }); | |
// デバッグ用 | |
window.convertFullwidth = () => { | |
processTextNodes(document.body); | |
console.log('🔄 手動変換完了'); | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment