假设我有以下标记:
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>Some title</h1>
<p>First paragraph</p>
<p>Second paragraph</p>
</body>
<html>
我需要标记文本的某些部分,即“第一段secon” 它看起来像这样:
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>Some title</h1>
<p>F
<mark>
irst paragraph</p><p>Secon
</mark>
d paragraph</p>
</body>
<html>
但问题是html标记会被破坏。标记越复杂,这种方法就会遇到越多的问题。
问题:
寻找关于如何获取第一个HTML示例并应用函数来返回html结构的想法,其中“irst paragraph second”以某种方式被特别标记。
我目前拥有的是:
答案 0 :(得分:4)
如果您想突出显示文档中的文字,那么此插件对您有所帮助。
https://github.com/julmot/jquery.mark
示例小提琴:https://jsfiddle.net/julmot/vpav6tL1/
用法很简单:
$(".context").mark("keyword");
答案 1 :(得分:0)
原则上你必须:
在单词级别进行更改将阻止您破坏标记。 我在下面添加了一个工作示例。但是我不确定它是否适用于所有浏览器。
示例中没有使用mergeWords
等一些函数,但我将它们包括在内,因为它们可以证明是有用的。
var splittedToWords = false;
function ignore(el) {
return (el.nodeType == 8) ||
(el.tagName == "BLOCKQUOTE") ||
(el.tagName == "SCRIPT") ||
(el.tagName == "DIV") ||
(!el.hasChildNodes() && el.textContent.match(/\S+/) == null);
}
function splitToWords(el) {
if (el.hasChildNodes()){
var count = el.childNodes.length;
for (var i = count - 1; i >= 0; i--) {
var node = el.childNodes[i];
if (!ignore(node))
splitToWords(node);
}
}
else { //text node
var words = el.textContent.match(/(\S+\s*)/g) || [];
var count = words.length;
var parentNode = el.parentNode;
for (var i = 0; i < count; i++) {
var wordNode = document.createElement("span");
wordNode.className = "word";
wordNode.innerText = words[i];
wordNode.setAttribute["word-index"] = i;
parentNode.insertBefore(wordNode, el);
}
parentNode.removeChild(el);
}
splittedToWords = true;
}
function unwrap(element) {
var next = element.nextSibling;
var parent = element.parentNode;
parent.removeChild(element);
var current;
var frag = document.createDocumentFragment();
do {
current = element.nextSibling;
frag.insertBefore(element, null);
} while ((element = current));
parent.insertBefore(frag, next);
}
function mergeWords(el) {
var words = document.getElementsByClassName("word");
count = words.length;
if (count > 0)
for (var i = 0; i < count; i++)
uwrap(words[i]);
}
function markWord(el, pos, len) {
var text = el.innerText;
var pre = text.substr(0, pos);
var mark = '<mark>' + text.substr(pos, len) + '</mark>';
var post = text.substring(pos + len, text.length);
el.innerHTML = pre + mark + post;
}
function mark(element, offset, text) {
if (!splittedToWords) {
var body = document.body;
splitToWords(body);
}
var words = document.getElementsByClassName("word");
var wordsCount = words.length;
var first = null;
for (var i = 0; i < wordsCount; i++ ) {
if (words[i].parentElement == element) {
first = i;
break;
}
}
done = false;
var i = first;
var pos = 0;
do {
var word = words[i];
var wordLength = word.innerText.length;
if (offset > pos + wordLength) {
i++;
pos += wordLength;
continue;
}
else {
done = true;
}
} while (!done);
var tWords = text.match(/(\S+\s*)/g) || [];
var tWordsCount = tWords.length;
if (tWordsCount == 0)
return;
for (var ti = 0; ti < tWordsCount; ti++) {
var wordEl = words[i++];
var word = wordEl.innerText;
var tWord = tWords[ti].trim();
var pos = word.indexOf(tWord);
if (pos == -1)
continue; //or maybe return.
markWord(wordEl, pos, tWord.length);
}
}
var e = document.getElementById("e");
//do the magic
mark(e, 1, 'irst paragraph Second');
<h1>Some title</h1>
<p id="e">First paragraph</p>
<p>Second paragraph</p>