Как выделить текст с помощью JavaScript
Может кто-нибудь помочь мне с функцией JavaScript, которая может выделить текст на веб-странице. И требование - выделять только один раз, а не выделять все вхождения текста, как в случае поиска.
21 ответ
Вы можете использовать эффект выделения jquery.
Но если вас интересует сырой код JavaScript, посмотрите, что я получил. Просто скопируйте вставить в HTML, откройте файл и нажмите "выделить" - это должно выделить слово "лиса". Думаю, это будет полезно для небольшого текста и одного повторения (как вы указали)
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>
Редактирование:
С помощью replace
Я вижу, что этот ответ приобрел некоторую популярность, я думал, что мог бы добавить к нему. Вы также можете легко использовать заменить
"the fox jumped over the fence".replace(/fox/,"<span>fox</span>");
Или для нескольких случаев (не относится к вопросу, но был задан в комментариях), вы просто добавляете global
на регулярное выражение замены.
"the fox jumped over the other fox".replace(/fox/g,"<span>fox</span>");
Надеюсь, это поможет заинтригованным комментаторам.
Замена HTML на всю веб-страницу
чтобы заменить HTML для всей веб-страницы, вы должны обратиться к innerHTML
тела документа.
document.body.innerHTML
Предлагаемые здесь решения довольно плохие.
- Вы не можете использовать регулярные выражения, потому что таким образом, вы ищете / выделить в тегах HTML.
- Вы не можете использовать регулярные выражения, потому что он не работает должным образом с UTF* (что-нибудь с нелатинскими / английскими символами).
- Вы не можете просто сделать innerHTML.replace, потому что это не работает, когда символы имеют специальную HTML-нотацию, например
&
за &,<
для <,>
для>,ä
для,ö
для öü
для тебяß
для ß и т. д.
Что тебе необходимо сделать:
Перебрать документ HTML, найти все текстовые узлы, получить textContent
получить позицию выделения текста с помощью indexOf
(с дополнительным toLowerCase
если это должно быть без учета регистра), добавьте все до indexof
как textNode
добавьте соответствующий текст с выделенным интервалом и повторите для остальной части текстового узла (строка выделения может появляться несколько раз в textContent
строка).
Вот код для этого:
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
};
Тогда вы можете использовать это так:
function TestTextHighlighting(highlightText)
{
var container = document.getElementById("testDocument");
InstantSearch.highlight(container, highlightText);
}
Вот пример 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>
Кстати, если вы ищете в базе данных с LIKE
,
например WHERE textField LIKE CONCAT('%', @query, '%')
[что вы не должны делать, вы должны использовать полнотекстовый поиск или Lucene], тогда вы можете экранировать каждый символ с помощью \ и добавить SQL-escape-оператор, в результате чего вы найдете специальные символы, которые являются LIKE-выражениями.
например
WHERE textField LIKE CONCAT('%', @query, '%') ESCAPE '\'
и значение @query не '% completed'
но '\%\ \c\o\m\p\l\e\t\e\d'
(протестировано, работает с SQL-Server и PostgreSQL и любой другой системой RDBMS, которая поддерживает ESCAPE)
Пересмотренная машинописная версия:
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
Использование:
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
Почему использование самодельной функции подсветки - плохая идея
Причина, по которой, вероятно, плохая идея начать создавать свою собственную функцию подсветки с нуля, заключается в том, что вы наверняка столкнетесь с проблемами, которые другие уже решили. проблемы:
- Вам нужно было бы удалить текстовые узлы с элементами HTML, чтобы выделить совпадения, не разрушая события DOM и не вызывая повторную генерацию DOM (что было бы в случае, например, с
innerHTML
) - Если вы хотите удалить выделенные элементы, вам придется удалить элементы HTML с их содержимым, а также объединить разделенные текстовые узлы для дальнейшего поиска. Это необходимо, потому что каждый плагин подсветки ищет совпадения в текстовых узлах, и если ваши ключевые слова будут разбиты на несколько текстовых узлов, они не будут найдены.
- Вам также необходимо создать тесты, чтобы убедиться, что ваш плагин работает в ситуациях, о которых вы не задумывались. И я говорю о кросс-браузерных тестах!
Звучит сложно? Если вам нужны такие функции, как игнорирование некоторых элементов при выделении, отображение диакритических знаков, отображение синонимов, поиск внутри фреймов, поиск по отдельным словам и т. Д., Это становится все более и более сложным.
Использовать существующий плагин
При использовании существующего, хорошо реализованного плагина, вам не нужно беспокоиться о вышеперечисленных вещах. В статье 10 плагинов для подсветки текста jQuery на Sitepoint сравниваются популярные плагины подсветки.
Посмотрите на mark.js
mark.js - такой плагин, который написан на чистом JavaScript, но также доступен как плагин jQuery. Он был разработан, чтобы предложить больше возможностей, чем другие плагины, с возможностью:
- искать ключевые слова отдельно вместо полного термина
- диакритические знаки на карте (например, если "justo" также должен соответствовать "justò")
- игнорировать совпадения внутри пользовательских элементов
- использовать пользовательский элемент подсветки
- использовать пользовательский класс подсветки
- карта пользовательских синонимов
- искать также внутри фреймов
- получить не найденные условия
В качестве альтернативы вы можете увидеть эту скрипку.
Пример использования:
// Highlight "keyword" in the specified context
$(".context").mark("keyword");
// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);
Это бесплатный и разработанный с открытым исходным кодом на GitHub ( ссылка на проект).
Ни одно из других решений не соответствовало моим потребностям, и хотя решение Стефана Штайгера работало так, как я ожидал, я нашел его слишком многословным.
Следующее - моя попытка:
/**
* 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>
Я также рекомендовал бы использовать что-то вроде escape-string-regexp, если ваши ключевые слова могут иметь специальные символы, которые необходимо экранировать в регулярных выражениях:
const keywordRegex = RegExp(keywords.map(escapeRegexp).join('|')), flags);
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);
}
Вот мое регулярное выражение для чистого JavaScript:
function highlight(text) {
document.body.innerHTML = document.body.innerHTML.replace(
new RegExp(text + '(?!([^<]+)?<)', 'gi'),
'<b style="background-color:#ff0;font-size:100%">$&</b>'
);
}
С HTML5 вы можете использовать <mark></mark>
теги для выделения текста. Вы можете использовать JavaScript для переноса текста / ключевого слова между этими тегами. Вот небольшой пример того, как пометить и снять пометку с текста.
Если вы также хотите, чтобы он выделялся при загрузке страницы, есть новый способ.
просто добавь #:~:text=Highlight%20These
попробуйте получить доступ к этой ссылке
https://stackru.com/questions/38588721#:~:text=Highlight%20a%20text
Перенесемся в 2019 год: в веб-API теперь есть встроенная поддержка выделения текста:
const selection = document.getSelection();
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
И вам хорошо! anchorNode
- начальный узел выбора, focusNode
- конечный узел выбора. И, если это текстовые узлы,offset
- это индекс начального и конечного символа в соответствующих узлах. Вот документация
У них даже есть живая демонстрация
У меня та же проблема, куча текста приходит через запрос xmlhttp. Этот текст в формате HTML. Мне нужно выделить каждый случай.
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(r,"<span class='hl'>$1</span>")
Чтобы ответить на ваш вопрос: вы можете не указывать g в параметрах регулярного выражения, и будет заменено только первое вхождение, но оно все еще остается в свойстве img src и уничтожает тег image:
<img src="brown <span class='hl'>fox</span>.jpg" title="The brown <span
class='hl'>fox</span> />
Я решил это таким образом, но мне было интересно, есть ли лучший способ, который я пропустил в регулярных выражениях:
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>");
});
Простой пример TypeScript
ПРИМЕЧАНИЕ. Хотя я во многом согласен с @Stefan, мне потребовалась только простая подсветка совпадений:
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));
}
}
}
А затем построим фактический результат:
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;
}
}
}
Я думаю, что этот код лучше, потому что выделяет все повторяющиеся символы
Просто передайте свое слово в следующую функцию :
function highlight_words(word) {
const page = document.body.innerHTML;
document.body.innerHTML = page.replace(new RegExp(word, "gi"), (match) => `<mark>${match}</mark>`);
}
Использование :
highlight_words("hello")
Это выделит все вхождения слова на странице.
Мне тоже было интересно, что вы можете попробовать то, что я узнал в этом посте.
Я использовал:
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>
Вы также можете попробовать это здесь: http://henriquedonati.com/projects/Extension/extension.html
хс
Я нашел плагин для подсветки, который лучше всего подходит, с его помощью вы можете выделить часть содержимого:
. $('Ли') выделить ('бла');
Я хотел бы подробнее рассказать об использовании фрагмента текста прокрутки
синтаксис:
#:~:text=[prefix-,]textStart[,textEnd][,-suffix]
подробнее: https://web.dev/text-fragments/#textstart
Я реализовал нечто подобное недавно. Моя цель состояла в том, чтобы реализовать выделение текста при поиске. Вот как я это сделал -
Создал регулярное выражение с полученным вводом.
const regex = new RegExp(`(${value})`, 'gi');
Пройдено по дереву элементов соответствующего элемента. А затем искал полученный ввод в текстовых узлах (вместо innerHTML, чтобы избежать совпадений в атрибутах, например, class, href и т. д.). Когда была получена спичка. Он (текстовый узел) был заменен на диапазон-оболочку, содержащий требуемый диапазон. Например.
text ---> <wrapper-span><span> text </span></wrapper-span>
Итак, я смог выделить свой текст.
highlightStr(value, regex, document.getELementById('searchable-div');
const highlightStr = (value, regex, node) => {
node.childNodes.forEach((childNode) => {
if (childNode.nodeValue && regex.test(childNode.nodeValue)) {
const highLightWrapper = document.createElement('span');
highLightWrapper.classList.add("highlight-wrapper-class");
childNode.replaceWith(highLightedWrapper);
highLightWrapper.innerHTML = childNode.nodeValue.replace(regex, `<span class="highlight">${value}</span>`);
}
this.highlightStr(value, regex, childNode);
});
}
Но теперь проблема в том, что если мы не удалим (или проверим наличие существующей) структуры wrapper-span, прежде чем снова попытаемся выделить текст. Мы можем закончить с бесконечным деревом промежутков оболочки или неработающим поиском. Поэтому я реализовал для него функцию сброса. Возможно, вы захотите запускать его каждый раз, когда хотите выделить текст. По сути, он просто заменяет текстовый узел его текстовым содержимым. Таким образом, мы получаем именно то, что у нас было до выделения текста.
resetHighlight(document.getELementById('searchable-div');
const resetHighlight = (node) => {
node.childNodes.forEach((childNode) => {
if ((childNode as HTMLElement).classList && (childNode as HTMLElement).classList.contains('highlight-wrapper-class') && childNode.textContent) {
childNode.replaceWith(childNode.textContent);
}
this.resetHighlight(childNode);
});
}
Вот кое-что, что я получил при работе с React.js
import React from 'react';
interface HighlightProps {
text: string;
searchTerm: string;
highlightStyle?: React.CSSProperties;
}
const defaultHighlightStyle: React.CSSProperties = {
backgroundColor: 'yellow',
};
const Highlight: React.FC<HighlightProps> = ({
text,
searchTerm,
highlightStyle = defaultHighlightStyle,
}) => {
if (!searchTerm) {
return <span>{text}</span>;
}
const regex = new RegExp(`(${searchTerm})`, 'gi');
const parts = text.split(regex);
return (
<span>
{parts.map((part, index) =>
part.toLowerCase() === searchTerm.toLowerCase() ? (
<span key={index} style={highlightStyle}>
{part}
</span>
) : (
<React.Fragment key={index}>{part}</React.Fragment>
),
)}
</span>
);
};
export default Highlight;
Назовите это так:
const ExampleComponent = () => {
const someContent = 'the quick brown fox jumped over the lazy dog';
const textToHighlight = 'fox';
return (
<Highlight text={someContent} searchTerm={textToHighlight} />
);
}
О кибернетике: Спасибо, функция ниже работает. Но есть проблема, потому что он заменяет также слова внутри тегов. Ниже приведен пример целевого слова, которое нужно выделить:
<a <mark>target</mark>="_blank" href="Its not OK to highlight <mark>target</mark> here">Its OK to highlight the words <mark>target</mark>s here</a>
Как это предотвратить?
function highlight_words(word) {
const page = document.body.innerHTML;
document.body.innerHTML = page.replace(new RegExp(word, "gi"), (match) => `<mark>${match}</mark>`);
}
Если вы окружите какой-либо текст внутри тега mark, он будет автоматически выделен браузером этим ярким желтым цветом. Подробности доступны здесь: https://dev.to/comscience/highlight-searched-text-on-a-page-with-just-javascript-17b3.
<h1>
Searching and Marking
</h1>
<input type="text" id="search"/>
<button onClick="search(id)" id="button">
Highlight
</button>
<p id="text">
What exactly is this Worker thread module, and why do we need it? In this post, we will talk about the historical reasons concurrency is implemented in JavaScript and Node.js, the problems we might find, current solutions, and the future of parallel processing with Worker threads.
Living in a single-threaded world
JavaScript was conceived as a single-threaded programming language that ran in a browser. Being single-threaded means that only one set of instructions is executed at any time in the same process (the browser, in this case, or just the current tab in modern browsers).
This made things easier for implementation and for developers using the language. JavaScript was initially a language only useful for adding some interaction to webpages, form validations, and so on — nothing that required the complexity of multithreading.
</p>
Теперь код JS будет выглядеть так
function search(e) {
let searched = document.getElementById("search").value.trim();
if (searched !== "") {
let text = document.getElementById("text").innerHTML;
let re = new RegExp(searched,"g"); // search for all instances
let newText = text.replace(re, `<mark>${searched}</mark>`);
document.getElementById("text").innerHTML = newText;
}
}
Использование метода surroundContents() для типа Range. Единственный аргумент - это элемент, который обернет этот Range.
function styleSelected() {
bg = document.createElement("span");
bg.style.backgroundColor = "yellow";
window.getSelection().getRangeAt(0).surroundContents(bg);
}