Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

ronaldomarcos

Manter posição do range/position inicial

Recommended Posts

Boa tarde, eu resolvi colocar num form (div editável) a opção de incluir links de imagens (sem upload) e emoticons. Com as imagens beleza, pois todas ficam numa linha nova, quanto aos emoticons eu queria sempre pegar a posição do cursor dentro do campo onde está o texto.

O HTML abaixo tem o div editável, bem simples... não coloquei o codigo inteiro da div que abre os emoticons, mas basicamente tem um onclick em cada figura que leva o parametro editor (que tem o id da div que estou editando) e emoti (o src da imagem).

 

 

HTML
<div id="comentar" class="comentar">
<div contenteditable="true" id="comentario" ></div>
</div>

 

Emoticon

<img title=":)" onclick="colaEmoticon('comentario',this.src)" alt=":)" src="http://www.........com/emoticons/smile.png">

 

 

A função abaixo que uso para colocar eles dentro do editor eu sempre tenho de clicar dentro da div antes (claro que o usuário não fará isso) para indicar onde deve ser inserido o primeiro img, depois ele mantém a ultima posição, eu gostaria de definir a div editavel como alvo, caso o curso esteja fora da div (assim não insere a imagem do emoticon fora do div)...

Parece simples como dar um focus(), mas isso sempre vai colocar o cursor no inicio, e os emoticons sempre ficarão no começo... isto é, apenas se estiver fora da div editável (pelo que vi isso é obtido com o getSelecton e range - que fucei um monte e nao consegui posicionar e acabei retirando).

Não estou usando jquery, pois é para uso apenas em mensagens dentro de um versão apenas para celular, e quero usar o mínimo de código..

Obrigado.

 

FUNÇÃO

function colaEmoticon(editor,emoti) {
var emoti = '<img src="'+emoti+'"> ';
var sel, range;

if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();

var el = document.createElement("div");
el.innerHTML = emoti;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);

if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Rafael, o que estou inserindo é html, não daria certo, cai no mesmo problema de antes, mas obrigado. Aliás notei o seguindo depois de umas fuçadas e algumas alterações... tive de salvar e recuperar a posição a cada vez.. utilizando o código abaixo, alterei a forma como insiro nó e sem usar fragment. Fazendo testes da seguinte forma funcionou, mas apenas com textos num input:

Então, criei um input text e escrevo para que ele coloque onde estava o cursor dentro do editor, e se por acaso seja clicado fora ele coloca no início do editor, perfeito até aí. ENTÃO, substitui para em vez inserir o texto do input, mando inserir o nó html (com o img do emoticom), funcionou perfeito. MAS quando eu coloco a mesma ação na imagem do emoticon para quando clicar ele inserir no editor, sempre sai no começo.

EXEMPLO: A parte do código é essa que publiquei (ta meio bagunçado, pois tirei o excedente): http://haempregos.com.br/editor.htm,

Escreva um texto, clique em qualquer posição e no botao inserir texto, não precisa escrever nada, pois coloquei um html na variavel... pode ver que vai na posicao do cursor sempre (exceto se tiver saido da div o foco, ai vai pra começo) NO ENTANTO, se clicar no inserir emoticom e clicar numa figura, que envia para mesma função de antes, ele sempre sai no inicio e não na posição do cursor


O script como ficou agora:

 

function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}

function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}


function insereNoCursor(emoti) {
var sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();

var textNode = document.createElement('img')
var atsrc = document.createAttribute('src');
atsrc.value = emoti;
textNode.setAttributeNode(atsrc);
range.insertNode(textNode);

sel.removeAllRanges();
range = range.cloneRange();
range.selectNode(textNode);
range.collapse(false);
sel.addRange(range);

}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.pasteHTML(emoti);
range.select();
}
}



var selRange;

function displayTextInserter() {
selRange = saveSelection();
document.getElementById("textInserter").style.display = "block";
document.getElementById("textToInsert").focus();
}


function insertText() {
var text = 'http://www.haempregos.com.br/emoticons/angel.png';
document.getElementById("textInserter").style.display = "none";
restoreSelection(selRange);
document.getElementById("comcomentario").focus();
insereNoCursor(text);
}


function chamaSmiles(left,top,id) {
if(!id) {
var id = '';
}
selRange = saveSelection();

if (document.getElementById("iconsmile"+id).style.display == 'none') {
document.getElementById("iconsmile"+id).style.top = top-148;
document.getElementById("iconsmile"+id).style.left = left-121;
document.getElementById("iconsmile"+id).style.display = '';
}else{
document.getElementById("iconsmile"+id).style.display = 'none';
}
}

function colaEmoticon(id,emoti) {
if(!id) {
var id = '';
}
var emoti = emoti;
document.getElementById("iconsmile"+id).style.display = 'none';
restoreSelection(selRange);
document.getElementById("comcomentario"+id).focus();
insereNoCursor(emoti);
}


Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.