Eu tenho esse HTML simples como exemplo:
<div id="editable" contenteditable="true">
text text text<br>
text text text<br>
text text text<br>
</div>
<button id="button">focus</button>
Quero uma coisa simples - quando clico no botão, quero colocar o cursor (cursor) em um local específico na div editável. Ao pesquisar na Web, tenho esse JS anexado ao clique no botão, mas ele não funciona (FF, Chrome):
var range = document.createRange();
var myDiv = document.getElementById("editable");
range.setStart(myDiv, 5);
range.setEnd(myDiv, 5);
É possível definir manualmente a posição do sinal de intercalação como esta?
setSelectionRange()
função da resposta que escrevi aqui: stackoverflow.com/questions/6240139/… . Como observei na resposta, existem várias coisas que ele não manipulará de maneira correta / consistente, mas pode ser bom o suficiente.document.createRange
(ouwindow.getSelection
, mas não chegará tão longe).A maioria das respostas que você encontra sobre o posicionamento editável do cursor é bastante simplista, pois elas servem apenas para entradas com texto simples de baunilha. Depois de usar elementos html no contêiner, o texto digitado é dividido em nós e distribuído livremente em uma estrutura de árvore.
Para definir a posição do cursor, tenho esta função que faz um loop em todos os nós de texto filho no nó fornecido e define um intervalo desde o início do nó inicial até o caractere chars.count :
Eu chamo a rotina com esta função:
O range.collapse (false) define o cursor para o final do intervalo. Eu testei com as versões mais recentes do Chrome, IE, Mozilla e Opera e todas elas funcionam bem.
PS. Se alguém estiver interessado, recebo a posição atual do cursor usando este código:
O código faz o oposto da função definida - obtém a janela atual.getSelection (). FocusNode e focusOffset e conta de volta todos os caracteres de texto encontrados até atingir um nó pai com o ID de containerId. A função isChildOf apenas verifica antes de executar se o nó fornecido é realmente um filho do parentId fornecido .
O código deve funcionar em linha reta, sem mudança, mas Acabo de tomar-lo de um plugin jQuery que eu desenvolvi assim ter cortado fora um par de este - deixe-me saber se alguma coisa não funciona!
fonte
node.id
e meparentId
relaciono sem um exemplo. Obrigado :)Se você não quiser usar o jQuery, tente esta abordagem:
editableDiv
seu elemento editável, não se esqueça de definir umid
para ele. Então você precisa tirar o seuinnerHTML
elemento e cortar todas as linhas de freio. E apenas defina o colapso com os próximos argumentos.fonte
fonte
É muito difícil definir o sinal de intercalação na posição correta quando você tem um elemento avançado como (p) (extensão) etc. O objetivo é obter (texto do objeto):
fonte
Estou escrevendo um marca-texto de sintaxe (e um editor de código básico) e precisava saber como digitar automaticamente um caractere de aspas simples e mover o cursor de volta (como muitos editores de código hoje em dia).
Aqui está um trecho da minha solução, graças a muita ajuda deste segmento, os documentos MDN e muita observação no console do moz.
Isso está em um elemento div editável por conteúdo
Deixo isso aqui como agradecimento, percebendo que já existe uma resposta aceita.
fonte
Eu fiz isso para o meu editor de texto simples.
Diferenças de outros métodos:
uso
selection.ts
fonte
Eu refatorei a resposta de @ Liam. Coloquei-o em uma classe com métodos estáticos, fiz suas funções receberem um elemento em vez de um #id, e alguns outros pequenos ajustes.
Esse código é particularmente bom para fixar o cursor em uma caixa de rich text que você pode criar
<div contenteditable="true">
. Fiquei preso por vários dias antes de chegar ao código abaixo.edit: Sua resposta e esta resposta têm um bug envolvendo pressionar Enter. Como enter não conta como um caractere, a posição do cursor é alterada após pressionar Enter. Se eu conseguir corrigir o código, atualizarei minha resposta.
edit2: Salve-se de muitas dores de cabeça e verifique se
<div contenteditable=true>
estádisplay: inline-block
. Isso corrige alguns erros relacionados à colocação do Chrome em<div>
vez de<br>
quando você pressiona enter.Como usar
Código
fonte
Eu acho que não é simples definir o sinal de intercalação para alguma posição no elemento editável por conteúdo. Eu escrevi meu próprio código para isso. Ignora a árvore do nó calculando quantos caracteres restam e define o sinal de intercalação no elemento necessário. Não testei muito esse código.
Também escrevi o código para obter a posição atual do cursor (não testei):
Você também precisa estar ciente de range.startOffset e range.endOffset contêm deslocamento de caracteres para nós de texto (nodeType === 3) e deslocamento de nó filho para nós de elemento (nodeType === 1). range.startContainer e range.endContainer podem se referir a qualquer nó de elemento de qualquer nível na árvore (é claro que também podem se referir a nós de texto).
fonte
Com base na resposta de Tim Down, mas verifica a última linha de texto "boa" conhecida. Coloca o cursor no final.
Além disso, eu também pude verificar recursivamente / iterativamente o último filho de cada último filho consecutivo para encontrar o último nó de texto "bom" absoluto no DOM.
fonte