kensaku-1
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>【確実な解決策】contenteditable と scrollIntoView</title>
<style>
body { font-family: sans-serif; padding: 1em; }
.container { display: flex; flex-direction: column; gap: 10px; }
.controls { display: flex; align-items: center; gap: 10px; }
/* 編集エリアをテキストエリアそっくりに見せるスタイル */
.editable-area {
width: 500px;
height: 200px;
border: 1px solid #767676;
padding: 8px;
overflow: auto; /* スクロールバーを表示 */
font-size: 16px;
line-height: 1.5;
background-color: white;
white-space: pre-wrap; /* 改行とスペースを保持し、自動折り返しも行う */
}
/* 検索で見つかった箇所をハイライトするスタイル */
.highlight {
background-color: #ff0;
border-radius: 3px;
}
</style>
</head>
<body>
<h1>【確実な解決策】編集エリア内検索 & ジャンプ機能</h1>
<div class="container">
<div class="controls">
<input type="text" id="searchInput" placeholder="検索キーワード">
<input type="button" value="次を検索" onclick="findNext()">
</div>
<div id="editor" class="editable-area" contenteditable="true"></div>
</div>
<script>
const editor = document.getElementById('editor');
const searchInput = document.getElementById('searchInput');
// 例文を}入
const sampleText = "このテキストエリアは、長文の入力が可能です。\nJavaScriptを使うことで、様々な便利機能を追加できます。例えば、このように検索{タンを押すと、指定したキーワードの場所までカーソルがジャンプします。\nもう一度「次を検索」{タンを押すと、次の「キーワード」に移動します。JavaScriptの可能性は無限大です。\nぜひ、このサンプルを改造して、あなただけの機能を作ってみてください。\n最後のキーワードはこちらです。\n\n";
editor.innerText = sampleText.repeat(5); // innerTextで改行を正しく反映
let currentMatches = []; // 見つかったキーワードのspan要素を保持する配列
let currentIndex = -1; // 現在ハイライトしている要素のインデックス
function findNext() {
const keyword = searchInput.value;
if (!keyword) {
alert('検索キーワードを入力してください。');
return;
}
// 検索キーワードが変わったか、まだ検索していなければ、検索をやり直す
if (currentMatches.length === 0 || editor.dataset.lastKeyword !== keyword) {
removeHighlights();
editor.dataset.lastKeyword = keyword; // 検索したキーワードを記録
const regex = new RegExp(keyword, 'gi');
editor.innerHTML = editor.innerText.replace(regex, `<span class="highlight">${keyword}</span>`);
// }ッチした全てのspan要素を配列に格納
currentMatches = Array.from(editor.querySelectorAll('.highlight'));
currentIndex = -1;
}
if (currentMatches.length === 0) {
alert('キーワードが見つかりませんでした。');
return;
}
// 次の要素へインデックスを進める(末尾まで行ったら先頭に戻る)
currentIndex = (currentIndex + 1) % currentMatches.length;
const currentElement = currentMatches[currentIndex];
// --- ★★★ これが最も確実なスクロール命令です ★★★ ---
currentElement.scrollIntoView({
behavior: 'smooth', // スムーズにスクロール
block: 'center' // 要素を中央に表示
});
// 強調のため、現在地の背景色を少し変える
currentMatches.forEach(el => el.style.backgroundColor = '#ff0'); // 他をリセット
currentElement.style.backgroundColor = '#ffa500'; // 現在地はオレンジに
}
function removeHighlights() {
// ハイライト用のspanを全て解除して、元のテキストに戻す
editor.innerHTML = editor.innerText;
}
</script>
</body>
</html>
使用変数
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>【確実な解決策】contenteditable と scrollIntoView</title>
<style>
body { font-family: sans-serif; padding: 1em; }
.container { display: flex; flex-direction: column; gap: 10px; }
.controls { display: flex; align-items: center; gap: 10px; }
/* 編集エリアをテキストエリアそっくりに見せるスタイル */
.editable-area {
width: 500px;
height: 200px;
border: 1px solid #767676;
padding: 8px;
overflow: auto; /* スクロールバーを表示 */
font-size: 16px;
line-height: 1.5;
background-color: white;
white-space: pre-wrap; /* 改行とスペースを保持し、自動折り返しも行う */
}
/* 検索で見つかった箇所をハイライトするスタイル */
.highlight {
background-color: #ff0;
border-radius: 3px;
}
</style>
</head>
<body>
<h1>【確実な解決策】編集エリア内検索 & ジャンプ機能</h1>
<div class="container">
<div class="controls">
<input type="text" id="searchInput" placeholder="検索キーワード">
<input type="button" value="次を検索" onclick="findNext()">
</div>
<div id="editor" class="editable-area" contenteditable="true"></div>
</div>
<script>
const editor = document.getElementById('editor');
const searchInput = document.getElementById('searchInput');
// 例文を}入
const sampleText = "このテキストエリアは、長文の入力が可能です。\nJavaScriptを使うことで、様々な便利機能を追加できます。例えば、このように検索{タンを押すと、指定したキーワードの場所までカーソルがジャンプします。\nもう一度「次を検索」{タンを押すと、次の「キーワード」に移動します。JavaScriptの可能性は無限大です。\nぜひ、このサンプルを改造して、あなただけの機能を作ってみてください。\n最後のキーワードはこちらです。\n\n";
editor.innerText = sampleText.repeat(5); // innerTextで改行を正しく反映
let currentMatches = []; // 見つかったキーワードのspan要素を保持する配列
let currentIndex = -1; // 現在ハイライトしている要素のインデックス
function findNext() {
const keyword = searchInput.value;
if (!keyword) {
alert('検索キーワードを入力してください。');
return;
}
// 検索キーワードが変わったか、まだ検索していなければ、検索をやり直す
if (currentMatches.length === 0 || editor.dataset.lastKeyword !== keyword) {
removeHighlights();
editor.dataset.lastKeyword = keyword; // 検索したキーワードを記録
const regex = new RegExp(keyword, 'gi');
editor.innerHTML = editor.innerText.replace(regex, `<span class="highlight">${keyword}</span>`);
// }ッチした全てのspan要素を配列に格納
currentMatches = Array.from(editor.querySelectorAll('.highlight'));
currentIndex = -1;
}
if (currentMatches.length === 0) {
alert('キーワードが見つかりませんでした。');
return;
}
// 次の要素へインデックスを進める(末尾まで行ったら先頭に戻る)
currentIndex = (currentIndex + 1) % currentMatches.length;
const currentElement = currentMatches[currentIndex];
// --- ★★★ これが最も確実なスクロール命令です ★★★ ---
currentElement.scrollIntoView({
behavior: 'smooth', // スムーズにスクロール
block: 'center' // 要素を中央に表示
});
// 強調のため、現在地の背景色を少し変える
currentMatches.forEach(el => el.style.backgroundColor = '#ff0'); // 他をリセット
currentElement.style.backgroundColor = '#ffa500'; // 現在地はオレンジに
}
function removeHighlights() {
// ハイライト用のspanを全て解除して、元のテキストに戻す
editor.innerHTML = editor.innerText;
}
</script>
</body>
</html>
使用変数
| backgroundColor | |
| charset | |
| class | |
| contenteditable | |
| currentElement | |
| currentIndex | |
| currentMatches | |
| editor | |
| el | |
| findNext -------( Function ) | |
| id | |
| innerHTML | |
| innerText | |
| keyword | |
| lang | |
| lastKeyword | |
| length | |
| onclick | |
| placeholder | |
| regex | |
| removeHighlights -------( Function ) | |
| sampleText | |
| searchInput | |
| type | |
| value |