使用 Javascript 突出显示 Ajax 响应

Highlight Ajax Response with Javascript

我试图在来自 ajax 响应的文本中突出显示查询,然后用它构建 HTML 并将其粘贴到 DOM 中。现在我正在使用这个代码片段:

function highlightWords(line, word, htmltag) {
    var tag = htmltag || ["<b>", "</b>"];
    var regex = new RegExp('(' + preg_quote(word) + ')', 'gi');
    return line.replace(regex, tag[0] + "" + tag[1]);
}

function preg_quote(str) {
    return (str + '').replace(/([\\.\+\*\?\[\^\]$\(\)\{\}\=\!\<\>\|\:])/g, "\");
}

但是,如果查询类似于 sit behind,则无法突出显示不同的词。它只会突出显示完整的短语而不是单个单词。它也不关心 HTML 标签,如果查询是 span,它会产生不漂亮的结果...

我找到了各种可以更好地处理突出显示的库,例如 https://markjs.io/ or https://www.the-art-of-web.com/javascript/search-highlight/

虽然那些图书馆总是想突出显示 DOM.

中已经存在的内容

我的搜索得到一个 ajax 响应,然后我用 JS 将其转换为 HTML 并使用 DOM7 将完整的 HTMLString 粘贴到父容器中(类似于 jQuery)。因此,我更愿意在创建 HTMLString 并将其粘贴到 DOM.

之前突出显示文本

有什么想法吗?

代码段样式:警告:根据问题

,这使用 DOM7

概述:不是将整个文本作为 HTML 字符串附加到您的#container, 将普通文本的部分附加为文本,将突出显示的元素附加为元素,以便您可以随意设置它们的样式。

var text // your ajax text response
var strQuery = 'sit behind' // your query string 

var queryWords = strQuery.split(' ')
var textWords = text.split(' ')
var bufferNormalWords  = []

textWords.forEach(function (word) {
    if (queryWords.indexOf(word) != -1) { // found
      var normalWords = bufferNormalWords.splice(0, buffer.length) // empty buffer
      // Your DOM7 commands
      $$('#container').add('span').text(normalWords.join(' ')) // normal text
      $$('#container').add('span').css('color', 'red').text(word + ' ') // why not red          
    }
    else bufferNormalWords.push(word)
})

不要将文本变成 HTML 字符串,只需设置文本,然后创建必要的元素以使用 DOM7.

如果您的 ajax 响应包含 html,我认为没有一种简单的方法可以绕过先创建 DOM 元素。即使在查询中包含 span 并且 ajax 结果包含 <span>

的情况下,下面也完成了工作
        function highlightWords(line, word, htmltag) {
            var words = word.split(/\s+/);
            var tag = htmltag || ["<b>", "</b>"];

            var root = document.createElement("div");
            root.innerHTML = line;
            root = _highlightWords(words, tag, root);
            return root.innerHTML;
        }

        // Recursively search the created DOM element
        function _highlightWords(words, htmlTag, el) {
            var children = [];

            el.childNodes.forEach(function(el) {
                if (el.nodeType != 3) { // anything other than Text Type
                    var highlighted = _highlightWords(words, htmlTag, el);
                    children.push(highlighted);
                } else {
                    var line = _highlight(el.textContent, words, htmlTag);
                    var span = document.createElement("span");
                    span.innerHTML = line;
                    children.push(span);
                }
            });

            // Clear the html of the element, so the new children can be added
            el.innerHTML = "";
            children.forEach(function (c) { el.appendChild(c)});
            return el;
        }

        // Find and highlight any of the words
        function _highlight(line, words, htmlTag) {
            words.forEach(function(singleWord) {
                if (!!singleWord) {
                    singleWord = htmlEscape(singleWord);
                    line = line.replace(singleWord, htmlTag[0] + singleWord + htmlTag[1]);
                }
            });
            return line;
        }

我认为您为此使用库是正确的。 我一直在使用一个名为 mark.js.

的很棒的库

它可以在没有依赖项或 jQuery 的情况下工作。 你可以让它发挥作用的方式。

  1. 拨打 AJAX 电话。
  2. 将字符串加载到 DOM。
  3. 在您加载的内容上调用 Mark.js API。

这是一个代码片段:

document.addEventListener('DOMContentLoaded', getText);

function getText() {
  const headline = document.getElementsByTagName("h1")[0];
  const p = document.getElementsByTagName("p")[0];

  fetch('https://jsonplaceholder.typicode.com/posts/1').
  then(response => response.json()).
  then(json => {
    console.log(json);
    headline.innerHTML = json.title;
    p.innerHTML = json.body;
    addMark('aut facere');
  });
}

function addMark(keyword) {
  var markInstance = new Mark(document.querySelector('.context'));
  var options = {
    separateWordSearch: true
  };
  markInstance.unmark({
    done: function() {
      markInstance.mark(keyword, options);
    },
  });
}
<script src="https://cdn.jsdelivr.net/mark.js/8.6.0/mark.min.js"></script>
<div class="context">
  <h1></h1>
  <p></p>
</div>

我只是在 ajax 请求的响应中突出显示。它对我有用:

$.ajax({
    url : url,
    type : 'POST',
    success: function(response) {
        // Highlight
        let term = 'word';
        $context = $("#selector");
        $context.show().unmark();
        if (term){
            $context.mark(term, {
                done: function() {
                    $context.not(":has(mark)").hide();
                }
            });
        }
    }
});