::highlight()とHighlight APIで特定の文字をハイライトさせたサンプル

CSSの::highlight()を使えば、JavaScriptで範囲を指定するだけで
HTMLを書き換えずにCSSで装飾できます。CSSは非常に強力です。

<p id="target">
  CSSの::highlight()を使えば、JavaScriptで範囲を指定するだけで<br />
  HTMLを書き換えずにCSSで装飾できます。CSSは非常に強力です。
</p>
::highlight(css-highlight) {
  background-color: yellow;
  text-decoration: dotted underline;
}
const targetNode = document.getElementById('target')
const searchWord = 'CSS'
const textNodes = []
const walker = document.createTreeWalker(targetNode, NodeFilter.SHOW_TEXT)
let node
let fullText = ''

while ((node = walker.nextNode())) {
  textNodes.push({
    node,
    start: fullText.length,
    end: fullText.length + node.textContent.length,
  })
  fullText += node.textContent
}

const ranges = []
let startPos = 0

while ((startPos = fullText.indexOf(searchWord, startPos)) !== -1) {
  const endPos = startPos + searchWord.length
  let startInfo = null
  let endInfo = null

  for (const item of textNodes) {
    if (!startInfo && startPos >= item.start && startPos < item.end) {
      startInfo = {
        node: item.node,
        offset: startPos - item.start,
      }
    }

    if (!endInfo && endPos > item.start && endPos <= item.end) {
      endInfo = {
        node: item.node,
        offset: endPos - item.start,
      }
    }
  }

  if (startInfo && endInfo) {
    const range = new Range()
    range.setStart(startInfo.node, startInfo.offset)
    range.setEnd(endInfo.node, endInfo.offset)
    ranges.push(range)
  }

  startPos += searchWord.length
}

const highlight = new Highlight(...ranges)
CSS.highlights.set('css-highlight', highlight)

元記事を表示する