리액트를 사용하여 텍스트 강조 표시JS
쿼리와 일치하는 텍스트를 강조 표시하려고 하는데 태그가 텍스트가 아닌 HTML로 표시되는 방법을 알 수 없습니다.
var Component = React.createClass({
_highlightQuery: function(name, query) {
var regex = new RegExp("(" + query + ")", "gi");
return name.replace(regex, "<strong>$1</strong>");
},
render: function() {
var name = "Javascript";
var query = "java"
return (
<div>
<input type="checkbox" /> {this._highlightQuery(name, query)}
</div>
);
}
});
현재 출력: <strong> Java </strong> 스크립트
원하는 출력: Javascript
간단한 Twoliner 도우미 방법은 다음과 같습니다.
getHighlightedText(text, highlight) {
// Split text on highlight term, include term itself into parts, ignore case
const parts = text.split(new RegExp(`(${highlight})`, 'gi'));
return <span>{parts.map(part => part.toLowerCase() === highlight.toLowerCase() ? <b>{part}</b> : part)}</span>;
}
이 강조 합니다.<b> </b>
필요한 경우 다른 태그를 사용하도록 간단히 수정할 수 있습니다.
업데이트: 키 누락 경고를 피하기 위해 부품에 맞는 글꼴 무게 스타일 설정과 스팬에 기반한 솔루션을 다음에 제시합니다.
getHighlightedText(text, highlight) {
// Split on highlight term and include term into parts, ignore case
const parts = text.split(new RegExp(`(${highlight})`, 'gi'));
return <span> { parts.map((part, i) =>
<span key={i} style={part.toLowerCase() === highlight.toLowerCase() ? { fontWeight: 'bold' } : {} }>
{ part }
</span>)
} </span>;
}
입니다.<mark>
태그를 지정하여 텍스트를 강조 표시합니다.
const Highlighted = ({text = '', highlight = ''}) => {
if (!highlight.trim()) {
return <span>{text}</span>
}
const regex = new RegExp(`(${_.escapeRegExp(highlight)})`, 'gi')
const parts = text.split(regex)
return (
<span>
{parts.filter(part => part).map((part, i) => (
regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>
))}
</span>
)
}
사용법은 다음과 같습니다.
<Highlighted text="the quick brown fox jumps over the lazy dog" highlight="fox"/>
NPM에는 이미 원하는 작업을 수행할 수 있는 반응 컴포넌트가 있습니다.
var Highlight = require('react-highlighter');
[...]
<Highlight search={regex}>{name}</Highlight>
제 해결책은 이렇습니다.
퍼포먼스에 했기 리액트 등)은 .dangerouslySetInnerHTML
.
이 은 후속 를 단일 합니다.<span/>
용장 스팬을 회피합니다.
const Highlighter = ({children, highlight}) => {
if (!highlight) return children;
const regexp = new RegExp(highlight, 'g');
const matches = children.match(regexp);
console.log(matches, parts);
var parts = children.split(new RegExp(`${highlight.replace()}`, 'g'));
for (var i = 0; i < parts.length; i++) {
if (i !== parts.length - 1) {
let match = matches[i];
// While the next part is an empty string, merge the corresponding match with the current
// match into a single <span/> to avoid consequent spans with nothing between them.
while(parts[i + 1] === '') {
match += matches[++i];
}
parts[i] = (
<React.Fragment key={i}>
{parts[i]}<span className="highlighted">{match}</span>
</React.Fragment>
);
}
}
return <div className="highlighter">{parts}</div>;
};
사용방법:
<Highlighter highlight='text'>Some text to be highlighted</Highlighter>
이 코드펜에서 실제 예를 확인하십시오.
으로는 리액트 JS는 XSS를합니다.JS HTML XSS를 사용합니다. 을 는, 한 어트리뷰트 HTML 을 .dangerouslySetInnerHTML
해 보십시오 이치노
render: function() {
var name = "Javascript";
var query = "java"
return (
<div>
<input type="checkbox" /> <span dangerouslySetInnerHTML={{__html: this._highlightQuery(name, query)}}></span>
</div>
);
}
const escapeRegExp = (str = '') => (
str.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1')
);
const Highlight = ({ search = '', children = '' }) => {
const patt = new RegExp(`(${escapeRegExp(search)})`, 'i');
const parts = String(children).split(patt);
if (search) {
return parts.map((part, index) => (
patt.test(part) ? <mark key={index}>{part}</mark> : part
));
} else {
return children;
}
};
<Highlight search="la">La La Land</Highlight>
★★★★★★★★★★★★★★★★ react-mark.js
을 사용하다
<Marker mark="hello">
Hello World
</Marker>
링크:
- NPM : https://www.npmjs.com/package/react-mark.js
- 문서: https://stackblitz.com/edit/react-mark-js?file=src/App.js
https://codesandbox.io/s/pensive-diffie-nwwxe?file=/src/App.js 함수로 일치 표시
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
res: "Lorem ipsum dolor"
};
this.markMatches = this.markMatches.bind(this);
}
markMatches(ev) {
let res = "Lorem ipsum dolor";
const req = ev.target.value;
if (req) {
const normReq = req
.toLowerCase()
.replace(/\s+/g, " ")
.trim()
.split(" ")
.sort((a, b) => b.length - a.length);
res = res.replace(
new RegExp(`(${normReq.join("|")})`, "gi"),
match => "<mark>" + match + "</mark>"
);
}
this.setState({
res: res
});
}
render() {
return (
<div className="App">
<input type="text" onChange={this.markMatches} />
<br />
<p dangerouslySetInnerHTML={{ __html: this.state.res }} />
</div>
);
}
}
export default App;
@Henok T의 솔루션에 근거해, 이하가 있습니다. lodash
.
Typescript에 구현되어 Styled-components를 사용하지만, 유형을 삭제하고 스타일을 인라인으로 추가하는 것만으로 바닐라 JS에 쉽게 적응할 수 있습니다.
import React, { useMemo } from "react";
import styled from "styled-components";
const MarkedText = styled.mark`
background-color: #ffd580;
`;
interface IHighlighted {
text?: string;
search?: string;
}
export default function Highlighted({ text = "", search = "" }: IHighlighted): JSX.Element {
/**
* The brackets around the re variable keeps it in the array when splitting and does not affect testing
* @example 'react'.split(/(ac)/gi) => ['re', 'ac', 't']
*/
const re = useMemo(() => {
const SPECIAL_CHAR_RE = /([.?*+^$[\]\\(){}|-])/g;
const escapedSearch = search.replace(SPECIAL_CHAR_RE, "\\$1");
return new RegExp(`(${escapedSearch})`, "i");
}, [search]);
return (
<span>
{search === ""
? text
: text
.split(re)
.filter((part) => part !== "")
.map((part, i) => (re.test(part) ? <MarkedText key={part + i}>{part}</MarkedText> : part))}
</span>
);
}
const highlightMatchingText = (text, matchingText) => {
const matchRegex = RegExp(matchingText, 'ig');
// Matches array needed to maintain the correct letter casing
const matches = [...text.matchAll(matchRegex)];
return text
.split(matchRegex)
.map((nonBoldText, index, arr) => (
<React.Fragment key={index}>
{nonBoldText}
{index + 1 !== arr.length && <mark>{matches[index]}</mark>}
</React.Fragment>
));
};
사용방법:
<p>highlightMatchingText('text here', 'text')</p>
또는
<YourComponent text={highlightMatchingText('text here', 'text')}/>
이 조작은 유효합니다.
var Component = React.createClass({
_highlightQuery: function(name, query) {
var regex = new RegExp("(" + query + ")", "gi");
return "<span>"+name.replace(regex, "<strong>$1</strong>")+"</span>";
},
render: function() {
var name = "Javascript";
var query = "java"
return (
<div>
<input type="checkbox" />{JSXTransformer.exec(this._highlightQuery(name, query))}
</div>
);
}
});
하는 것입니다.if the, 진 the를 .<span>
를 달다render()
더 기능하다_highlightQuery()
하나, 하나, 하나, 하나, 둘, 셋.
다른 접근 방식을 사용할 것을 제안합니다.컴포넌트를 . 를 들어 1개의 컴포넌트를 만듭니다.<TextContainer />
이 들어있어요.<Text />
★★★★★★★★★★★★★★★★★★.
var React = require('react');
var Text = require('Text.jsx');
var TextContainer = React.createClass({
getInitialState: function() {
return {
query: ''
};
},
render: function() {
var names = this.props.names.map(function (name) {
return <Text name={name} query={this.state.query} />
});
return (
<div>
{names}
</div>
);
}
});
module.exports = TextContainer;
보시는 바와 같이 텍스트 컨테이너는 현재 쿼리를 상태로 유지합니다. 이제 ㅇㅇ, ㅇㅇ.<Text />
츠키다
var React = require('react');
var Text = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
query: React.PropTypes.string.isRequired
},
render: function() {
var query = this.props.query;
var regex = new RegExp("(" + query + ")", "gi");
var name = this.props.name;
var parts = name.split(regex);
var result = name;
if (parts) {
if (parts.length === 2) {
result =
<span>{parts[0]}<strong>{query}</strong>{parts[1]}</span>;
} else {
if (name.search(regex) === 0) {
result = <span><strong>{query}</strong>{parts[0]}</span>
} else {
result = <span>{query}<strong>{parts[0]}</strong></span>
}
}
}
return <span>{result}</span>;
}
});
module.exports = Text;
루트 컴포넌트에는 현재 쿼리의 상태가 있습니다.의 '어린애들', '어린애들', '어린애들', '어린애들', '어린애들', '어린애들', '어린애들'을합니다.render()
방법.각 아이는 새 쿼리를 새 소품으로 수신하고 쿼리와 일치하는 부분을 강조 표시하여 텍스트를 출력합니다.
HTML 태그를 포함한 코멘트를 검색해야 했습니다.
예: 제 코멘트 중 하나는 다음과 같습니다.
헬로 월드
<div>Hello<strong>World</strong></div>
그래서 저는 이런 댓글들을 검색해서 검색 결과를 부각시키고 싶었어요.
아시다시피 HTML 태그를 사용하여 텍스트를 강조 표시할 수 있습니다.<mark>
그래서 저는 도우미 기능을 하나 만들어서 추가 작업을 수행했습니다.<mark>
검색된 텍스트가 포함된 경우 텍스트에 태그를 지정합니다.
getHighlightedText = (text, highlight) => {
if (!highlight.trim()) {
return text;
}
const regex = new RegExp(`(${highlight})`, "gi");
const parts = text.split(regex);
const updatedParts = parts
.filter((part) => part)
.map((part, i) =>
regex.test(part) ? <mark key={i}>{part}</mark> : part
);
let newText = "";
[...updatedParts].map(
(parts) =>
(newText =
newText +
(typeof parts === "object"
? `<${parts["type"]}>${highlight}</${parts["type"]}>`
: parts))
);
return newText;
};
그래서 함수 안에서 텍스트와 검색 텍스트를 인수로 전달해야 합니다.
입력
getHighlightedText("<div>Hello<strong>World</strong></div>", "hello")
산출량
<div><mark>Hello</mark><strong>World</strong></div>
솔루션에 대해 더 많은 도움이 필요하면 알려주세요.
공백으로 분할된 여러 텍스트 부분을 강조 표시할 수 있도록 위에서 @Henok T 버전을 확장했지만 따옴표 또는 큰따옴표로 묶은 문자열은 함께 보관합니다.
예를 들어 하이라이트text "some text" 'some other text' text2
다음 텍스트를 강조 표시합니다.
text
some text
some other text
text2
를 참조해 주세요.
const Highlighted = ({text = '', highlight = ''}: { text: string; highlight: string; }) => {
if (!highlight.trim()) {
return <span>{text}</span>
}
var highlightRegex = /'([^']*)'|"([^"]*)"|(\S+)/gi; // search for all strings but keep strings with "" or '' together
var highlightArray = (highlight.match(highlightRegex) || []).map(m => m.replace(highlightRegex, '$1$2$3'));
// join the escaped parts with | to a string
const regexpPart= highlightArray.map((a) => `${_.escapeRegExp(a)}`).join('|');
// add the regular expression
const regex = new RegExp(`(${regexpPart})`, 'gi')
const parts = text.split(regex)
return (
<span>
{parts.filter(part => part).map((part, i) => (
regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>
))}
</span>
)
}
언급URL : https://stackoverflow.com/questions/29652862/highlight-text-using-reactjs
'programing' 카테고리의 다른 글
nginx - 404 permalinks 페이지를 찾을 수 없습니다. (0) | 2023.04.05 |
---|---|
ApplicationContext를 시작하는 동안 오류가 발생했습니다.자동 구성 보고서를 표시하려면 '디버깅'을 활성화하여 응용 프로그램을 다시 실행하십시오. (0) | 2023.03.31 |
속성 파일에서 값을 읽는 방법 (0) | 2023.03.31 |
기존의 모든 필드를 포함시키고 문서에 새 필드 추가 (0) | 2023.03.31 |
archive-product.php의 변경이 기능하지 않는다. (0) | 2023.03.31 |