使用Javascript突出显示Ajax响应

使用Javascript突出显示Ajax响应,javascript,ajax,highlight,dom7,Javascript,Ajax,Highlight,Dom7,在构建HTML并将其粘贴到DOM之前,我试图突出显示来自ajax响应的文本中的查询。现在我正在使用以下代码片段: function highlightWords(line, word, htmltag) { var tag = htmltag || ["<b>", "</b>"]; var regex = new RegExp('(' + preg_quote(word) + ')', 'gi'); return line.replace(rege

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

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

function preg_quote(str) {
    return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}
函数高亮字(行、字、htmltag){
var tag=htmltag | |[“”,“”];
var regex=new RegExp('('+preg_quote(word)+'),'gi');
返回行。替换(正则表达式,标记[0]+“$1”+标记[1]);
}
功能预报价(str){
返回(str+'').replace(/([\\.\+\*\?\[\^\]\$\(\)\{\\\\\\=\!\\\\\\\\\\;\:])/g,“\\$1”);
}
但是,如果查询类似于“坐在后面”,则无法突出显示不同的单词。它只会突出整个短语,而不是单个单词。它也不关心HTML标记,例如,如果查询是
span
,则会产生不恰当的结果

我发现了各种处理突出显示方式更好的库,如或

但是,这些库总是希望突出显示DOM中已经存在的内容

我的搜索得到一个ajax响应,然后我用JS将其转换为HTML,并使用(类似于jQuery)将完整的HTMLString粘贴到父容器中。Therfor我更喜欢在创建HTMLString并将其粘贴到DOM中之前高亮显示文本


有什么想法吗?

代码片段样式:警告:根据问题使用DOM7

概述:不要将整个文本作为HTML字符串附加到#容器中, 将普通文本的部分附加为文本,将高亮显示的元素附加为元素,以便您可以随意设置它们的样式

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)
})

不要把文本变成HTMLstring,只需设置文本,并创建必要的元素,以使用DOM7

对它们进行样式设置。如果您的ajax响应包含html,我认为没有简单的方法可以先创建DOM元素。下面将完成任务,即使在查询中存在
span
并且ajax结果包含

函数高亮字(行、字、htmltag){
var words=word.split(/\s+/);
var tag=htmltag | |[“”,“”];
var root=document.createElement(“div”);
root.innerHTML=line;
root=_highlightWords(单词、标记、根);
返回root.innerHTML;
}
//递归搜索创建的DOM元素
函数_highlightWords(words、htmlTag、el){
var children=[];
el.childNodes.forEach(函数(el){
如果(el.nodeType!=3){//文本类型以外的任何内容
突出显示的变量=_highlightWords(words、htmlTag、el);
儿童。推(突出显示);
}否则{
变量行=_突出显示(el.textContent、words、htmlTag);
var span=document.createElement(“span”);
span.innerHTML=line;
儿童。推(span);
}
});
//清除元素的html,以便可以添加新的子元素
el.innerHTML=“”;
forEach(函数(c){el.appendChild(c)});
返回el;
}
//查找并突出显示任何单词
功能突出显示(行、字、htmlTag){
words.forEach(函数(单字){
如果(!!单字){
singleWord=htmlEscape(singleWord);
line=line.replace(singleWord,htmlTag[0]+singleWord+htmlTag[1]);
}
});
回流线;
}

我认为您使用库实现这一点是正确的。 我一直在使用一个名为

它在没有依赖项或jQuery的情况下工作。 你能让它工作的方式

  • 进行AJAX调用
  • 将字符串加载到DOM中
  • 对已加载的内容调用Mark.js API
  • 下面是一段代码片段:

    document.addEventListener('DOMContentLoaded',getText);
    函数getText(){
    const headline=document.getElementsByTagName(“h1”)[0];
    const p=document.getElementsByTagName(“p”)[0];
    取('https://jsonplaceholder.typicode.com/posts/1').
    然后(response=>response.json()。
    然后(json=>{
    log(json);
    headline.innerHTML=json.title;
    p、 innerHTML=json.body;
    地址标记(“aut facere”);
    });
    }
    函数addMark(关键字){
    var markInstance=新标记(document.querySelector('.context');
    变量选项={
    separateWordSearch:true
    };
    markInstance.unmark({
    完成:函数(){
    markInstance.mark(关键字、选项);
    },
    });
    }
    
    


    我只是在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();
                    }
                });
            }
        }
    });
    

    你说“那些库虽然总是想突出显示DOM中已经存在的内容”-也许你可以将它们从DOM中复制出来,使用库,然后将它们放回?当前的JSFIDLE将有助于显示正在发生的事情,然后您可以说您想要什么?您只需在div中添加响应并将css分配给它?我不介意否决票,但如果您能告诉我什么没有按要求工作或代码没有遵循最佳实践,我将非常感激。提前谢谢。我也没有,我只是觉得OP使用了DOM7,一个代码片段,不喜欢库。(包括DOM7)我没有否决任何答案,我必须在周一工作时检查答案。这看起来是最有希望的方法。我目前的错误是,在使用
    span
    元素进行样式设置时,多次对具有不同关键字的字符串使用highlight函数。而不是检查关键字并在稍后阶段一次性应用样式。@Danmoreng我认为你的思路是正确的。充分利用你拥有的工具。
    $.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();
                    }
                });
            }
        }
    });