• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[JQUERY] Suchfunktion erweitern

bosko

Member
Guten Morgen,

ich habe diesen Code im Netz gefunden, für eine Suchfunktion eines Textes in einer DIV auf der HP,
gefällt mir ganz gut aber möchte diesen erweitern:
HTML:
jQuery.fn.highlight = function(pat) {
 function innerHighlight(node, pat) {
  var skip = 0;
  if (node.nodeType == 3) {
   var pos = node.data.toUpperCase().indexOf(pat);
   if (pos >= 0) {
    var spannode = document.createElement('span');
    spannode.className = 'highlight';
    var middlebit = node.splitText(pos);
    var endbit = middlebit.splitText(pat.length);
    var middleclone = middlebit.cloneNode(true);
    spannode.appendChild(middleclone);
    middlebit.parentNode.replaceChild(spannode, middlebit);
    skip = 1;
   }
  }
  else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
   for (var i = 0; i < node.childNodes.length; ++i) {
    i += innerHighlight(node.childNodes[i], pat);
   }
  }
  return skip;
 }
 return this.each(function() {
  innerHighlight(this, pat.toUpperCase());
 });
};

jQuery.fn.removeHighlight = function() {
 function newNormalize(node) {
    for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) {
        var child = children[i];
        if (child.nodeType == 1) {
            newNormalize(child);
            continue;
        }
        if (child.nodeType != 3) { continue; }
        var next = child.nextSibling;
        if (next == null || next.nodeType != 3) { continue; }
        var combined_text = child.nodeValue + next.nodeValue;
        new_node = node.ownerDocument.createTextNode(combined_text);
        node.insertBefore(new_node, child);
        node.removeChild(child);
        node.removeChild(next);
        i--;
        nodeCount--;
    }
 }

 return this.find("span.highlight").each(function() {
    var thisParent = this.parentNode;
    thisParent.replaceChild(this.firstChild, this);
    newNormalize(thisParent);
 }).end();
};

HTML:
$(function() {
    $('#code-search').bind('keyup change', function(ev) {
        var searchTerm = $(this).val();
        $('#code').removeHighlight();
        if(searchTerm) {
            $('#code').highlight( searchTerm );
        }
    });
});

Würder gern das einfügen das er mir ausgibt, wie oft ein Wort gefunden wurde und wenn es möglich ist,
eine Art Pfeilsystem das man zum gesuchten Wort Springen kann und weiter Springen und ....


Gruß
 
Guten Morgen,

ich habe den Code von ober erstmal verworfen und dies nun so umgesetzt:
HTML:
function f_mark(p_value)
{
// Alten Inhalt auslesen
var v_content = document.getElementById('content');
var v_number = document.getElementById('num');
var v_old = v_content.innerHTML;
var number = 0;

var v_pattern = new RegExp('<span class="highlight" id="([^<]*)">([^<]*)</span>', 'gi');
var v_new = v_old.replace(v_pattern, '$2');

if (p_value != '' && p_value.length > 1) {
    v_pattern = new RegExp('(' + p_value + ')', 'gi');
    v_new.replace(v_pattern, function() {
    number++;
    });    
v_new = v_new.replace(v_pattern, '<span class="highlight" id="ju_'+number+'">$1</span>');
    
} else {
    number = "Bitte geben Sie min 2 Zeichen ein.";
}

v_content.innerHTML = v_new;
v_number.innerHTML = number;
}

Soweit alles schick und schön, gesuchter Begriff wird nun im Text Markiert ;) und auch ausgegeben wo oft der
gesuchte Begriff auftaucht...
Nun will ich das ein Botton gibt, wo ich zu jedem Markierten Begriff Springen kann, vorgestellt habe ich es mir so:
HTML:
$(".weiter").click(function() {
      var previous;
      previous = $(this).parent().prev().find(".highlight");
       $('html,body').animate({ scrollTop: previous.offset().top
            }, 1000);
});

Leider passiert hier nix...

- - - Aktualisiert - - -

Was ich noch hinzufügen muss ist das ich beim RegExp ein Fehler drin habe,
RegExp soll alle Worte und Zeichen ausschliessen die zwischen < und > stehen
also html tag's, wie ist das der Code?
 
Ist das was du bauen willst das selbe wie bei der Browsersuche?
STRG + F - Suchbegriff eingeben - Fundstellen werden gelb - mit F3 zum nächsten springen.
 
Guten morgen,
Jap aber mobile Geräte habe leider keine suche..
Bei meiner Seite soll es auch nur ein bestimmten DIV durchsucht werden aber der enthält wieder rum auch HTML Tag die nicjt durchsucht werden soll
 
Würde ich mir auf jeden Fall etwas Fertiges suchen. Denn Quellcode nach Quellcode abzusuchen kann eigentlich nur schief gehen ;)

Und prinzipiell könnte man vielleicht mit einer Schleife zeichenweise durch das div laufen und immer bei Beginn von HTML Quellcode ein Flag "nichts gelb machen" setzen und bei Quellcodeende wieder löschen. Und wenn das Flag nicht gesetzt ist wendest du deinen Gelb-mach-Code an.
 
Code:
<!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 (in span), 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>
 
Zurück
Oben