Last active
August 24, 2023 11:55
-
-
Save motsu0/256887a51e37c74508d9d3a81c381057 to your computer and use it in GitHub Desktop.
keyword search in page
This file contains 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
.s-highlight{ | |
background-color:yellow; | |
} | |
.s-hide{ | |
display: none; | |
} |
This file contains 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
<p> | |
<input id="input-word" type="text" placeholder="keyword"> | |
</p> | |
<div> | |
<div class="sample-part"> | |
<h3>夏目漱石、「吾輩は猫である」より</h3> | |
<p>吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。</p> | |
</div> | |
<div class="sample-part"> | |
<h3>夏目漱石、「こころ」より</h3> | |
<p>私はその人を常に先生と呼んでいた。だからここでもただ先生と書くだけで本名は打ち明けない。これは世間を憚かる遠慮というよりも、その方が私にとって自然だからである。私はその人の記憶を呼び起すごとに、すぐ「先生」といいたくなる。筆を執っても心持は同じ事である。よそよそしい頭文字などはとても使う気にならない。</p> | |
</div> | |
<div class="sample-part"> | |
<h3>中島敦、「山月記」より</h3> | |
<p>一年の後、公用で旅に出、汝水のほとりに宿った時、遂に発狂した。或夜半、急に顔色を変えて寝床から起上ると、何か訳の分らぬことを叫びつつそのまま下にとび下りて、闇の中へ駈出した。彼は二度と戻って来なかった。附近の山野を捜索しても、何の手掛りもない。その後李徴がどうなったかを知る者は、誰もなかった。</p> | |
</div> | |
<div class="sample-part"> | |
<h3>lorem ipsum</h3> | |
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> | |
</div> | |
</div> |
This file contains 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
const samplePartEls = document.getElementsByClassName('sample-part'); | |
const highlightEls = document.getElementsByClassName('s-highlight'); | |
const hideEls = document.getElementsByClassName('s-hide'); | |
const searchWordInput = document.getElementById('search-word-input'); | |
searchWordInput.addEventListener('input', showHighlight); | |
function showHighlight() { | |
//リセット処理 | |
[...highlightEls].forEach((el) => { | |
el.outerHTML = el.textContent; | |
}); | |
[...hideEls].forEach((el) => { | |
el.classList.remove('s-hide'); | |
}); | |
//本処理 | |
const rawSearchWord = searchWordInput.value; | |
if (rawSearchWord === '') return; | |
// かなカナ両方にマッチするように変換 | |
const searchWord = rawSearchWord | |
.replace(/[\u3041-\u3096\u30a1-\u30f6]/g, (match) => { | |
if (/[\u3041-\u3096]/.test(match)) { | |
return `[${match}${String.fromCharCode( | |
match.charCodeAt(0) + 0x60 | |
)}]`; | |
} | |
return `[${String.fromCharCode( | |
match.charCodeAt(0) - 0x60 | |
)}${match}]`; | |
}); | |
// タグ内のtextContentにマッチ | |
const contentRegexp = new RegExp( | |
`(?<=\\>)[\\s\\S]*(${searchWord})[\\s\\S]*(?=\\<)`, | |
'gi' | |
); | |
// 検索文字列そのままにマッチ | |
const rawRegexp = new RegExp(searchWord, 'gi'); | |
// 各要素に適用 | |
[...samplePartEls].forEach((partEl) => { | |
if (rawRegexp.test(partEl.textContent)) { | |
partEl.innerHTML = partEl.innerHTML.replace( | |
contentRegexp, | |
(partMatch) => { | |
let tempHtml = partMatch.replace(rawRegexp, (spanMatch) => { | |
return `<span class="s-highlight">${spanMatch}</span>`; | |
}); | |
return tempHtml; | |
} | |
); | |
} else { | |
partEl.classList.add('s-hide'); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment