Hi,
vielen Dank für deine tolle Bemühungen. Da ich leider noch nicht ganz damit zurecht kam habe folgenden Code gefunden,
der für mich funktioniert.
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Fenstertitel</title>
<style type="text/css">
#toSearch {
position: relative;
}
.marker {
position: absolute;
background-color: red;
display: inline-block;
z-index: -1;
}
.marker.marked {
background-color: lightblue;
}
</style>
</head>
<body>
<input id="search"><button id="next">next</button>
<div id="toSearch">Lorem ipsum dol<span>or sit amet<b> (in span)</b>, conset</span>etur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>
<script type="text/javascript">
function getSearchRanges(node, search){
var ranges = [];
var offsets = [];
var pos = -1 * search.length;
var value = node.textContent.toLowerCase();
search = search.toLowerCase();
while ((pos = value.indexOf(search, pos + search.length)) > -1){
offsets.push(pos);
}
var textNodes = [];
var lastOffset = 0;
function traverse(node){
if (node.nodeType === 3){
textNodes.push({
node: node,
start: lastOffset,
end: lastOffset + node.nodeValue.length
});
lastOffset += node.nodeValue.length;
}
else {
for (var i = 0; i < node.childNodes.length; i += 1){
traverse(node.childNodes[i]);
}
}
}
traverse(node);
function getTextNodeByOffset(offset){
for (var i = 0; i < textNodes.length; i += 1){
if (textNodes[i].start <= offset && textNodes[i].end >= offset){
return {
node: textNodes[i].node,
offset: offset - textNodes[i].start
};
}
}
console.error("offset not found:", offset);
}
return offsets.map(function(offset){
var range = document.createRange();
var start = getTextNodeByOffset(offset);console.log(start);
range.setStart(start.node, start.offset);
var end = getTextNodeByOffset(offset + search.length);
range.setEnd(end.node, end.offset);
return range;
});
}
function createMarkerFromRect(rect, referenceRect){
var marker = document.createElement("span");
marker.className = "marker";
marker.style.height = rect.height + "px";
marker.style.width = rect.width + "px";
marker.style.top = (rect.top - referenceRect.top) + "px";
marker.style.left = (rect.left - referenceRect.left) + "px";
return marker;
}
function createMarkersFromRange(range, referenceRect){
return Array.from(range.getClientRects()).map(function(rect){
return createMarkerFromRect(rect, referenceRect);
});
}
function search(search){
Array.from(document.querySelectorAll(".marker")).forEach(function(marker){
marker.parentNode.removeChild(marker);
});
if (search){
var toSearch = document.getElementById("toSearch");
var referenceRect = toSearch.getBoundingClientRect();
var firstMarker = true;
getSearchRanges(toSearch, search).forEach(function(range){
createMarkersFromRange(range, referenceRect).forEach(function(marker){
marker.range = range;
if (firstMarker){
marker.classList.add("marked");
}
toSearch.appendChild(marker);
});
firstMarker = false;
});
}
}
document.getElementById("search").addEventListener("input", function(){
search(this.value);
})
window.addEventListener("resize", function(){
search(document.getElementById("search").value);
});
document.getElementById("next").addEventListener("click", function(){
var markers = Array.from(document.getElementById("toSearch").querySelectorAll(".marker"));
function unmark(range){
markers
.filter(function(marker){
return marker.range === range;
})
.forEach(function(marker){
marker.classList.remove("marked");
});
}
function mark(range){
markers
.filter(function(marker){
return marker.range === range;
})
.forEach(function(marker){
marker.classList.add("marked");
});
}
var foundRange = false;
markers.forEach(function(marker, i){
if (foundRange === false){
if (marker.classList.contains("marked")){
foundRange = marker.range;
unmark(foundRange);
}
}
else {
if (foundRange !== true && foundRange !== marker.range){
mark(marker.range);
foundRange = true;
}
}
});
if (foundRange !== true){
mark(markers[0].range);
}
});
</script>
</body>
</html>
Alles anzeigen