我想创建包含以下URL的页面:

http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkinshttp://xyzcorp/schedules/2015年8月24_Aug28/Billy_Boneshttp://xyzcorp/schedules/2015年8月24_Aug28/John_Silver

这些特定的URL都包含完全相同的内容(“2015Aug24_Aug28”页面),但会突出显示末尾标记的名称的所有实例。例如,“http://xyzcorp/schedules/2015年8月24_Aug28/Billy_Bones将显示突出显示的名称“Billy Bones”的每个实例,就像通过浏览器在页面上执行该名称的“查找”一样。

我想客户端需要这样的东西:

var employee=getLastURLPortion();//return“Billy_Bones”(或其他)employee=humanifyTheName(员工);//用空格替换下划线,因此它是“Billy Bones”(等等)突出显示(员工);//这个我不知道该怎么做

这可以在HTML/CSS中完成吗?还是还需要JavaScript或jQuery?

8
  • 啤酒也不是,但在炎热的日子里它非常好。 评论 2015年8月23日13:00
  • 1
    使用荧光笔插件 评论 2015年8月23日13:04
  • 1
    我认为真正的问题是页面是如何呈现的,你能在模板中添加一些东西吗? 评论 2015年8月23日13:13
  • 2
    @这就是为什么我建议使用一个已经经过测试的插件。一旦有人深入了解了这一点,他们就会意识到维护html结构和不干扰事件并不是一件小事 评论 2015年8月23日13:27
  • 2
    看起来不像警察任何在提出这个问题之前,请先进行研究。OP似乎认为使用3种特定技术可能是可行的,但并不费心对每种技术进行基本搜索(例如“用javascript突出显示文本”或“用css突出显示文本“)。孩子们,在你问问题之前,你应该先研究一下! 评论 2015年8月23日15:28

3个答案

重置为默认值
6

如果你调用函数

突出显示(员工);

这就是ECMAScript 2018+中该函数的样子:

功能突出显示(员工){Array.from(document.querySelectorAll(“body,body*:not(script):not(style):no(noscript)”).flatMap(({childNodes})=>[…childNodes]).filter(({nodeType,textContent})=>nodeType===文档。TEXT_NODE&&textContent.includes(员工)).forEach((textNode)=>textNode.replaceWith(…textNode.textContent.split(employee).flatMap((part)=>[document.createTextNode(部件),Object.assign(document.createElement(“标记”){text内容:员工})]).切片(0,-1));//上面的flatMap创建了一个[text,employeeName,text,Employee Name,text,embloyeeName]-模式。我们需要删除最后一个多余的employeeName。}

这是ECMAScript 5.1版本:

功能突出显示(员工){Array.prototype.slice.call(document.querySelectorAll(“body,body*:not(script):not.map(函数(元素){return Array.prototype.slice.call(elem.childNodes);//然后提取它们的子节点并将其转换为数组。}).reduce(函数(节点A、节点B){return nodesA.concat(nodesB);//将每个阵列展平为单个阵列}).filter(函数(节点){return node.nodeType===文档。TEXT_NODE&&NODE.textContent.indexOf(员工)>-1;//仅筛选包含员工姓名的文本节点。}).forEach(函数(节点){var nextNode=node.nextSibling,//记住下一个节点(如果存在)parent=node.parentNode,//记住父节点content=node.textContent,//记住内容新节点=[];//为新突出显示的内容创建空数组node.pparentNode.removeChild(节点);//暂时将其移除。content.split(employee).forEach(function(part,i,arr){//查找员工姓名的每次出现newNodes.push(document.createTextNode(part));//为周围的所有内容创建文本节点如果(i<arr.长度-1){newNodes.push(document.createElement(“mark”));//为每次出现的员工姓名创建标记元素节点newNodes[newNodes.length-1].innerHTML=员工;//newNodes[newNodes.length-1].setAttribute(“类”,“突出显示”);}});newNodes.forEach(函数(n){//将所有内容追加或插入到位if(nextNode){parent.insertBefore(n,nextNode);}其他{parent.appendChild(n);}});});}

替换单个文本节点的主要好处是不会丢失事件侦听器。现场保持完整,只有文本变化。

而不是作记号元素,您还可以使用跨度并用属性并在CSS中指定。

这是一个例子,我使用了这个函数和随后的突出显示(“文本”);的MDN页文本节点:

突出显示所有“文本”的网站

(未突出显示的一个事件是SVG节点<iframe>).

  • 很好!你建议如何更改突出显示?换句话说,删除所有<标记>此函数生成的元素? 评论 9月14日13:59
  • 你可以有效地反过来做同样的事情。使用查询选择器全部()抓住<标记>元素和调用替换为()替换结果创建文本节点()的内容<标记>元素。
    – D月
    评论 9月16日16:44
  • 您甚至可以考虑添加一些形式的数据-属性将每个<标记>元素进行特定搜索,以避免销毁不相关的<标记>页面上的元素。
    – D月
    评论 9月16日16:44

我使用以下正则表达式替换所有匹配的url,以创建带有突出显示文本的锚:

(http://xyzcorp/schedules/(.*?)/)(.*)(|<|\n|\r|$)

正则表达式可视化

Debuggex演示

以下代码将替换所有普通url。如果不需要将它们替换为链接,只需高亮显示它们,然后删除标记:

var str=“http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins http://xyzcorp/schedules/2015年8月24_Aug28/Billy_Bones http://xyzcorp/schedules/2015年8月24_Aug28/John_Silver ";var highlighted=str.replace(新RegExp(“(http://xyzcorp/schedules/(.*?)/)(.*)(|<|\n|\r|$)“,”g“),”<a href='$1$3'>$1<span style='背景色:#d0d0'>$3</span></a>“);

突出显示的字符串的内容将是:

<a href='http://xyzcorp/schedules/2015年8月24日至8月28日Jim_Hawkins'>http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins公司</a><a href='http://xyzcorp/schedules/2015年8月24_Aug28/Billy_Bones'>http://xyzcorp/schedules/2015Aug24_Aug28/<span style=“背景颜色:#d0d0d0”>Billy_Bones</span></a><a href='http://xyzcorp/schedules/2015年8月24_Aug28/John_Silver'>http://xyzcorp/schedules/2015Aug24_Aug28/约翰西尔弗</a>

更新:

此函数将替换输入文本中的匹配名称:

函数highlight_names(html_in){var name=location.href.split(“/”).pop().replace(“_”,“”);return html_in.replace(new RegExp(“(”+名称+“)”,“g”),“<span style='background-color:#d0d0'>$1”);}
1
  • 令人印象深刻,但不应该突出显示URL(它们只会出现在地址栏上);应该突出显示的是页面上“Billy Bones”的每个实例(假设URL以“\Billy_Bones”结尾)。 评论 2015年8月23日13:45
2

一种解决方案是,在加载窗口后,递归遍历所有节点,并用突出显示类将搜索词包装在文本节点中。这样,原始结构和事件订阅就不会被保留。

(这里,使用jquery,但可以不用):

Java脚本:

$(函数(){//从url获取术语var term=window.location.href.match(/\/(\w+)\/?$/)[1] .替换('_','');//搜索正则表达式var re=新RegExp('('+term+')','gi');//递归函数功能高亮项(元素){var contents=$(elem).contents();if(contents.length>0){contents.each(function(){highlightTerm(此);});}其他{//文本节点if(元素节点类型===3){var$elem=$(元素);var文本=$elem.text();if(重新测试(文本)){$elem.wrap(“<span/>”).parent().html(text.replace(re,'<span class=“highlight”>$1</span>'));}}}}highlightTerm(document.body);});

CSS(客服代表):

.突出显示{背景色:黄色;}

$(函数(){//从url获取术语//var term=window.location.href.match(/\/(\w+)\/?$/)[1] .替换('_','');var术语='http://xyzcorp/schedules/2015年8月24_Aug28/Billy_Bones/'匹配(/\/(\w+)\/?$/)[1] .替换('_','');//搜索regexpvar re=新RegExp('('+term+')','gi');//递归函数功能高亮项(元素){var contents=$(elem).contents();if(contents.length>0){contents.each(function(){高亮术语(this);});}其他{//文本节点if(元素节点类型===3){var$elem=$(元素);var文本=$elem.text();if(重新测试(文本)){$elem.wrap(“<span/>”).parent().html(text.replace(re,'<span class=“highlight”>$1</span>'));}}}}highlightTerm(document.body);});
.突出显示{背景色:黄色;}
<script src=“https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js“></script><div><div class=“post-text”itemprop=“text”><p>我想创建带有URL的页面,例如:</p><pre style=“”class=“default prettyprint prettyplient”><代码>http(http)</span><span class=“pun”>:</span><span class=“com”>//xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins</span><span class=“pln”>http</span><span class=“pun”>:</span>//xyzcorp/schedules/2015年8月24_Aug28/Billy_Bones</span><span class=“pln”>http协议</span><span class=“pun”>:</span>//xyzcorp/schedules/2015年8月24_Aug28/John_Silver</span></code></pre><p>这些特定的URL都包含完全相同的内容(“2015Aug24_Aug28”页面),但会突出显示末尾标记的名称的所有实例。例如,“<code>http://xyzcorp/schedules/2015年8月24日至8月28日/Billy_Bones</code>将显示突出显示的名称“Billy Bones”的每个实例,就像通过浏览器在页面上执行该名称的“查找”一样</p><p>我想客户端需要这样的东西:</p><pre style=“”class=“default prettyprint prettyplient”><代码>var(无功功率)</span>员工</span><span class=“pun”>=</span><span class=“pln”>getLastURL部分</span><span class=“pun”>()</span><span class=“pln”></span><span class=“com”>//return“Billy_Bones”(或其他)</span><span class=“pln”>雇员</span><span class=“pun”>=</span>人性化TheName</span><span class=“pun”>(</span>员工</span><span class=“pun”>)</span><span class=“pln”></span>//用空格替换下划线,所以它是“Billy Bones”(等等)</span><span class=“pln”></span>突出显示</span><span class=“pun”>(</span><span class=“pln”>员工</span><span class=“pun”>)</span><span class=“pln”></span>我不知道该怎么做</span></code></pre><p>这可以在HTML/CSS中完成吗?还是还需要JavaScript或jQuery</p>(第页)</div>

演示:http://plnkr.co/edit/rhfqzWThLTu9ccBb1Amy?p=预览

0

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.