Glossar mit JS / RegExp / Problem mit Wortgrenze implementieren
Leila
- javascript
Hallo liebes Forum,
Ich brauche ein bisschen Hilfe. Muss dazu sagen dass ich in Javascript leider noch Anfänger bin, mir vieles erst aneignen muss.
Es geht darum ein Glossar zu einem Produkttext in einem Onlineshop zu erstellen. DAs ganze wurde auch schon vorbereitet. Über eine Javascriptfunktion werden bestimmte Zeichenketten in dem Text gesucht und mit den ID's von Div-Containern gematcht. Das entsprechende Wort wird unterstrichen ausgegeben und erhält einen Tooltip, welches die Bedeutung erklärt. An sich eine simple Geschichte (schön gelöst ist die andere Frage...). Nun ist es aber so dass auch Wörter wie AUS in HAUS (zb.) gefunden werden, was natürlich keinen Sinn macht...
Ich habe mir jetzt ein bisschen gefährliches Halbwissen über Wortgrenzen mit RegExp angelesen und herumprobiert. ERfolglos. Ich brauche euch, um mir auf die Sprünge zu helfen.
Nachfolgend der Code-schnipsel (exemplarisch!)
<div id="toolTip" style="display:none;">
</div>
<div class="produkttext">
Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus.
</div>
<div id="glossar" style="display: none;">
<div id="aus">
bla bla bla
</div>
</div>
<script type="text/javascript">
function hideLexInfo() {
var info_layer = document.getElementById("toolTip");
toolTip.style.display = 'none';
}
function showLexInfo(entry, acelement) {
var doc = document;
var info = doc.getElementById(entry).innerHTML;
var toolTip = doc.getElementById("toolTip");
toolTip.innerHTML = '<b>'+entry+'</b><br /><br />'+info;
toolTip.style.zIndex = 9000;
toolTip.style.display = 'block';
$(acelement).mousemove(function(e){
var x = acelement.offsetLeft-280;
var y =acelement.offsetTop-380;
toolTip.style.marginTop = y+'px';
toolTip.style.marginLeft = x+'px';
});
}
function getLexInfo() {
var doc = document;
var infolayer = $('#glossar').children();
var descs = $('.produkttext');
for (var j=0; j<descs.length; j++) {
for (var i=0;i<infolayer.length; i++) {
var exp = new RegExp(infolayer[i].id, "g");
descs[j].innerHTML = descs[j].innerHTML.replace(exp, '<span class="cue" onMouseOver="javascript:showLexInfo(this.innerHTML, this)" onMouseOut="javascript:hideLexInfo()">'+infolayer[i].id+'</span>');
}
}
}
getLexInfo();
</script>
Tja das Problem ist, dass nun in der Ausgabe nat. auch im Wort HAUS und HINAUS der Teil AUS erkannt und entsprechend verarbeitet wird.
Nur was genau muss ich tun, damit er im Produkttext eben nicht innerhalb von Worten die Zeichenkette sucht sondern nur in ganzen Wörtern also immer nur das Wort AUS? Und HAUS und HINAUS in Ruhe lässt? ;)
Ja ich weiss, es gibt hier (http://de.selfhtml.org/javascript/objekte/regexp.htm) eig. die Lösung, aber ich schaffe es nicht das auf meine Funktion zu übertragen.
Ich habe das hier probiert:
var exp = new RegExp(/\binfolayer[i].id\b/, "g");
Aber da spuckt mir die FF-Fehlerkonsole nur einen "Illegal Charakter"-Fehler aus...
Es wäre so toll wenn Ihr mir auf die Sprünge helft. DANKE!
Hallo Leila,
var exp = new RegExp(/\binfolayer[i].id\b/, "g");
ich bin kein regExp-Experte, aber versuch doch mal
var sexp = "\\b" + infolayer[i].id + "\\b";
var exp = new RegExp(sexp,"g");
Gruß, Jürgen
Hallo Jürgen,
vielen Dank schonmal. Sieht zwar vielversprechend aus, half aber nichts ;(
Es passiert exakt nichts, auch keine Fehler in der Konsole...
Ich bin irgendwie am Ende meiner Weisheit.
Es erscheint doch irgendwie so logisch:
descs[j].innerHTML = descs[j].innerHTML.replace(exp, '<span class="cue" onMouseOver="javascript:showLexInfo(this.innerHTML, this)" onMouseOut="javascript:hideLexInfo()">'+infolayer[i].id+'</span>');
}
übersetzt: Ersetze innerhalb des Produkttextes alle Wörter mit der ID des Glossars (und packe es in das span, welches auch den tooltip generiert).. und die neue Variable sexp sollte doch angeben dass er exakt dieses Wort sucht und nicht innerhalb von Ganzen Wörtern.. ich versteh es einfach nicht...
Grüße, Leila
Hallo Leila,
so weit ich weiß werden Eventhandler, die per innerHTML gesetzt werden, nicht registriert. Teste erst mal das Ersetzen, z.B. indem du durch was Anderes ersetzt oder das Wort Fett darstellst. Wenn das geht, kannst du den Eventhandler mit DOM-Methoden einbauen.
Gruß, Jürgen
PS javascript: hat in Eventhandlern nichts zu suchen.
Hallo Jürgen,
das habe ich aber schon getestet.. es bleibt weiterhin so dass im Text
alle Wörter so ausgezeichnet werden...
H<strong>aus<strong> und hin<strong>aus</strong> <strong>aus</strong>
Also irgendwie funktioniert das nicht. Nur warum? Ist da noch ein Logigfehler in der Konstruktion?
Ich seh den Wald vor lauter Bäumen nicht mehr..
Grüße, Leila
Hallo Leila,
Ich seh den Wald vor lauter Bäumen nicht mehr..
ich sehe noch nicht mal die Bäume :). Hast du mal einen Link auf deine Testseite?
Gruß, Jürgen
Hi Jürgen,
erstmal schonmal 1000 DANK dass du mir so treu hilfst ;) Ich bastle die testseite heute abend (muss sie aus dem grossem Projekt hier erst extrahieren) .. bitte vergiss mich nicht ;)
Danke und Grüße, Leila
Ich kann sie leider nicht hochladen... aber hier copy paste der Quelltext meiner kleinen Testseite:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Glossar Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
</head>
<body>
<div id="toolTip" style="display:none; background-color:#ffffff;padding:15px;width:300px;color:#666666;font-size:12px;position:absolute;box-shadow: 0 0 5px rgba(0, 0, 0.4, 0.4) inset;">
</div>
<div class="produkttext">
Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus.
</div>
<div id="glossar" style="display: none;">
<div id="aus">
bla bla bla
</div>
</div>
<script type="text/javascript">
function hideLexInfo() {
var info_layer = document.getElementById("toolTip");
toolTip.style.display = 'none';
}
function showLexInfo(entry, acelement) {
var doc = document;
var info = doc.getElementById(entry).innerHTML;
var toolTip = doc.getElementById("toolTip");
toolTip.innerHTML = '<b>'+entry+'</b><br /><br />'+info;
toolTip.style.zIndex = 9000;
toolTip.style.display = 'block';
$(acelement).mousemove(function(e){
var x = acelement.offsetLeft-280;
var y =acelement.offsetTop-380;
toolTip.style.marginTop = y+'px';
toolTip.style.marginLeft = x+'px';
});
}
function getLexInfo() {
var doc = document;
var infolayer = $('#glossar').children();
var descs = $('.produkttext');
for (var j=0; j<descs.length; j++) {
for (var i=0;i<infolayer.length; i++) {
var exp = new RegExp(infolayer[i].id, "g");
descs[j].innerHTML = descs[j].innerHTML.replace(exp, '<strong class="cue" onMouseOver="javascript:showLexInfo(this.innerHTML, this)" onMouseOut="javascript:hideLexInfo()">'+infolayer[i].id+'</strong>');
}
}
}
getLexInfo();
</script>
</body>
</html>
Grüße, Leila
Hallo Leila,
var exp = new RegExp(infolayer[i].id, "g");
warum hast du denn meinen Vorschlag nicht verwendet? Hier fehlen die Worttrenner.
Gruß, Jürgen
Hallo Jürgen,
richtig, entschuldige bitte. Nur passiert nach Einfügen der neuen Variable rein gar nichts mehr...die Fehlerkonsole spuckt auch nichts aus..
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Glossar Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
</head>
<body>
<div id="toolTip" style="display:none; background-color:#ffffff;padding:15px;width:300px;color:#666666;font-size:12px;position:absolute;box-shadow: 0 0 5px rgba(0, 0, 0.4, 0.4) inset;">
</div>
<div class="produkttext">
Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus. Ein Haus ist ein Gebäude. Aus diesem gehen Menschen hinaus.
</div>
<div id="glossar" style="display: none;">
<div id="aus">
bla bla bla
</div>
</div>
<script type="text/javascript">
function hideLexInfo() {
var info_layer = document.getElementById("toolTip");
toolTip.style.display = 'none';
}
function showLexInfo(entry, acelement) {
var doc = document;
var info = doc.getElementById(entry).innerHTML;
var toolTip = doc.getElementById("toolTip");
toolTip.innerHTML = '<b>'+entry+'</b><br /><br />'+info;
toolTip.style.zIndex = 9000;
toolTip.style.display = 'block';
$(acelement).mousemove(function(e){
var x = acelement.offsetLeft-280;
var y =acelement.offsetTop-380;
toolTip.style.marginTop = y+'px';
toolTip.style.marginLeft = x+'px';
});
}
function getLexInfo() {
var doc = document;
var infolayer = $('#glossar').children();
var descs = $('.produkttext');
for (var j=0; j<descs.length; j++) {
for (var i=0;i<infolayer.length; i++) {
var sexp = "\b" + infolayer[i].id + "\b";
var exp = new RegExp(sexp,"g");
descs[j].innerHTML = descs[j].innerHTML.replace(exp, '<strong class="cue" onMouseOver="javascript:showLexInfo(this.innerHTML, this)" onMouseOut="javascript:hideLexInfo()">'+infolayer[i].id+'</strong>');
}
}
}
getLexInfo();
</script>
</body>
</html>
Hallo Leila,
... Nur passiert nach Einfügen der neuen Variable rein gar nichts mehr...die Fehlerkonsole spuckt auch nichts aus..
kein onmouseover oder auch kein "fettmachen"?
Gruß, Jürgen
Hallo Jürgen,
Kommando zurück!
Es klappt! Ich habe das Glossar um ein paar Einträge erweitert.. alles perfekt! Es ist genauso wie es sein sollte. Wahnsinn. Ich würde nur gerne verstehen warum es nur bei einem Eintrag nicht klappt... falls Du das zufällig sofort siehst wäre ich dankbar um Aufklärung.. aber so: TOP!!!!
Ich DANKE Dir! Wirklich toll!
So und nun gibt es aber NOCH ein Problem welches der Grund war, dass ich bei dem "richtigen" Projekt nicht so recht weitergekommen bin. Die Wortgrenze funktioniert zwar, aber in dem Glossar werden Wörte verwendet mit Bindestrich. Also sowas: Haus-Maus. Das erkennt er nicht als ganzes Wort.. gibt es eine Möglichkeit dem Code beizubringen dass er Wörter mit Bindestrich als ganzen String erkennen soll?
Grüße, Leila
Hallo Leila,
dann schmeiß aber noch die "javascript:" raus, und entscheide dich, ob du jquery ($(...) benutzen willst, oder die Dom-Methoden (document.getElement)...
Gruß, Jürgen
Hallo Jürgen,
ja das mach ich, keine Sorge!
Aber hast Du noch eine Idee zu den Bindestrichen?
Grüße, Leila
Hallo Leila,
meine RegExp-Kenntnisse sind nur grundlegend; ich habe keine Idee, wie man das "-" nicht als Worttrenner behandelt.
Wenn hier sonst keiner eine Idee hat, könntest du das "-" durch ein anderes Zeichen ersetzen, das sonst nie im Text vorkommt, und nach dem "fettmachen" wieder zurück tauschen.
Gruß, Jürgen
Hallo liebes Forum,
bevor der Thread verschwindet hier nochmal die grosse Bitte ob vielleicht noch jemand eine Idee / einen Tipp hat: Wie schon beschrieben habe ich das Problem, dass ich einfach nicht weiterkomme mit den Wörter im Glossar welche einen Bindestrich enthalten. Wie kann ich meiner Funktion beibeibringen ein Wort wie HAUS-MAUS als ganzes zu sehen?
Vielen lieben Dank, Leila
Hallo Leila,
bevor der Thread verschwindet
das dauert über zwei Wochen nach dem letzten Beitrag.
zu deinem Problem:
ich würde die Bindestriche durch eine Zeichenfolge ersetzen, die wirklich nie im Text vorkommt und auch nicht als Wortgrenze erkannt wird, die Worte hervorheben und dann die Ersetzung wieder rückgängig machen.
Aber vielleicht kommt ja noch ein RegExp-Experte vorbei.
Gruß, Jürgen