¿Cómo obtener la posición de texto seleccionada del área de texto en JavaScript?

20

Quiero obtener la posición de texto seleccionada usando javascript. Por ejemplo,
tengo un área de texto simple.

#input-text {
  resize: none;
  width: 50%;
  height: 50px;
  margin: 1rem auto;
}
<textarea id="input-text">I am a student and I want to become a good person</textarea>

En mi área de texto, tengo algunos textos como:

"I am a student and I want to become a good person"

De esta cadena, si selecciono "convertirse en una buena persona" en el área de texto,
¿cómo puedo obtener la posición de texto / cadena seleccionada en javascript?


Aquí el carácter de cadena seleccionado comienza desde 29 y termina en 49. Entonces, la posición inicial es 29 y la posición final es 49

MD Tahazzot
fuente
1
Por posición quieres decir ¿cuál es el índice del carácter "b" de "convertirse" en la cadena?
Palacio
Siento que la pregunta es solo pedir HTMLInputElement.selectionStart y selectionEnd mientras que las respuestas hablan principalmente sobre el evento de selección. Sin embargo, no tiene sentido escribir una respuesta que se incluya en todas las otras respuestas.
JollyJoker

Respuestas:

24

Esto funcionará para la selección de texto con el mouse y el teclado para todos los elementos de área de texto en la página. Asegúrate de cambiar el selector y ser más específico allí y leer los comentarios si no quieres / necesitas la selección del teclado.

var mySelection = function (element) {
    let startPos = element.selectionStart;
    let endPos = element.selectionEnd;
    let selectedText = element.value.substring(startPos, endPos);

    if(selectedText.length <= 0) {
      return; // stop here if selection length is <= 0
    }
    
    // log the selection
    console.log("startPos: " + startPos, " | endPos: " + endPos );
    console.log("selectedText: " +  selectedText);

  };

var textAreaElements = document.querySelectorAll('textarea');
[...textAreaElements].forEach(function(element) {
    // register "mouseup" event for the mouse
    element.addEventListener('mouseup', function(){
        mySelection(element)
    });
    
    // register "keyup" event for the keyboard
    element.addEventListener('keyup', function( event ) {
        // assuming we need CTRL, SHIFT or CMD key to select text
        // only listen for those keyup events
        if(event.keyCode == 16 || event.keyCode == 17 || event.metaKey) {
            mySelection(element)
        }
    });
});
textarea {
   resize: none; 
   width: 50%;
   height: 50px; 
   margin: 1rem auto;
}
<textarea>I am a student and I want to become a good person</textarea>

caramba
fuente
2
Con buena pinta. +1
Saharsh
2
Esto no se dispara si selecciona usar el teclado en lugar del mouse.
curiousdannii
1
@curiousdannii He actualizado la respuesta, ahora también funciona con la selección de teclado
caramba
5

Haría uso del evento onselect para obtener lo mismo.

<textarea id="input-text" onselect="myFunction(event)">I am a student and I want to become a good person</textarea>


<script>
    function myFunction(event) {
      const start  = event.currentTarget.selectionStart;
      const end= event.currentTarget.selectionEnd;
    }
</script>
Dreamweaver
fuente
1
    var idoftextarea='answer';
    function getSelectedText(idoftextarea){
        var textArea = document.getElementById(idoftextarea);
        var text =textArea.value;
        var indexStart=textArea.selectionStart;
        var indexEnd=textArea.selectionEnd;
        alert(text.substring(indexStart, indexEnd));

    }


    getSelectedText(idoftextarea);

Nourhan Ahmed
fuente
1

La respuesta de Caramba funcionó bastante bien, sin embargo, tuve el problema de que si seleccionaba algún texto y soltaba el mouse fuera del área de texto, el evento no se activaba.

Para resolver esto, cambié el evento inicial a mousedown, este evento registra un mouseupevento en el documento para garantizar que se active después de soltar el cursor. losmouseup evento luego se elimina después de que ha disparado.

Esto se puede lograr agregando la onceopción addEventListener, pero lamentablemente no es compatible con IE11, por eso utilicé la solución en el fragmento.

var mySelection = function (element) {
    let startPos = element.selectionStart;
    let endPos = element.selectionEnd;
    let selectedText = element.value.substring(startPos, endPos);

    if(selectedText.length <= 0) {
      return; // stop here if selection length is <= 0
    }
    
    // log the selection
    console.log("startPos: " + startPos, " | endPos: " + endPos );
    console.log("selectedText: " +  selectedText);
};

function addSelfDestructiveEventListener (element, eventType, callback) {
    let handler = () => {
        callback();
        element.removeEventListener(eventType, handler);
    };
    element.addEventListener(eventType, handler);
};

var textAreaElements = document.querySelectorAll('textarea');
[...textAreaElements].forEach(function(element) {
    // register "mouseup" event for those
    element.addEventListener('mousedown', function(){
      // This will only run the event once and then remove itself
      addSelfDestructiveEventListener(document, 'mouseup', function() {
        mySelection(element)
      })
    });
    
    // register "keyup" event for the keyboard
    element.addEventListener('keyup', function( event ) {
        // assuming we need CTRL, SHIFT or CMD key to select text
        // only listen for those keyup events
        if(event.keyCode == 16 || event.keyCode == 17 || event.metaKey) {
            mySelection(element)
        }
    });
});
textarea {
   resize: none; 
   width: 50%;
   height: 50px; 
   margin: 1rem auto;
}
<textarea>I am a student and I want to become a good person</textarea>

Hola
fuente
¡Me gusta cómo implementaste el addSelfDestructiveEventListener!
caramba
0
var mySelection = function (element) {
let startPos = element.selectionStart;
let endPos = element.selectionEnd;
let selectedText = element.value.substring(startPos, endPos);

if(selectedText.length <= 0) {
  return; // stop here if selection length is <= 0
}

// log the selection
console.log("startPos: " + startPos, " | endPos: " + endPos );
console.log("selectedText: " +  selectedText); };var textAreaElements = document.querySelectorAll('textarea'); 
[...textAreaElements].forEach(function(element) {
// register "mouseup" event for the mouse
element.addEventListener('mouseup', function(){
    mySelection(element)
});
// register "keyup" event for the keyboard
element.addEventListener('keyup', function( event ) {
    // assuming we need CTRL, SHIFT or CMD key to select text
    // only listen for those keyup events
    if(event.keyCode == 16 || event.keyCode == 17 || event.metaKey) {
        mySelection(element)
    }
});});
Yasser Abdel-Maksoud
fuente
¿Puede agregar una pequeña explicación a lo que hace su código?
Rachel McGuigan