๊ธฐ์กด์ ์น์์ ํน์ ํ ์คํธ๋ฅผ ๊ฐ์กฐ(ํ์ด๋ผ์ดํธ)ํ๋ ค๋ฉด, ํด๋น ํ ์คํธ๋ฅผ <span>์ด๋ <em> ํ๊ทธ๋ก ๊ฐ์ธ๊ณ ํด๋์ค๋ฅผ ๋ถ์ฌํ ๋ค CSS๋ฅผ ์ ์ฉํด์ผ ํ์ต๋๋ค. ์ด๋ DOM ๊ตฌ์กฐ๋ฅผ ๋ณต์กํ๊ฒ ๋ง๋ค๊ณ ์ฑ๋ฅ ์ ํ์ ์์ธ์ด ๋ ์ ์์์ต๋๋ค.
CSS Custom Highlight API๋ DOM์ ์กฐ์ํ์ง ์๊ณ ์ค์ง Javascript์ Css๋ง์ผ๋ก ํ ์คํธ ๋ฒ์์ ์คํ์ผ์ ์ ์ฉํ๋ ์๋ก์ด ํ์ค์ ์ ์ํฉ๋๋ค.
1. ์ Custom Highlight API๋ฅผ ์ฌ์ฉํด์ผ ํ ๊น?
| ์ฅ์ | ์ค๋ช |
| DOM ๋ ๋ฆฝ์ฑ & ์ฑ๋ฅ | ํ ์คํธ ๊ฐ์กฐ๋ฅผ ์ํด HTML ํ๊ทธ๋ฅผ ์ฝ์ ํ ํ์๊ฐ ์์ต๋๋ค. DOM ์กฐ์์ ์ต์ํํ์ฌ ๋ ๋๋ง ์ฑ๋ฅ์ด ํฅ์๋๊ณ ํ์ด์ง ๋ก๋ฉ ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค. |
| ๋ณต์กํ ๋ฒ์ ์ฒ๋ฆฌ | ์ฌ๋ฌ ๊ฐ์ ํ ์คํธ ๋ฒ์๋, DOM ๋ ธ๋๋ฅผ ๊ฐ๋ก์ง๋ฅด๋ ๋ฒ์๋ฅผ ํ๋์ ํ์ด๋ผ์ดํธ๋ก ์ฝ๊ฒ ๊ทธ๋ฃนํํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. (์: ๋ฌธ๋จ ๊ฒฝ๊ณ๋ฅผ ๋๋ ๊ฒ์ ๊ฒฐ๊ณผ ๊ฐ์กฐ) |
| ์ ๊ทผ์ฑ (Accessibility) | ์ฌ์ฉ์ ์ ํ(::selection)๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๋ ๋๋ง ๋ ์ด์ด ์์ ์ ์ฉ๋๋ฏ๋ก, ์คํฌ๋ฆฐ ๋ฆฌ๋์ ๋ฐฉํด ์์ด ์๊ฐ์ ์ธ ๊ฐ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. |
| ์ฌ์ด ์คํ์ผ๋ง | ์ ์ฉ ๊ฐ์ ์์์ธ ::highlight()๋ฅผ ์ฌ์ฉํ์ฌ CSS๋ก ๊ฐํธํ๊ฒ ์คํ์ผ์ ์ ์ํ ์ ์์ต๋๋ค. |
2. Custom Highlight API์ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์
์ด API๋ ์ฃผ๋ก ์ธ ๊ฐ์ง ํต์ฌ ์์๋ก ์๋ํฉ๋๋ค.
- Range ๊ฐ์ฒด (JavaScript):
- ์ญํ : ํ์ด๋ผ์ดํธํ ํ ์คํธ์ ์์์ ๊ณผ ๋์ ์ ์ ์ํฉ๋๋ค. (DOM ๋ ธ๋์ ์คํ์ ์ ์ง์ )
- Highlight ๊ฐ์ฒด (JavaScript):
- ์ญํ : ํ๋ ์ด์์ Range ๊ฐ์ฒด๋ฅผ ๋ด๋ ์ปฌ๋ ์ ์ ๋๋ค. ์ด ๊ฐ์ฒด๊ฐ ํ๋์ ๋ ผ๋ฆฌ์ ์ธ ํ์ด๋ผ์ดํธ ๊ทธ๋ฃน์ ๋ํํฉ๋๋ค.
- document.body.highlights (JavaScript Map):
- ์ญํ : ๋ธ๋ผ์ฐ์ ์ ํ์ด๋ผ์ดํธ๋ฅผ ๋ฑ๋กํ๋ ์ ์ญ ๋งต์ ๋๋ค. ์ฌ๊ธฐ์ Highlight ๊ฐ์ฒด๋ฅผ ์ด๋ฆ(ํค)๊ณผ ํจ๊ป ๋ฑ๋กํด์ผ ๋น๋ก์ ๋ ๋๋ง๋ฉ๋๋ค.
- ::highlight(custom-name) (CSS):
- ์ญํ : document.body.highlights ๋งต์ ๋ฑ๋กํ ์ด๋ฆ์ ์ฐธ์กฐํ์ฌ ํด๋น ๋ฒ์์ ์ค์ ์คํ์ผ์ ์ ์ฉํฉ๋๋ค.
3. ์ค์ ํ์ฉ ์์ : ๊ฒ์ ๊ฒฐ๊ณผ ๊ฐ์กฐ
์ค์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฒ์์ด๋ฅผ ํ์ด์ง ์ ์ฒด์์ ์ฐพ์ ๊ฐ์กฐํ๋ ์ฝ๋๋ฅผ ์์๋ก ๋ณด์ฌ์ค๋๋ค.
const SEARCH_HIGHLIGHT_NAME = 'search-match';
const searchTerm = 'API'; // ๊ฒ์์ด๋ผ๊ณ ๊ฐ์
/**
* ํ
์คํธ ๋
ธ๋์์ ๊ฒ์์ด๋ฅผ ์ฐพ์ Range ๊ฐ์ฒด ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค.
*/
function findMatches(term) {
const matches = [];
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
let node;
while (node = walker.nextNode()) {
let index = node.textContent.indexOf(term);
while (index !== -1) {
const range = new Range();
range.setStart(node, index);
range.setEnd(node, index + term.length);
matches.push(range);
index = node.textContent.indexOf(term, index + term.length);
}
}
return matches;
}
// 1. ๊ธฐ์กด ํ์ด๋ผ์ดํธ ์ ๋ฆฌ
document.body.highlights.get(SEARCH_HIGHLIGHT_NAME)?.clear();
// 2. ์๋ก์ด ๋ฒ์(Range) ์ฐพ๊ธฐ
const ranges = findMatches(searchTerm);
// 3. Highlight ๊ฐ์ฒด ์์ฑ ๋ฐ ๋ฑ๋ก (API ์ง์ ํ์ธ ํ์)
if (window.CSS.highlights) {
const highlight = new Highlight(...ranges);
document.body.highlights.set(SEARCH_HIGHLIGHT_NAME, highlight);
}
/* JavaScript์์ ๋ฑ๋กํ 'search-match' ์ด๋ฆ์ ์ฌ์ฉ */
::highlight(search-match) {
background-color: yellow;
color: black;
font-weight: bold;
}
4. ์น์ฌ์ดํธ ํ์ฉ ๋ฐฉ์
- ํตํฉ ๊ฒ์ ๊ฒฐ๊ณผ ๊ฐ์กฐ: ์ฌ์ดํธ ์ ์ฒด ๊ฒ์ ์์ง์ ๊ฒฐ๊ณผ๋ฅผ DOM ์กฐ์ ์์ด ๋น ๋ฅด๊ฒ ํ์ด๋ผ์ดํธ.
- ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ ๊ฒฝ๊ณ : ๊ด๋ฆฌ์ ํ์ด์ง์์ ์๋ชป๋ ํ์์ ๋ฐ์ดํฐ(์: ์ด๋ฉ์ผ, ์ ํ๋ฒํธ)๋ฅผ ํฌํจํ ํ ์คํธ๋ฅผ ์๋์ผ๋ก ๋นจ๊ฐ์์ผ๋ก ๊ฐ์กฐํ์ฌ ์์ ํ์๋ฅผ ์๋ฆผ.
- ์ ๊ทผ์ฑ ๊ธฐ๋ฅ: ์ฌ์ฉ์๊ฐ 'ํต์ฌ ์ฉ์ด ๋ณด๊ธฐ' ๋ฒํผ์ ํด๋ฆญํ๋ฉด, ๋ณต์กํ ๋ณธ๋ฌธ ๋ด์ ํต์ฌ ๋จ์ด(์: ํ์ ์ฉ์ด)๋ฅผ ์ผ๊ด์ ์ผ๋ก ๊ฐ์กฐํด์ฃผ๋ ๊ธฐ๋ฅ ๊ตฌํ.
'w. Gemini' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Google Labs 'Learn' ์นดํ ๊ณ ๋ฆฌ ํต์ฌ ์ ๋ฆฌ: ํ์ต์ ๋ฏธ๋ TOP 3 (0) | 2026.03.16 |
|---|---|
| Google Labs๊ฐ ์ ์ํ๋ '์ฐฝ์์ ๋ฏธ๋'์ Create ์นดํ ๊ณ ๋ฆฌ ์๊ฐ. (0) | 2026.03.16 |
| ์ฐ์ต ๋ฌธ์ 3: ๋ณตํฉ ๋ ์ด์์ (0) | 2025.11.18 |
| ์ฐ์ต ๋ฌธ์ 2: ์์ฐ์ค๋ฝ๊ฒ ๋จ์ด์ง๋ ๋ฐ์ํ ๋ ์ด์์ (0) | 2025.11.18 |
| ์ฐ์ต ๋ฌธ์ 1: ๊ธฐ๋ณธ ๋ฐ์ํ ์นด๋ ๋ ์ด์์ (0) | 2025.11.18 |
