Position des Cursors im Textarea (IE) auslesen
Thomas Michel
- javascript
Hallo zusammen
Ich habe kein problem den markierten text auszulesen, diese infos habe ich im archiv gefunden. Nun möchte ich jedoch mein menu so erweiter das auch ein bild eingefügt werden kann. Diese funktion ist schon komplett vorhanden. der bilddtag wird jedoch immer am ende des textes eingefügt. ich möchte nun das dies beim bilnkenden cursor geschieht. Wo kriege ich diese infos vom cursor?
mfG
Thomas
Hallo Thomas,
Wo kriege ich diese infos vom cursor?
der "Cursor" oder "Indentation Marker" oder "Caret" ist nicht direkt abfragbar
(jedenfalls nicht auf einem WindowsSystem mit dem IE). Es geht aber trotzdem.
Nicht erschrecken! Erst mal ein bisschen Infos.
Hier die Erklärung von MS zum Caret, die erklärt, weshalb immer wieder gesagt wird, es geht nicht:
"Unlike other UI elements, the caret object does not have an associated window handle. To obtain access to the caret object, clients must set a WinEventProc callback function and wait for the caret object to generate events.
The caret object in the rich edit control provided by Riched20.dll (which is used in text editors such as WordPad in Windows 98) does not send any WinEvents when its position is changed during text selection. When users press SHIFT and arrow keys to select text, the caret object does not trigger the EVENT_OBJECT_LOCATIONCHANGE WinEvent. Similarly, when the selection is set programmatically through rich edit messages, the caret object does not send any events to indicate its new position.
All applications that use Riched20.dll exhibit this problem. Applications using earlier versions of the rich edit control correctly send events based on the selection."
zu finden unter: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaapndx_9jqs.asp
Wie findest Du nun die Position?
Dein Freund ist selection.createRange() (für andere Browser schau mal auf = getSelection/setSelection).
Die Technik ist weiter unten beschrieben.
Nachdem Du mit dieser Technik ein _selection-objekt_ erzeugt hast, schreibst Du in den angeklickten Text der textarea mittels
_selection-objekt_.text = 'Die Info hätte ich auch im SELFHTML-Archiv gefunden';
Über die indexOf()-Funktion holst Du Dir dann die Position dieses Strings innerhalb des Textes der Textarea und weist,
an welche Stelle hat die Benutzerin geklickt. Ein paar weitere String-Operationen und alles ist so wie du es haben willst.
Es geht aber auch einfacher.
Du brauchst die direkte Textposition nicht zu wissen!
Über _selection-objekt_.text = '<img src=.....>'; landet dein gewünschter String dort wo er hin soll (wenn dahin geklickt wurde, wo dieser Tag hinsoll...)
Hier nun die Technik: (Grundidee = Ein Tip von Antje Hoffmann im Archiv)
Es ist ganz simpel, wenn man mit dem selection-Objekt und createRange() arbeitet.
Zunächst ein paar Variable definieren:
<!-- optional !--> var oMover = '#FF0000';// Farbe für den onMouseover-Effekt
<!-- optional !--> var oMout = '#0000FF';// Farbe für den onMouseout-Effekt
<!-- zwingend !--> var FEsel = ''; // Zwischenspeicher für selektierte Werte
Ein Button, der ein bequemes Bedienen ermöglicht, irgendwo auf der Seite.
<button name="selEintrag"
type="button"
id="selEintrag"
onMouseup="javascript:selEintrag()"
title="\n Einfügen von HTML-Tags in einen Text \n\n Klicken Sie in ein Textfeld oder. \n\n markieren Sie einen Text um die Aktion zu starten.\n\n Klicken Sie dann auf diesen Button. \n"
onMouseover="this.style.color=oMover;"
onMouseout="this.style.color=oMout;">
<a>Einfügen</a>
</button>
Eine beliebige Anzahl von <textarea>-Elementen, bei denen nur wichtig ist, das irgendein Ereignis eine
Wertzuweisung zu der Variablen FEsel macht. Hierin ist nachher der markierte Text (=generated-Status des
selection-Objekts) oder kein markierter Text, aber eine Klickposition (=degenerated-Status des selection-Objekts)
<textarea id="FE1"
name="FE1"
wrap="virtual"
cols="80"
rows="8"
onClick="FEsel=selection.createRange()">
" userText "
</textarea>
Irgendeine Funktion, die irgendetwas mit der Selektion macht, wenn die Benutzer auf den Button drücken.
function selEintrag()
{
if (!FEsel){ alert('Achtung!\n\nSie haben weder in ein Eingabefeld geklickt, noch einen Text markiert.\n\nBitte führen Sie eine dieser Aktionen aus, bevor Sie "Einfügen" wählen.');return;}
selWert = FEsel.text; // übertragen des selektierten Wertes
if (debuginfo >= '3') alert('Hinweis:\n\n An die Einfügenfunktion wird folgender Wert übergeben:\n\n' + selWert);
Hier ist ein Aufruf für einen Dialog, über den die Benutzer bestimmte Formatierungen auswählen können
var arr = showModalDialog( "Einfuegen.htm",
selWert,
"font-family:Verdana; font-size:12; dialogWidth:28em; dialogHeight:46em" );
Der Rückgabewert entscheidet, wie weiter verfahren wird.
arr ist null, wenn der Dialog geschlossen wurde, ohne das irgendetwas darin ausgewählt wurde, dann passiert gar nichts.
Gibt es aber einen Rückgabewert, so muss etwas passieren.
Hier werden drei Möglichkeiten abgefragt:
1. Sonderfunktion der markierte Text sollte über den Dialog in eine Tabelle gewandelt werden, dann wird der
Inhalt der Selektion einfach ersetzt durch den Rückgabewert. Das bedeutet, ich kann den selektierten
Inhalt in etwas beliebig anderes umwandeln.
2. Sonderfunktion alles HTML im markierten Text soll entfernt werden. Rettungsfunktion für versehentlich
eingefügte HTML-Tags, die wieder entfernt werden sollen. Das ist der Teil, weshalb ich sage nicht
ganz 100% gut. Bei geschachtelten Tags (Tag im Tag durch Fehlbedienung) bleibt unter Umständen vom
letzen Tag der Text hinter dem vorletzten schliessenden ">" bis zum letzten schliessenden ">" (inklusive)
stehen. Weiter entfernt die replace-Funktion auch die Zeichenkombination "<>" was nicht unbedingt
gewollt sein muss. Ich habe aber keine Schreibweise für den regulären Ausdruck finden können, der das
verhindert. Meine Schwäche...
3. Die "normale" Aktion den markierten Text mit den ausgewählten HTML-Tags umrahmen. Dazu wird der Rückgabewert
in zwei Teile zerlegt (Das muss im Dialog entsprechend codiert sein, das der Rückgabewert in dieser Form
geliefert wird.). Im ersten Teil steht das öffenende Tag, im zweiten das schliesende Tag.
Die Selektion wird dann anschliessend mit den Teilen umrahmt.
Die reine Wertzuweisung an die Selektion führt dazu, dass der Text in der angeklickten Textarea an der
angeklickten Stelle ersetzt wird und alles ist so wie es sein soll.
Zum Schluss muss noch die Selektion negiert werden, damit man nicht unabsichtlich ein zweites Mal damit arbeitet.
if (arr != null)
{
var htmlTag=arr.split('|');
var rg=FEsel;
if (htmlTag[0] == 'in Tabelle wandeln') { rg.text = htmlTag[1]; return;}
else if (htmlTag[0] == 'alles HTML entfernen') {rg.text = rg.text.replace(/<[^>]*>/g,''); return;}
else rg.text=htmlTag[0]+rg.text+htmlTag[1];
FEsel = !FEsel;
return
}
FEsel = !FEsel;
}
Gruß
Günter