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?
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
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:
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>" );
}
Beeindruckend, aber es sind nicht die URLs, die hervorgehoben werden sollten (sie erscheinen nur in der Adressleiste); Was hervorgehoben werden sollte, ist jedes Vorkommen von „Billy Bones“ auf der Seite (vorausgesetzt, die URL endet mit „\Billy_Bones“).
– B. Ton Shannon-B. Krähenrabe
23. August 2015 um 13:45 Uhr
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>
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