Dapatkah seseorang membantu saya dengan fungsi javascript yang dapat menyorot teks pada halaman web. Dan persyaratannya adalah - menyorot hanya sekali, tidak seperti menyorot semua kemunculan teks seperti yang kita lakukan dalam kasus pencarian.
Dapatkah seseorang membantu saya dengan fungsi javascript yang dapat menyorot teks pada halaman web. Dan persyaratannya adalah - menyorot hanya sekali, tidak seperti menyorot semua kemunculan teks seperti yang kita lakukan dalam kasus pencarian.
Jawaban:
Anda dapat menggunakan efek sorotan jquery .
Tetapi jika Anda tertarik dengan kode javascript mentah, lihat apa yang saya dapatkan. Cukup salin tempel ke HTML, buka file dan klik "sorot" - ini akan menyorot kata "rubah". Dari segi kinerja, saya pikir ini akan dilakukan untuk teks kecil dan satu pengulangan (seperti yang Anda tentukan)
function highlight(text) {
var inputText = document.getElementById("inputText");
var innerHTML = inputText.innerHTML;
var index = innerHTML.indexOf(text);
if (index >= 0) {
innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML;
}
}
.highlight {
background-color: yellow;
}
<button onclick="highlight('fox')">Highlight</button>
<div id="inputText">
The fox went over the fence
</div>
Editan:
replace
Saya melihat jawaban ini mendapatkan popularitas, saya pikir saya bisa menambahkannya. Anda juga dapat dengan mudah menggunakan ganti
"the fox jumped over the fence".replace(/fox/,"<span>fox</span>");
Atau untuk beberapa kemunculan (tidak relevan untuk pertanyaan, tetapi diminta dalam komentar) Anda cukup menambahkan global
ganti ekspresi reguler.
"the fox jumped over the other fox".replace(/fox/g,"<span>fox</span>");
Semoga ini membantu untuk komentator yang tertarik.
untuk mengganti HTML untuk seluruh halaman web, Anda harus merujuk ke innerHTML
badan dokumen.
document.body.innerHTML
"<span class='highlight'>"
dengan "<span style='color: " + color + ";'>"
, warna harus sepertivar color = "#ff0000";
<img src="fox.jpg" />
Anda akan mendapatkan HTML yang tidak valid yang akan terlihat seperti ini: <img src="<span class='highlight'>fox</span>.jpg" />
Tidak bagus
Solusi yang ditawarkan di sini cukup buruk.
&
untuk &, <
untuk <, >
untuk>, ä
untuk ä, ö
untuk ö ü
untuk üß
untuk ß, dll.Apa yang kamu butuhkan:
Ulangi dokumen HTML, temukan semua node teks, dapatkan textContent
, dapatkan posisi teks sorotan dengan indexOf
(dengan opsional toLowerCase
jika harus peka huruf besar-kecil), tambahkan semuanya sebelumnya indexof
sebagai textNode
, tambahkan Teks yang cocok dengan rentang sorotan, dan ulangi untuk sisa kode teks (string sorotan mungkin muncul beberapa kali dalam textContent
string).
Ini kode untuk ini:
var InstantSearch = {
"highlight": function (container, highlightText)
{
var internalHighlighter = function (options)
{
var id = {
container: "container",
tokens: "tokens",
all: "all",
token: "token",
className: "className",
sensitiveSearch: "sensitiveSearch"
},
tokens = options[id.tokens],
allClassName = options[id.all][id.className],
allSensitiveSearch = options[id.all][id.sensitiveSearch];
function checkAndReplace(node, tokenArr, classNameAll, sensitiveSearchAll)
{
var nodeVal = node.nodeValue, parentNode = node.parentNode,
i, j, curToken, myToken, myClassName, mySensitiveSearch,
finalClassName, finalSensitiveSearch,
foundIndex, begin, matched, end,
textNode, span, isFirst;
for (i = 0, j = tokenArr.length; i < j; i++)
{
curToken = tokenArr[i];
myToken = curToken[id.token];
myClassName = curToken[id.className];
mySensitiveSearch = curToken[id.sensitiveSearch];
finalClassName = (classNameAll ? myClassName + " " + classNameAll : myClassName);
finalSensitiveSearch = (typeof sensitiveSearchAll !== "undefined" ? sensitiveSearchAll : mySensitiveSearch);
isFirst = true;
while (true)
{
if (finalSensitiveSearch)
foundIndex = nodeVal.indexOf(myToken);
else
foundIndex = nodeVal.toLowerCase().indexOf(myToken.toLowerCase());
if (foundIndex < 0)
{
if (isFirst)
break;
if (nodeVal)
{
textNode = document.createTextNode(nodeVal);
parentNode.insertBefore(textNode, node);
} // End if (nodeVal)
parentNode.removeChild(node);
break;
} // End if (foundIndex < 0)
isFirst = false;
begin = nodeVal.substring(0, foundIndex);
matched = nodeVal.substr(foundIndex, myToken.length);
if (begin)
{
textNode = document.createTextNode(begin);
parentNode.insertBefore(textNode, node);
} // End if (begin)
span = document.createElement("span");
span.className += finalClassName;
span.appendChild(document.createTextNode(matched));
parentNode.insertBefore(span, node);
nodeVal = nodeVal.substring(foundIndex + myToken.length);
} // Whend
} // Next i
}; // End Function checkAndReplace
function iterator(p)
{
if (p === null) return;
var children = Array.prototype.slice.call(p.childNodes), i, cur;
if (children.length)
{
for (i = 0; i < children.length; i++)
{
cur = children[i];
if (cur.nodeType === 3)
{
checkAndReplace(cur, tokens, allClassName, allSensitiveSearch);
}
else if (cur.nodeType === 1)
{
iterator(cur);
}
}
}
}; // End Function iterator
iterator(options[id.container]);
} // End Function highlighter
;
internalHighlighter(
{
container: container
, all:
{
className: "highlighter"
}
, tokens: [
{
token: highlightText
, className: "highlight"
, sensitiveSearch: false
}
]
}
); // End Call internalHighlighter
} // End Function highlight
};
Kemudian Anda bisa menggunakannya seperti ini:
function TestTextHighlighting(highlightText)
{
var container = document.getElementById("testDocument");
InstantSearch.highlight(container, highlightText);
}
Berikut ini contoh dokumen HTML
<!DOCTYPE html>
<html>
<head>
<title>Example of Text Highlight</title>
<style type="text/css" media="screen">
.highlight{ background: #D3E18A;}
.light{ background-color: yellow;}
</style>
</head>
<body>
<div id="testDocument">
This is a test
<span> This is another test</span>
äöüÄÖÜäöüÄÖÜ
<span>Test123äöüÄÖÜ</span>
</div>
</body>
</html>
Ngomong-ngomong, jika Anda mencari di database dengan LIKE
,
misalnya WHERE textField LIKE CONCAT('%', @query, '%')
[yang seharusnya tidak Anda lakukan, Anda harus menggunakan pencarian teks lengkap atau Lucene], maka Anda dapat keluar dari setiap karakter dengan \ dan menambahkan pernyataan-escape-SQL, dengan cara itu Anda akan menemukan karakter khusus yang merupakan ekspresi LIKE.
misalnya
WHERE textField LIKE CONCAT('%', @query, '%') ESCAPE '\'
dan nilai @query tidak '%completed%'
tetapi'%\c\o\m\p\l\e\t\e\d%'
(diuji, berfungsi dengan SQL-Server dan PostgreSQL, dan setiap sistem RDBMS lain yang mendukung ESCAPE)
Sebuah versi skrip yang direvisi:
namespace SearchTools
{
export interface IToken
{
token: string;
className: string;
sensitiveSearch: boolean;
}
export class InstantSearch
{
protected m_container: Node;
protected m_defaultClassName: string;
protected m_defaultCaseSensitivity: boolean;
protected m_highlightTokens: IToken[];
constructor(container: Node, tokens: IToken[], defaultClassName?: string, defaultCaseSensitivity?: boolean)
{
this.iterator = this.iterator.bind(this);
this.checkAndReplace = this.checkAndReplace.bind(this);
this.highlight = this.highlight.bind(this);
this.highlightNode = this.highlightNode.bind(this);
this.m_container = container;
this.m_defaultClassName = defaultClassName || "highlight";
this.m_defaultCaseSensitivity = defaultCaseSensitivity || false;
this.m_highlightTokens = tokens || [{
token: "test",
className: this.m_defaultClassName,
sensitiveSearch: this.m_defaultCaseSensitivity
}];
}
protected checkAndReplace(node: Node)
{
let nodeVal: string = node.nodeValue;
let parentNode: Node = node.parentNode;
let textNode: Text = null;
for (let i = 0, j = this.m_highlightTokens.length; i < j; i++)
{
let curToken: IToken = this.m_highlightTokens[i];
let textToHighlight: string = curToken.token;
let highlightClassName: string = curToken.className || this.m_defaultClassName;
let caseSensitive: boolean = curToken.sensitiveSearch || this.m_defaultCaseSensitivity;
let isFirst: boolean = true;
while (true)
{
let foundIndex: number = caseSensitive ?
nodeVal.indexOf(textToHighlight)
: nodeVal.toLowerCase().indexOf(textToHighlight.toLowerCase());
if (foundIndex < 0)
{
if (isFirst)
break;
if (nodeVal)
{
textNode = document.createTextNode(nodeVal);
parentNode.insertBefore(textNode, node);
} // End if (nodeVal)
parentNode.removeChild(node);
break;
} // End if (foundIndex < 0)
isFirst = false;
let begin: string = nodeVal.substring(0, foundIndex);
let matched: string = nodeVal.substr(foundIndex, textToHighlight.length);
if (begin)
{
textNode = document.createTextNode(begin);
parentNode.insertBefore(textNode, node);
} // End if (begin)
let span: HTMLSpanElement = document.createElement("span");
if (!span.classList.contains(highlightClassName))
span.classList.add(highlightClassName);
span.appendChild(document.createTextNode(matched));
parentNode.insertBefore(span, node);
nodeVal = nodeVal.substring(foundIndex + textToHighlight.length);
} // Whend
} // Next i
} // End Sub checkAndReplace
protected iterator(p: Node)
{
if (p == null)
return;
let children: Node[] = Array.prototype.slice.call(p.childNodes);
if (children.length)
{
for (let i = 0; i < children.length; i++)
{
let cur: Node = children[i];
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
if (cur.nodeType === Node.TEXT_NODE)
{
this.checkAndReplace(cur);
}
else if (cur.nodeType === Node.ELEMENT_NODE)
{
this.iterator(cur);
}
} // Next i
} // End if (children.length)
} // End Sub iterator
public highlightNode(n:Node)
{
this.iterator(n);
} // End Sub highlight
public highlight()
{
this.iterator(this.m_container);
} // End Sub highlight
} // End Class InstantSearch
} // End Namespace SearchTools
Pemakaian:
let searchText = document.getElementById("txtSearchText");
let searchContainer = document.body; // document.getElementById("someTable");
let highlighter = new SearchTools.InstantSearch(searchContainer, [
{
token: "this is the text to highlight" // searchText.value,
className: "highlight", // this is the individual highlight class
sensitiveSearch: false
}
]);
// highlighter.highlight(); // this would highlight in the entire table
// foreach tr - for each td2
highlighter.highlightNode(td2); // this highlights in the second column of table
ä
mis. akan diubah menjadi karakter sebenarnya, bahkan saat menggunakan innerHTML
.
Alasan mengapa mungkin ide yang buruk untuk mulai membangun fungsi penyorotan Anda sendiri dari awal adalah karena Anda pasti akan mengalami masalah yang telah diselesaikan orang lain. Tantangan:
innerHTML
)Kedengarannya rumit? Jika Anda menginginkan beberapa fitur seperti mengabaikan beberapa elemen dari penyorotan, pemetaan diakritik, pemetaan sinonim, pencarian di dalam iframe, pencarian kata terpisah, dll. Ini menjadi semakin rumit.
Saat menggunakan plugin yang sudah ada dan diimplementasikan dengan baik, Anda tidak perlu khawatir tentang hal-hal yang disebutkan di atas. Artikel 10 plugin penyorot teks jQuery di Sitepoint membandingkan plugin penyorot populer.
mark.js adalah plugin semacam itu yang ditulis dalam JavaScript murni, tetapi juga tersedia sebagai plugin jQuery. Itu dikembangkan untuk menawarkan lebih banyak peluang daripada plugin lain dengan opsi untuk:
Atau Anda bisa melihat biola ini .
Contoh penggunaan :
// Highlight "keyword" in the specified context
$(".context").mark("keyword");
// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);
Ini gratis dan dikembangkan sebagai sumber terbuka di GitHub ( referensi proyek ).
acrossElements
opsi. Dan untuk komentar ketiga; mark.js tidak besar dibandingkan dengan fungsionalitas yang ditawarkannya. Dan tidak, tidak mungkin ada sesuatu yang rusak di masa mendatang, karena mark.js telah diuji, misalnya memulai Chrome 30 dan di semua versi yang lebih baru dengan pengujian unit lintas-browser dan tidak pernah ada masalah dengan versi yang akan datang.
function stylizeHighlightedString() {
var text = window.getSelection();
// For diagnostics
var start = text.anchorOffset;
var end = text.focusOffset - text.anchorOffset;
range = window.getSelection().getRangeAt(0);
var selectionContents = range.extractContents();
var span = document.createElement("span");
span.appendChild(selectionContents);
span.style.backgroundColor = "yellow";
span.style.color = "black";
range.insertNode(span);
}
span.style.backgroundColor = "yellow";
diterjemahkan ke CSS style="background-color: yellow;"
- perbedaan halus antara camelCase dan notasi putus-putus membuat saya tersandung pada awalnya.
Inilah solusi JavaScript murni regexp saya:
function highlight(text) {
document.body.innerHTML = document.body.innerHTML.replace(
new RegExp(text + '(?!([^<]+)?<)', 'gi'),
'<b style="background-color:#ff0;font-size:100%">$&</b>'
);
}
one|two|three
>
karakter. Ubah regex (?!([^<]+)?<)
agar berfungsi.
Saya memiliki masalah yang sama, banyak teks masuk melalui permintaan xmlhttp. Teks ini berformat html. Saya perlu menyoroti setiap kejadian.
str='<img src="brown fox.jpg" title="The brown fox" />'
+'<p>some text containing fox.</p>'
Masalahnya adalah saya tidak perlu menyorot teks dalam tag. Misalnya saya perlu menyorot rubah:
Sekarang saya bisa menggantinya dengan:
var word="fox";
word="(\\b"+
word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
+ "\\b)";
var r = new RegExp(word,"igm");
str.replace(r,"<span class='hl'>$1</span>")
Untuk menjawab pertanyaan Anda: Anda dapat mengabaikan g di opsi regexp dan hanya kemunculan pertama yang akan diganti tetapi ini masih yang ada di properti img src dan menghancurkan tag gambar:
<img src="brown <span class='hl'>fox</span>.jpg" title="The brown <span
class='hl'>fox</span> />
Ini adalah cara saya menyelesaikannya tetapi bertanya-tanya apakah ada cara yang lebih baik, sesuatu yang saya lewatkan dalam ekspresi reguler:
str='<img src="brown fox.jpg" title="The brown fox" />'
+'<p>some text containing fox.</p>'
var word="fox";
word="(\\b"+
word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
+ "\\b)";
var r = new RegExp(word,"igm");
str.replace(/(>[^<]+<)/igm,function(a){
return a.replace(r,"<span class='hl'>$1</span>");
});
<img src="word">
atau <a href="word">
.
Tidak ada solusi lain yang benar-benar sesuai dengan kebutuhan saya, dan meskipun solusi Stefan Steiger berfungsi seperti yang saya harapkan, saya merasa sedikit terlalu bertele-tele.
Berikut adalah usaha saya:
/**
* Highlight keywords inside a DOM element
* @param {string} elem Element to search for keywords in
* @param {string[]} keywords Keywords to highlight
* @param {boolean} caseSensitive Differenciate between capital and lowercase letters
* @param {string} cls Class to apply to the highlighted keyword
*/
function highlight(elem, keywords, caseSensitive = false, cls = 'highlight') {
const flags = caseSensitive ? 'gi' : 'g';
// Sort longer matches first to avoid
// highlighting keywords within keywords.
keywords.sort((a, b) => b.length - a.length);
Array.from(elem.childNodes).forEach(child => {
const keywordRegex = RegExp(keywords.join('|'), flags);
if (child.nodeType !== 3) { // not a text node
highlight(child, keywords, caseSensitive, cls);
} else if (keywordRegex.test(child.textContent)) {
const frag = document.createDocumentFragment();
let lastIdx = 0;
child.textContent.replace(keywordRegex, (match, idx) => {
const part = document.createTextNode(child.textContent.slice(lastIdx, idx));
const highlighted = document.createElement('span');
highlighted.textContent = match;
highlighted.classList.add(cls);
frag.appendChild(part);
frag.appendChild(highlighted);
lastIdx = idx + match.length;
});
const end = document.createTextNode(child.textContent.slice(lastIdx));
frag.appendChild(end);
child.parentNode.replaceChild(frag, child);
}
});
}
// Highlight all keywords found in the page
highlight(document.body, ['lorem', 'amet', 'autem']);
.highlight {
background: lightpink;
}
<p>Hello world lorem ipsum dolor sit amet, consectetur adipisicing elit. Est vel accusantium totam, ipsum delectus et dignissimos mollitia!</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, corporis.
<small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium autem voluptas perferendis dolores ducimus velit error voluptatem, qui rerum modi?</small>
</p>
Saya juga akan merekomendasikan menggunakan sesuatu seperti escape-string-regexp jika kata kunci Anda dapat memiliki karakter khusus yang perlu di-escape dalam regex:
const keywordRegex = RegExp(keywords.map(escapeRegexp).join('|')), flags);
CATATAN: Meskipun saya setuju dengan @Stefan dalam banyak hal, saya hanya membutuhkan sorotan kecocokan sederhana :
module myApp.Search {
'use strict';
export class Utils {
private static regexFlags = 'gi';
private static wrapper = 'mark';
private static wrap(match: string): string {
return '<' + Utils.wrapper + '>' + match + '</' + Utils.wrapper + '>';
}
static highlightSearchTerm(term: string, searchResult: string): string {
let regex = new RegExp(term, Utils.regexFlags);
return searchResult.replace(regex, match => Utils.wrap(match));
}
}
}
Dan kemudian menyusun hasil aktual:
module myApp.Search {
'use strict';
export class SearchResult {
id: string;
title: string;
constructor(result, term?: string) {
this.id = result.id;
this.title = term ? Utils.highlightSearchTerm(term, result.title) : result.title;
}
}
}
Sejak HTML5 Anda dapat menggunakan file <mark></mark>
tag untuk menyorot teks. Anda dapat menggunakan javascript untuk membungkus beberapa teks / kata kunci di antara tag ini. Berikut ini sedikit contoh cara menandai dan menghapus tanda teks.
innerHTML
berbahaya. Ini akan menghapus acara.
Maju cepat ke 2019, API Web sekarang memiliki dukungan asli untuk menyorot teks:
const selection = document.getSelection();
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
Dan Anda siap berangkat! anchorNode
adalah simpul awal pemilihan, focusNode
adalah simpul akhir pemilihan. Dan, jika mereka adalah node teks, offset
adalah indeks dari karakter awal dan akhir di node masing-masing. Berikut dokumentasinya
Mereka bahkan memiliki demo langsung
Saya juga bertanya-tanya, Anda bisa mencoba apa yang saya pelajari di posting ini .
Saya menggunakan:
function highlightSelection() {
var userSelection = window.getSelection();
for(var i = 0; i < userSelection.rangeCount; i++) {
highlightRange(userSelection.getRangeAt(i));
}
}
function highlightRange(range) {
var newNode = document.createElement("span");
newNode.setAttribute(
"style",
"background-color: yellow; display: inline;"
);
range.surroundContents(newNode);
}
<html>
<body contextmenu="mymenu">
<menu type="context" id="mymenu">
<menuitem label="Highlight Yellow" onclick="highlightSelection()" icon="/images/comment_icon.gif"></menuitem>
</menu>
<p>this is text, select and right click to high light me! if you can`t see the option, please use this<button onclick="highlightSelection()">button </button><p>
Anda juga dapat mencobanya di sini: http://henriquedonati.com/projects/Extension/extension.html
xc
Kami jika Anda juga ingin disorot pada pemuatan halaman, ada cara baru.
tambahkan saja #:~:text=Highlight%20These
coba akses tautan ini
/programming/38588721#:~:text=Highlight%20a%20text
Menggunakan metode surroundContents () pada tipe Range . Argumen satu-satunya adalah elemen yang akan membungkus Range itu.
function styleSelected() {
bg = document.createElement("span");
bg.style.backgroundColor = "yellow";
window.getSelection().getRangeAt(0).surroundContents(bg);
}