Javascript 如何在网页上动态突出显示字符串?
我想创建包含URL的页面,例如:Javascript 如何在网页上动态突出显示字符串?,javascript,jquery,html,css,meteor,Javascript,Jquery,Html,Css,Meteor,我想创建包含URL的页面,例如: http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver 这些特定URL将包含完全相同的内容(“2015Aug24_Aug28”页面),但将突出显示标记在末尾的名称的所有实例。例如,“http://xyz
http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins
http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver
这些特定URL将包含完全相同的内容(“2015Aug24_Aug28”页面),但将突出显示标记在末尾的名称的所有实例。例如,“http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
“将突出显示名称“Billy Bones”的每个实例,就好像该名称的“查找”是通过浏览器在页面上执行的
我认为需要这样的东西,客户端:
var employee = getLastURLPortion(); // return "Billy_Bones" (or whatever)
employee = humanifyTheName(employee); // replaces underscores with spaces, so that it's "Billy Bones" (etc.)
Highlight(employee); // this I have no clue how to do
这可以在HTML/CSS中完成吗,或者也需要JavaScript或jQuery吗?我使用以下正则表达式替换所有匹配的url,用突出显示的文本创建锚定:
(http://xyzcorp/schedules/(.*?)/)(.*?)( |<|\n|\r|$)
(http://xyzcorp/schedules/(.*?/)(.*?)(|一种解决方案是,在加载窗口后,递归遍历所有节点,并使用突出显示类将搜索项包装在文本节点中。这样,就不会保留原始结构和事件订阅
(这里,使用jquery,但可以不使用):
Javascript:
$(函数(){
//从url获取术语
//var term=window.location.href.match(/\/(\w+)\/?$/)[1]。替换(“”,“”);
var术语组http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones/“.match(/\/(\w+)\/?$/)[1]。替换(“\”,”);
//搜索regexp
var re=new RegExp(“(“+term+”)”,“gi”);
//递归函数
功能远光灯(elem){
var contents=$(elem.contents();
如果(contents.length>0){
contents.each(函数(){
强光术语(本);
});
}否则{
//文本节点
if(elem.nodeType==3){
变量$elem=$(elem);
var text=$elem.text();
if(重新测试(文本)){
$elem.wrap(“”.parent().html(text.replace(re,$1'));
}
}
}
}
highlightTerm(document.body);
});
。突出显示{
背景颜色:黄色;
}
我想创建包含URL的页面,例如:
http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins
http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver
http
:
//xyzcorp/schedules/2015年8月24日/28日/Jim_Hawkins
http
:
//xyzcorp/schedules/2015年8月24日/28日/Billy\u Bones
http
:
//xyzcorp/schedules/2015年8月24日/28日/John_Silver
这些特定URL都将包含完全相同的内容(“2015Aug24_Aug28”页面),但将突出显示标记在末尾的名称的所有实例。例如,“http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
将突出显示名称“Billy Bones”的每个实例,就好像该名称的“查找”是通过浏览器在页面上执行的
我认为需要这样的东西,客户端:
var employee = getLastURLPortion(); // return "Billy_Bones" (or whatever)
employee = humanifyTheName(employee); // replaces underscores with spaces, so that it's "Billy Bones" (etc.)
Highlight(employee); // this I have no clue how to do
变量
雇员
=
GetLastUrlPart
();
//返回“Billy_Bones”(或其他)
雇员
=
人名
(
雇员
);
//将下划线替换为空格,使其成为“Billy Bones”(等)
突出
(
雇员
);
//我不知道该怎么做
这可以在HTML/CSS中完成,还是需要JavaScript或jQuery
如果调用该函数
highlight(employee);
这就是ECMAScript 2018+中该函数的外观:
function highlight(employee){
Array.from(document.querySelectorAll("body, body *:not(script):not(style):not(noscript)"))
.flatMap(({childNodes}) => [...childNodes])
.filter(({nodeType, textContent}) => nodeType === document.TEXT_NODE && textContent.includes(employee))
.forEach((textNode) => textNode.replaceWith(...textNode.textContent.split(employee).flatMap((part) => [
document.createTextNode(part),
Object.assign(document.createElement("mark"), {
textContent: employee
})
])
.slice(0, -1))); // The above flatMap creates a [text, employeeName, text, employeeName, text, employeeName]-pattern. We need to remove the last superfluous employeeName.
}
这是ECMAScript 5.1版本:
function highlight(employee){
Array.prototype.slice.call(document.querySelectorAll("body, body *:not(script):not(style):not(noscript)")) // First, get all regular elements under the `<body>` element
.map(function(elem){
return Array.prototype.slice.call(elem.childNodes); // Then extract their child nodes and convert them to an array.
})
.reduce(function(nodesA, nodesB){
return nodesA.concat(nodesB); // Flatten each array into a single array
})
.filter(function(node){
return node.nodeType === document.TEXT_NODE && node.textContent.indexOf(employee) > -1; // Filter only text nodes that contain the employee’s name.
})
.forEach(function(node){
var nextNode = node.nextSibling, // Remember the next node if it exists
parent = node.parentNode, // Remember the parent node
content = node.textContent, // Remember the content
newNodes = []; // Create empty array for new highlighted content
node.parentNode.removeChild(node); // Remove it for now.
content.split(employee).forEach(function(part, i, arr){ // Find each occurrence of the employee’s name
newNodes.push(document.createTextNode(part)); // Create text nodes for everything around it
if(i < arr.length - 1){
newNodes.push(document.createElement("mark")); // Create mark element nodes for each occurrence of the employee’s name
newNodes[newNodes.length - 1].innerHTML = employee;
// newNodes[newNodes.length - 1].setAttribute("class", "highlighted");
}
});
newNodes.forEach(function(n){ // Append or insert everything back into place
if(nextNode){
parent.insertBefore(n, nextNode);
}
else{
parent.appendChild(n);
}
});
});
}
功能突出显示(员工){
Array.prototype.slice.call(document.queryselectoral(“body,body*:not(script):not(style):not(noscript)”)//首先,获取``元素下的所有常规元素
.map(功能(elem){
返回Array.prototype.slice.call(elem.childNodes);//然后提取其子节点并将其转换为数组。
})
.reduce(函数(nodesA、nodesB){
返回nodesA.concat(nodesB);//将每个数组展平为单个数组
})
.filter(函数(节点){
return node.nodeType==document.TEXT\u node&&node.textContent.indexOf(employee)>-1;//仅筛选包含员工姓名的文本节点。
})
.forEach(函数(节点){
var nextNode=node.nextSibling,//记住下一个节点(如果存在的话)
parent=node.parentNode,//还记得父节点吗
content=node.textContent,//记住内容
newNodes=[];//为新突出显示的内容创建空数组
node.parentNode.removeChild(node);//现在删除它。
content.split(employee).forEach(function(part,i,arr){//查找每个出现的员工姓名
newNodes.push(document.createTextNode(part));//为其周围的所有内容创建文本节点
如果(i
替换单个文本节点的主要好处是事件监听器不会丢失。站点保持不变,只有文本更改
您也可以使用span
来代替mark
元素,并使用class
属性取消对行的注释,并在CSS中指定该行
这是一个示例,其中我使用了此函数,并在以下页面上使用了后续的高亮显示(“Text”);
:
(未突出显示的一个实例是
之外的SVG节点)。Neit
highlight(employee);
function highlight(employee){
Array.from(document.querySelectorAll("body, body *:not(script):not(style):not(noscript)"))
.flatMap(({childNodes}) => [...childNodes])
.filter(({nodeType, textContent}) => nodeType === document.TEXT_NODE && textContent.includes(employee))
.forEach((textNode) => textNode.replaceWith(...textNode.textContent.split(employee).flatMap((part) => [
document.createTextNode(part),
Object.assign(document.createElement("mark"), {
textContent: employee
})
])
.slice(0, -1))); // The above flatMap creates a [text, employeeName, text, employeeName, text, employeeName]-pattern. We need to remove the last superfluous employeeName.
}
function highlight(employee){
Array.prototype.slice.call(document.querySelectorAll("body, body *:not(script):not(style):not(noscript)")) // First, get all regular elements under the `<body>` element
.map(function(elem){
return Array.prototype.slice.call(elem.childNodes); // Then extract their child nodes and convert them to an array.
})
.reduce(function(nodesA, nodesB){
return nodesA.concat(nodesB); // Flatten each array into a single array
})
.filter(function(node){
return node.nodeType === document.TEXT_NODE && node.textContent.indexOf(employee) > -1; // Filter only text nodes that contain the employee’s name.
})
.forEach(function(node){
var nextNode = node.nextSibling, // Remember the next node if it exists
parent = node.parentNode, // Remember the parent node
content = node.textContent, // Remember the content
newNodes = []; // Create empty array for new highlighted content
node.parentNode.removeChild(node); // Remove it for now.
content.split(employee).forEach(function(part, i, arr){ // Find each occurrence of the employee’s name
newNodes.push(document.createTextNode(part)); // Create text nodes for everything around it
if(i < arr.length - 1){
newNodes.push(document.createElement("mark")); // Create mark element nodes for each occurrence of the employee’s name
newNodes[newNodes.length - 1].innerHTML = employee;
// newNodes[newNodes.length - 1].setAttribute("class", "highlighted");
}
});
newNodes.forEach(function(n){ // Append or insert everything back into place
if(nextNode){
parent.insertBefore(n, nextNode);
}
else{
parent.appendChild(n);
}
});
});
}