使用 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 的情况下工作。
你可以让它发挥作用的方式。
- 拨打 AJAX 电话。
- 将字符串加载到 DOM。
- 在您加载的内容上调用 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();
}
});
}
}
});
我试图在来自 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 的情况下工作。 你可以让它发挥作用的方式。
- 拨打 AJAX 电话。
- 将字符串加载到 DOM。
- 在您加载的内容上调用 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();
}
});
}
}
});