Ich möchte Seiten mit URLs erstellen wie:
http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins
http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver
Diese speziellen URLs würden alle den exakt gleichen Inhalt enthalten (die Seite „2015Aug24_Aug28“), würden aber alle Instanzen des Namens hervorheben, die bis zum Ende getaggt sind. Zum Beispiel, “http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones
” würde jede Instanz des Namens “Billy Bones” hervorgehoben anzeigen, als ob auf der Seite über den Browser ein “Suchen” für diesen Namen ausgeführt worden wäre.
Ich stelle mir vor, dass auf Client-Seite so etwas erforderlich ist:
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
Geht das in HTML/CSS oder wird dafür auch JavaScript oder jQuery benötigt?

Sebastian Simon
Wenn Sie die Funktion aufrufen
highlight(employee);
So würde diese Funktion in ECMAScript 2018+ aussehen:
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.
}
Und dies ist eine ECMAScript 5.1-Version:
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);
}
});
});
}
Der Hauptvorteil des Ersetzens einzelner Textknoten besteht darin, dass Ereignis-Listener nicht verloren gehen. Die Website bleibt intakt, nur die Text Änderungen.
Anstatt der mark
Element können Sie auch a verwenden span
und kommentieren Sie die Zeile mit dem aus class
-Attribut und geben Sie es in CSS an.
Dies ist ein Beispiel, in dem ich diese Funktion und eine nachfolgende verwendet habe highlight("Text");
auf der MDN-Seite für Text
Knoten:

(Das einzige Vorkommen, das nicht hervorgehoben ist, ist ein SVG-Knoten hinter einem <iframe>
).

László Kardinál
Ich habe die folgende Regex verwendet, um alle übereinstimmenden URLs zu ersetzen, um Anker mit hervorgehobenem Text zu erstellen:
(http://xyzcorp/schedules/(.*?)/)(.*?)( |<|\n|\r|$)

Debuggex-Demo
Der folgende Code ersetzt alle einfachen URLs. Wenn Sie sie nicht durch Links ersetzen müssen, markieren Sie sie einfach und entfernen Sie die Tags:
var str = "http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver ";
var highlighted = str.replace( new RegExp("(http://xyzcorp/schedules/(.*?)/)(.*?)( |<|\n|\r|$)","g"), "<a href="https://stackoverflow.com/questions/32166803/">$1<span style="background-color: #d0d0d0">$3</span></a>" );
Der Inhalt der hervorgehobenen Zeichenfolge ist:
<a href="http://xyzcorp/schedules/2015Aug24_Aug28/Jim_Hawkins">http://xyzcorp/schedules/2015Aug24_Aug28/<span style="background-color: #d0d0d0">Jim_Hawkins</span></a>
<a href="http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones">http://xyzcorp/schedules/2015Aug24_Aug28/<span style="background-color: #d0d0d0">Billy_Bones</span></a>
<a href="http://xyzcorp/schedules/2015Aug24_Aug28/John_Silver">http://xyzcorp/schedules/2015Aug24_Aug28/<span style="background-color: #d0d0d0">John_Silver</span></a>
AKTUALISIEREN:
Diese Funktion ersetzt die übereinstimmenden Namen aus dem Eingabetext:
function highlight_names( html_in )
{
var name = location.href.split("https://stackoverflow.com/").pop().replace("_"," ");
return html_in.replace( new RegExp( "("+name+")", "g"), "<span style="background-color: #d0d0d0">$1</span>" );
}

Manji
Eine Lösung wäre, nach dem Laden des Fensters alle Knoten rekursiv zu durchlaufen und Suchbegriffe in Textknoten mit einer Highlight-Klasse einzuschließen. Auf diese Weise bleiben die ursprüngliche Struktur und die Ereignisabonnements nicht erhalten.
(Hier mit jquery, aber es geht auch ohne):
Javascript:
$(function() {
// get term from url
var term = window.location.href.match(/\/(\w+)\/?$/)[1].replace('_', ' ');
// search regexp
var re = new RegExp('(' + term + ')', 'gi');
// recursive function
function highlightTerm(elem) {
var contents = $(elem).contents();
if(contents.length > 0) {
contents.each(function() {
highlightTerm(this);
});
} else {
// text nodes
if(elem.nodeType === 3) {
var $elem = $(elem);
var text = $elem.text();
if(re.test(text)) {
$elem.wrap("<span/>").parent().html(text.replace(re, '<span class="highlight">$1</span>'));
}
}
}
}
highlightTerm(document.body);
});
CSS:
.highlight {
background-color: yellow;
}
$(function() {
// get term from url
//var term = window.location.href.match(/\/(\w+)\/?$/)[1].replace('_', ' ');
var term = 'http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones/'.match(/\/(\w+)\/?$/)[1].replace('_', ' ');
// search regexp
var re = new RegExp('(' + term + ')', 'gi');
// recursive function
function highlightTerm(elem) {
var contents = $(elem).contents();
if(contents.length > 0) {
contents.each(function() {
highlightTerm(this);
});
} else {
// text nodes
if(elem.nodeType === 3) {
var $elem = $(elem);
var text = $elem.text();
if(re.test(text)) {
$elem.wrap("<span/>").parent().html(text.replace(re, '<span class="highlight">$1</span>'));
}
}
}
}
highlightTerm(document.body);
});
.highlight {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<div class="post-text" itemprop="text">
<p>I want to create pages with urls such as:</p>
<pre style="" class="default prettyprint prettyprinted">
<code>
<span class="pln">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>
<span class="com">//xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones</span>
<span class="pln">
http</span>
<span class="pun">:</span>
<span class="com">//xyzcorp/schedules/2015Aug24_Aug28/John_Silver</span>
</code>
</pre>
<p>These particular URLs would all contain the exact same content (the "2015Aug24_Aug28" page), but would highlight all instances of the name tagged on to the end. For example, " <code>http://xyzcorp/schedules/2015Aug24_Aug28/Billy_Bones</code>
" would show every instance of the name "Billy Bones" highlighted, as if a "Find" for that name was executed on the page via the browser.</p>
<p>I imagine something like this is required, client-side:</p>
<pre style="" class="default prettyprint prettyprinted">
<code>
<span class="kwd">var</span>
<span class="pln"> employee </span>
<span class="pun">=</span>
<span class="pln"> getLastURLPortion</span>
<span class="pun">();</span>
<span class="pln"></span>
<span class="com">// return "Billy_Bones" (or whatever)</span>
<span class="pln">
employee </span>
<span class="pun">=</span>
<span class="pln"> humanifyTheName</span>
<span class="pun">(</span>
<span class="pln">employee</span>
<span class="pun">);</span>
<span class="pln"></span>
<span class="com">// replaces underscores with spaces, so that it's "Billy Bones" (etc.)</span>
<span class="pln"></span>
<span class="typ">Highlight</span>
<span class="pun">(</span>
<span class="pln">employee</span>
<span class="pun">);</span>
<span class="pln"></span>
<span class="com">// this I have no clue how to do</span>
</code>
</pre>
<p>Can this be done in HTML/CSS, or is JavaScript or jQuery also required for this?</p>
</div>
10067700cookie-checkWie kann ich Zeichenfolgen auf einer Webseite dynamisch hervorheben?yes
Bier auch nicht, aber an einem heißen Tag ist es schrecklich gut.
– B. Ton Shannon-B. Krähenrabe
23. August 2015 um 13:00 Uhr
Verwenden Sie ein Textmarker-Plugin
– charlietfl
23. August 2015 um 13:04 Uhr
Ich denke, die eigentliche Frage ist, wie die Seiten gerendert werden, und können Sie etwas in der Vorlage dafür hinzufügen?
– Kelly J. Andrews
23. August 2015 um 13:13 Uhr
@Xufox, deshalb habe ich vorgeschlagen, ein Plugin zu verwenden, das bereits kampferprobt ist. Sobald sich jemand damit beschäftigt, stellt er fest, dass es keine triviale Übung ist, die HTML-Struktur beizubehalten und Ereignisse nicht zu stören
– charlietfl
23. August 2015 um 13:27 Uhr
Es sieht nicht so aus wie beim OP irgendein recherchieren Sie überhaupt, bevor Sie diese Frage stellen. OP scheint zu glauben, dass es möglich sein könnte, 3 spezifische Technologien zu verwenden, macht sich jedoch nicht die Mühe, jeweils eine grundlegende Suche durchzuführen (z. B. “Text mit Javascript hervorheben” oder “Text mit CSS hervorheben”). Sie sollten recherchieren, bevor Sie Ihre Frage stellen, Kinder!
– Zimt
23. August 2015 um 15:28 Uhr