it-swarm.com.de

Wie erhält man von Anfang an die Position der Caret-Spalte (nicht der Pixel) in einem Textbereich in Zeichen?

Wie erhält man die Caret-Position in einem <textarea> mit JavaScript?

Beispielsweise: This is| a text

Dies sollte 7.

Wie würden Sie es schaffen, die den Cursor/die Auswahl umgebenden Zeichenfolgen zurückzugeben?

Z.B.: 'This is', '', ' a text'.

Wenn das Wort "ist" markiert ist, würde es 'This ', 'is', ' a text'.

174

Mit Firefox, Safari (und anderen Gecko-basierten Browsern) können Sie textarea.selectionStart problemlos verwenden, aber für IE) funktioniert das nicht, daher müssen Sie Folgendes tun:

function getCaret(node) {
  if (node.selectionStart) {
    return node.selectionStart;
  } else if (!document.selection) {
    return 0;
  }

  var c = "\001",
      sel = document.selection.createRange(),
      dul = sel.duplicate(),
      len = 0;

  dul.moveToElementText(node);
  sel.text = c;
  len = dul.text.indexOf(c);
  sel.moveStart('character',-1);
  sel.text = "";
  return len;
}

( Code hier vervollständigen )

Ich empfehle Ihnen auch, das jQuery FieldSelection Plugin zu überprüfen, damit können Sie das und vieles mehr ...

Edit: Ich habe den obigen Code tatsächlich neu implementiert:

function getCaret(el) { 
  if (el.selectionStart) { 
    return el.selectionStart; 
  } else if (document.selection) { 
    el.focus(); 

    var r = document.selection.createRange(); 
    if (r == null) { 
      return 0; 
    } 

    var re = el.createTextRange(), 
        rc = re.duplicate(); 
    re.moveToBookmark(r.getBookmark()); 
    rc.setEndPoint('EndToStart', re); 

    return rc.text.length; 
  }  
  return 0; 
}

Überprüfen Sie ein Beispiel hier .

173
CMS

Aktualisiert am 5. September 2010

Da hier offenbar alle auf dieses Problem hingewiesen werden, füge ich meine Antwort einer ähnlichen Frage hinzu, die den gleichen Code wie diese Antwort enthält, aber den vollständigen Hintergrund für alle Interessierten bietet:

IE document.selection.createRange enthält keine führenden oder nachfolgenden Leerzeilen

Die Berücksichtigung nachfolgender Zeilenumbrüche ist im Internet Explorer schwierig, und ich habe keine Lösung gefunden, die dies korrekt ausführt, einschließlich anderer Antworten auf diese Frage. Mit der folgenden Funktion können Sie jedoch den Anfang und das Ende der Auswahl (die bei einem Caret identisch sind) innerhalb eines <textarea> Oder eines Textes <input> Zurückgeben. .

Beachten Sie, dass das Textfeld den Fokus haben muss, damit diese Funktion im Internet Explorer ordnungsgemäß funktioniert. Rufen Sie im Zweifelsfall zuerst die Methode focus() des Textbereichs auf.

function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}
57
Tim Down

Ich habe die obige Funktion geändert, um Wagenrückläufe im IE zu berücksichtigen. Es ist ungetestet, aber ich habe etwas Ähnliches damit in meinem Code gemacht, damit es funktionieren sollte.

function getCaret(el) {
  if (el.selectionStart) { 
    return el.selectionStart; 
  } else if (document.selection) { 
    el.focus(); 

    var r = document.selection.createRange(); 
    if (r == null) { 
      return 0; 
    } 

    var re = el.createTextRange(), 
    rc = re.duplicate(); 
    re.moveToBookmark(r.getBookmark()); 
    rc.setEndPoint('EndToStart', re); 

    var add_newlines = 0;
    for (var i=0; i<rc.text.length; i++) {
      if (rc.text.substr(i, 2) == '\r\n') {
        add_newlines += 2;
        i++;
      }
    }

    //return rc.text.length + add_newlines;

    //We need to substract the no. of lines
    return rc.text.length - add_newlines; 
  }  
  return 0; 
}
3
mark

Wenn Sie IE nicht unterstützen müssen, können Sie die selectionStart- und selectionEnd-Attribute von textarea verwenden.

Um die Position des Carets zu ermitteln, verwenden Sie einfach selectionStart:

function getCaretPosition(textarea) {
  return textarea.selectionStart
}

Verwenden Sie folgenden Code, um die die Auswahl umgebenden Zeichenfolgen abzurufen:

function getSurroundingSelection(textarea) {
  return [textarea.value.substring(0, textarea.selectionStart)
         ,textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)
         ,textarea.value.substring(textarea.selectionEnd, textarea.value.length)]
}

Demo auf JSFiddle .

Siehe auch HTMLTextAreaElement docs .