누군가가 웹 페이지의 텍스트를 강조 할 수있는 자바 스크립트 기능으로 나를 도울 수 있습니까? 그리고 요구 사항은-한 번만 강조 표시하는 것입니다. 검색의 경우처럼 텍스트의 모든 항목을 강조 표시하는 것과는 다릅니다.
누군가가 웹 페이지의 텍스트를 강조 할 수있는 자바 스크립트 기능으로 나를 도울 수 있습니까? 그리고 요구 사항은-한 번만 강조 표시하는 것입니다. 검색의 경우처럼 텍스트의 모든 항목을 강조 표시하는 것과는 다릅니다.
답변:
jquery 강조 효과를 사용할 수 있습니다 .
그러나 원시 자바 스크립트 코드에 관심이 있으시면 제가 얻은 것을 살펴보십시오. HTML에 붙여 넣기를 복사하고 파일을 열고 "강조 표시"를 클릭하십시오. 그러면 "fox"라는 단어가 강조 표시됩니다. 성능면에서는 이것이 작은 텍스트와 한 번의 반복 (지정한 것처럼)에 대해 할 것이라고 생각합니다.
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을 대체하려면 innerHTML
문서 본문을 참조해야합니다 .
document.body.innerHTML
"<span class='highlight'>"
와 "<span style='color: " + color + ";'>"
같은 색이어야 뭔가var color = "#ff0000";
<img src="fox.jpg" />
다음과 같은 경우에 어떤 일이 발생 <img src="<span class='highlight'>fox</span>.jpg" />
여기에 제공된 솔루션은 매우 나쁩니다.
&
for & <
, >
for>, ä
for >, for ä, ö
for ö ü
for ü ß
for ß 등).해야 할 일 :
루프가 HTML 문서를 통해 얻을 모든 텍스트 노드를 찾을 수 textContent
와 하이라이트 텍스트의 위치를 얻을 수 indexOf
(선택 사양으로 toLowerCase
는 대소 문자를 구분해야하는 경우)하기 전에, APPEND 모든 것을 indexof
같은 textNode
, APPEND 하이라이트 범위와 일치하는 텍스트, 나머지 텍스트 노드에 대해 반복합니다 (강조 문자열은 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, '%')
[당신이, 당신은 전체 텍스트 검색 또는 루씬을 사용해야하지 말아야한다, 당신은, 그런 식으로 모든 문자를 이스케이프 \ 및 SQL-탈출 문을 추가 할 수 있습니다 LIKE 표현식 인 특수 문자를 찾을 수 있습니다.
예 :
WHERE textField LIKE CONCAT('%', @query, '%') ESCAPE '\'
및 @query의 값이 아닌 '%completed%'
하지만'%\c\o\m\p\l\e\t\e\d%'
(테스트 완료, SQL-Server 및 PostgreSQL 및 ESCAPE를 지원하는 다른 모든 RDBMS 시스템에서 작동)
수정 된 typescript 버전 :
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
ä
예를 들어를 사용하는 경우에도 실제 문자로 변환됩니다 innerHTML
.
처음부터 자신 만의 하이라이트 기능을 구축하는 것이 좋지 않은 이유는 다른 사람들이 이미 해결 한 문제에 부딪 힐 것이기 때문입니다. 과제 :
innerHTML
).복잡하게 들리나요? 강조 표시, 분음 부호 매핑, 동의어 매핑, iframe 내부 검색, 분리 된 단어 검색 등에서 일부 요소를 무시하는 것과 같은 일부 기능을 원하는 경우 이는 점점 더 복잡해집니다.
잘 구현 된 기존 플러그인을 사용할 때 위에 언급 된 것에 대해 걱정할 필요가 없습니다. Sitepoint 의 기사 10 jQuery 텍스트 하이 라이터 플러그인은 인기있는 하이 라이터 플러그인 을 비교합니다.
mark.js 는 순수한 JavaScript로 작성된 플러그인이지만 jQuery 플러그인으로도 사용할 수 있습니다. 다음과 같은 옵션이있는 다른 플러그인보다 더 많은 기회를 제공하도록 개발되었습니다.
또는 이 바이올린을 볼 수 있습니다 .
사용 예 :
// Highlight "keyword" in the specified context
$(".context").mark("keyword");
// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);
GitHub에서 무료로 개발 된 오픈 소스입니다 ( 프로젝트 참조 ).
acrossElements
옵션을 사용하여 태그간에 일치하는 항목을 찾을 수 있습니다 . 그리고 세 번째 주석에; mark.js는 제공하는 기능에 비해 크지 않습니다. 그리고 아니요, mark.js가 예를 들어 Chrome 30을 시작하고 크로스 브라우저 단위 테스트가있는 모든 최신 버전에서 테스트되었으므로 향후 버전에 문제가 없었기 때문에 미래에 문제가 발생할 가능성은 거의 없습니다.
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";
가 CSS로 번역 된다는 알림 / 팁 style="background-color: yellow;"
-camelCase와 점선 표기법의 미묘한 차이가 처음에는 나를 괴롭 혔습니다.
다음은 내 정규식 순수 JavaScript 솔루션입니다.
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
>
. (?!([^<]+)?<)
작동 하도록 정규식을 수정하십시오 .
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>")
질문에 대답하려면 regexp 옵션에서 g를 생략하고 첫 번째 항목 만 대체되지만 여전히 img src 속성에있는 항목이며 이미지 태그를 파괴합니다.
<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>");
});
<img src="word">
또는 <a href="word">
.
다른 솔루션 중 어느 것도 내 요구 사항에 맞지 않으며 Stefan Steiger의 솔루션이 예상대로 작동했지만 너무 장황했습니다.
다음은 내 시도입니다.
/**
* 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);
참고 : 많은 부분에서 @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;
}
}
}
HTML5부터는 <mark></mark>
태그를 사용하여 텍스트를 강조 할 수 있습니다 . 자바 스크립트를 사용하여 이러한 태그 사이에 일부 텍스트 / 키워드를 래핑 할 수 있습니다. 다음은 텍스트를 표시하고 표시 해제하는 방법에 대한 간단한 예입니다.
innerHTML
위험합니다. 이벤트를 삭제합니다.
2019 년으로 빠르게 진행되는 Web API는 이제 기본적으로 텍스트 강조 표시를 지원합니다.
const selection = document.getSelection();
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
그리고 당신은 갈 수 있습니다! anchorNode
선택 시작 노드이고 focusNode
선택 종료 노드입니다. 그리고 텍스트 노드 인 offset
경우 각 노드에서 시작 및 끝 문자의 인덱스입니다. 다음은 문서입니다.
라이브 데모 도 있습니다.
나도, 당신은 내가 배운 것을 시도 할 수 있는지 궁금 이 게시 할 수 있습니다.
나는 사용했다 :
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에서 시도해 볼 수도 있습니다.
xc
페이지로드시 강조 표시되도록하려면 새로운 방법이 있습니다.
그냥 추가 #:~:text=Highlight%20These
이 링크에 액세스하십시오
/programming/38588721#:~:text=Highlight%20a%20text
범위 유형 에 서라운드 컨텐츠 () 메소드 사용 . 유일한 인수는 해당 Range를 래핑하는 요소입니다.
function styleSelected() {
bg = document.createElement("span");
bg.style.backgroundColor = "yellow";
window.getSelection().getRangeAt(0).surroundContents(bg);
}