Como obter a posição do texto selecionado da área de texto em JavaScript?

20

Quero obter a posição do texto selecionado usando javascript. Por exemplo,
eu tenho uma área de texto simples.

#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>

Na minha área de texto, tenho alguns textos como:

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

A partir dessa string, se eu selecionar "tornar-se uma boa pessoa" na área de
texto , então Como posso obter a posição de texto / string selecionada em javascript?


Aqui, o caractere de sequência selecionado começa em 29 e termina em 49. Portanto, a posição inicial é 29 e a posição final é 49

Md. Tahazzot
fonte
11
Por posição, você quer dizer qual é o índice do caractere "b" de "tornar-se" na string?
palaѕн 23/02
Sinto que a pergunta está apenas pedindo HTMLInputElement.selectionStart e selectionEnd, enquanto as respostas falam principalmente sobre o evento de seleção. Não faz sentido escrever uma resposta que esteja incluída em todas as outras respostas.
JollyJoker

Respostas:

24

Isso funcionará para a seleção de texto com o mouse e o teclado para todos os elementos da área de texto na página. Altere o seletor, seja mais específico e leia os comentários, se você não quiser / precisar da seleção do 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
fonte
2
Muito arrumado. +1
Saharsh em
2
Isso não dispara se você selecionar usando o teclado e não o mouse.
curiousdannii
11
@curiousdannii Atualizei a resposta, agora também funciona com a seleção de teclados
caramba
5

Eu usaria o evento onselect para obter o mesmo.

<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
fonte
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
fonte
1

A resposta do Caramba funcionou muito bem, no entanto, tive o problema de que se você selecionasse algum texto e soltasse o mouse fora da área de texto , o evento não seria acionado.

Para resolver isso, mudei o evento inicial para mousedown, este evento registra um mouseupevento no documento para garantir que ele seja acionado após o lançamento do cursor. omouseup evento é removido automaticamente após ser acionado.

Isso pode ser alcançado com a adição da onceopção addEventListener, mas infelizmente não é suportada no IE11, e é por isso que usei a solução no snippet.

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>

Hiws
fonte
Eu gosto de como você implementou o 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
fonte
Você pode adicionar uma pequena explicação ao que o código faz?
Rachel McGuigan