LI要素を検索したりできるコードを書いた
やること
対象のHTMLファイルに以下の2行を実行するだけで完了です。 別ファイルでやらない場合はもうちょっと複雑になります。 bootstrap@5は見た目を綺麗にするために入っている。
echo '<script type="text/javascript" src="main.js"></script>' >> index.html
echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">' >> index.html
main.js
今回の本体。
- 検索:よくある検索機能。
- 登録:表示したくない要素をキーワードでミュートする機能。
- 反転:表示・非表示を切り替え。
できることはこれだけ。 中途半端に便利でしょ?
function search() {
let keyword = searchInput.value;
let is_reset = false;
if (keyword.length === 0) {
is_reset = true;
}
[...document.querySelectorAll('li')].forEach((li) => {
if (li.firstChild.textContent.includes(keyword)) {
li.style.display = "";
} else {
li.style.display = "none";
}
});
}
function register() {
let keyword = searchInput.value;
if (keyword.length === 0) {
return;
}
localStorage.setItem(keyword, [...document.querySelectorAll('li')]
.filter((li) => li.firstChild.textContent.includes(keyword))
.map((e) => e.firstChild.textContent).join(', '));
}
function reverse() {
[...document.querySelectorAll('li')].forEach((li) => {
if (li.style.display === 'none') {
li.style.display = '';
} else {
li.style.display = 'none';
}
})
}
function hide() {
let titles = Object.values(localStorage);
[...document.querySelectorAll('li')].forEach((li) => {
if (titles.find((value) => value.match(li.firstChild.textContent.replace(/\(/, "\\(").replace(/\)/, "\\)")))) {
li.style.display = "none";
} else {
li.style.display = "";
}
});
}
let searchInput = document.createElement('input');
searchInput.setAttribute('type', 'search');
searchInput.classList.add('form-control');
searchInput.placeholder = "";
searchInput.setAttribute('aria-label', "検索");
searchInput.setAttribute('aria-describedby', "search-button");
searchInput.onkeydown = (event) => {
if (event.key === 'Enter') {
search();
}
};
let searchButton = document.createElement('button');
searchButton.textContent = '検索';
searchButton.classList.add('btn');
searchButton.classList.add('btn-outline-secondary');
searchButton.setAttribute('id', "search-button");
searchButton.setAttribute('type', 'button');
searchButton.addEventListener('click', search);
let registerButton = document.createElement('button');
registerButton.textContent = '登録';
registerButton.classList.add('btn');
registerButton.classList.add('btn-outline-secondary');
registerButton.setAttribute('id', "register-button");
registerButton.setAttribute('type', 'button');
registerButton.addEventListener('click', register);
let reverseButton = document.createElement('button');
reverseButton.textContent = '反転';
reverseButton.classList.add('btn');
reverseButton.classList.add('btn-outline-secondary');
reverseButton.setAttribute('id', "reverse-button");
reverseButton.setAttribute('type', 'button');
reverseButton.addEventListener('click', reverse);
let searchInputGroupPrepend = document.createElement('div');
searchInputGroupPrepend.classList.add('input-group-prepend');
let searchInputGroup = document.createElement('div');
searchInputGroup.classList.add('input-group');
searchInputGroup.classList.add('mb-3');
searchInputGroupPrepend.appendChild(searchButton);
searchInputGroupPrepend.appendChild(registerButton);
searchInputGroup.appendChild(searchInputGroupPrepend);
searchInputGroup.appendChild(searchInput);
document.body.insertBefore(searchInputGroup, document.querySelector('ul'));
let searchInputGroupAppend = document.createElement('div');
searchInputGroupAppend.classList.add('input-group-append');
searchInputGroupAppend.appendChild(reverseButton);
searchInputGroup.appendChild(searchInputGroupAppend);
window.onload = () => {
hide();
}