와 텍스트 노드에 좀 텍스트 노드있어 :삽입 HTML 자바 스크립트
var node
을 그리고 난 "LOL"의 모든 발생 주위에 범위를 포장합니다. 내가 스팬 요소로 "lol"
할 때
node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>")
그것은 그것 "<span>lol<span>"
출력합니다.
와 텍스트 노드에 좀 텍스트 노드있어 :삽입 HTML 자바 스크립트
var node
을 그리고 난 "LOL"의 모든 발생 주위에 범위를 포장합니다. 내가 스팬 요소로 "lol"
할 때
node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>")
그것은 그것 "<span>lol<span>"
출력합니다.
당신은 부모 노드로 node
을해야 할 수도 있습니다, 당신은 단지 innerHTML을 사용할 수 있습니다 그 방법 : 여기 node.childNodes[0]
node.innerHTML=node.childNodes[0].nodeValue.replace(/lol/, "<span>lol</span>");
실제 텍스트 노드를 참조하고 node
는 포함하는 요소입니다.
다음 문서를 HTML 요소와 텍스트를 대체 할 수있는 코드를 제공합니다 : 문서에서
http://blog.alexanderdickson.com/javascript-replacing-text
:
var matchText = function(node, regex, callback, excludeElements) {
excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
var child = node.firstChild;
do {
switch (child.nodeType) {
case 1:
if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) {
continue;
}
matchText(child, regex, callback, excludeElements);
break;
case 3:
child.data.replace(regex, function(all) {
var args = [].slice.call(arguments),
offset = args[args.length - 2],
newTextNode = child.splitText(offset);
newTextNode.data = newTextNode.data.substr(all.length);
callback.apply(window, [child].concat(args));
child = newTextNode;
});
break;
}
} while (child = child.nextSibling);
return node;
}
사용법 :
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) {
var span = document.createElement("span");
span.className = "search-term";
span.textContent = match;
node.parentNode.insertBefore(span, node.nextSibling);
});
그리고 설명을 :
,는 기본적으로 그것을 할 올바른 방법은
- 으로 반복 모든 텍스트 노드를 통해 ...입니다.
- 텍스트 노드에서 하위 문자열을 찾습니다.
- 오프셋으로 분할합니다.
- 스플릿 사이에 스팬 요소를 삽입하십시오.
Andreas Josas가 제시 한 대답은 상당히 좋습니다. 그러나 동일한 텍스트 노드에서 검색어가 여러 번 나타난 경우 코드에 몇 가지 버그가있었습니다. 여기에 버그가 수정 된 솔루션이 있으며 추가로 삽입물을 matchText로 분해하여보다 쉽게 사용하고 이해할 수 있습니다. 이제 새로운 태그 만 콜백에 생성되고 return에 의해 matchText에 전달됩니다.
버그 수정업데이트 matchText 기능 :
var matchText = function(node, regex, callback, excludeElements) {
excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
var child = node.firstChild;
while (child) {
switch (child.nodeType) {
case 1:
if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
break;
matchText(child, regex, callback, excludeElements);
break;
case 3:
var bk = 0;
child.data.replace(regex, function(all) {
var args = [].slice.call(arguments),
offset = args[args.length - 2],
newTextNode = child.splitText(offset+bk), tag;
bk -= child.data.length + all.length;
newTextNode.data = newTextNode.data.substr(all.length);
tag = callback.apply(window, [child].concat(args));
child.parentNode.insertBefore(tag, newTextNode);
child = newTextNode;
});
regex.lastIndex = 0;
break;
}
child = child.nextSibling;
}
return node;
};
사용법 :
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) {
var span = document.createElement("span");
span.className = "search-term";
span.textContent = match;
return span;
});
당신이 앵커 (링크)를 삽입하고자하는 경우 스팬 태그 대신 태그는 될 요소를 작성, 변경의 " "대신"span "을 추가하고 태그에 href 속성을 추가하는 행을 추가하고 excludeElements 목록에 'a'를 추가하여 링크가 링크 내부에서 작성되지 않도록하십시오.
재사용 할 때 regex를 재설정하기 위해'regex.lastIndex = 0' 수정을 추가했습니다. http://stackoverflow.com/questions/1520800/why-regexp-with-global-flag-in-javascript-give-wrong-results – Jeff
더 나은 대답은 아니지만, 내가 완성을 위해 한 일을 게시하고 있습니다. 필자의 경우 #text 노드에서 강조해야하는 텍스트의 오프셋을 이미 찾거나 결정했습니다. 이것은 또한 단계를 명확히합니다.
//node is a #text node, startIndex is the beginning location of the text to highlight, and endIndex is the index of the character just after the text to highlight
var parentNode = node.parentNode;
// break the node text into 3 parts: part1 - before the selected text, part2- the text to highlight, and part3 - the text after the highlight
var s = node.nodeValue;
// get the text before the highlight
var part1 = s.substring(0, startIndex);
// get the text that will be highlighted
var part2 = s.substring(startIndex, endIndex);
// get the part after the highlight
var part3 = s.substring(endIndex);
// replace the text node with the new nodes
var textNode = document.createTextNode(part1);
parentNode.replaceChild(textNode, node);
// create a span node and add it to the parent immediately after the first text node
var spanNode = document.createElement("span");
spanNode.className = "HighlightedText";
parentNode.insertBefore(spanNode, textNode.nextSibling);
// create a text node for the highlighted text and add it to the span node
textNode = document.createTextNode(part2);
spanNode.appendChild(textNode);
// create a text node for the text after the highlight and add it after the span node
textNode = document.createTextNode(part3);
parentNode.insertBefore(textNode, spanNode.nextSibling);
감사합니다. 저에게 가장 좋은 답변이었습니다. – romuleald
이 경우 텍스트 노드를 html 콘텐츠로 다시 채워야합니다. –
@ArunPJohny 어떻게해야합니까? – alt
@ JacksonGariety - 텍스트 노드를 새 DOM span 요소 및 텍스트 노드로 바꾸거나 부모의 innerHTML 속성을 수정해야합니다. 가자. 시도해라. – RobG