使用Javascript突出显示Ajax响应
在构建HTML并将其粘贴到DOM之前,我试图突出显示来自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
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的情况下工作。
你能让它工作的方式
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();
}
});
}
}
});