Exigir
1. Ao entrar @, o menu de amigos correspondente aparece
2. Quando o cursor entra na tag contendo "@friends", o menu aparecerá
3. Ao pressionar o backspace para excluir, se o cursor estiver frontal da tag contendo "@friends", o menu será exibido.
4. Compatível com o IE, Firefox.
Práticas específicas
Para os requisitos 1, é natural pensar em eventos de ligação à caixa de entrada. Aqui você precisa amarrar mousedown, não mouseup. Porque se for mouseup, o uso de event.preventDefault () não pode impedir que o teclado digite @. Além disso, o uso de retorno false nos retornos de chamada do evento aqui não funcionará.
Depois de vincular o evento Mousedown, você precisa inserir uma tag personalizada contendo "@friends". A caixa de entrada no Sina Weibo é feita com a Textarea. Não sei como é tratado internamente, então tenho que ler o Baidu Tieba.
Você pode ver que a tag <span class = 'em'> </span> foi inserida na barra de postagem. Isso deve ser conveniente para correspondência de fundo com expressões regulares.
Específico
A cópia do código é a seguinte:
vm.check_key = function (e) {
VAR Editor = $ ('Editor'), Range;
if (e.shiftKey && e.KeyCode == 50) {
if (Document.Selection && Document.Selection.Createrange) {
range = document.Selection.Createrange ();
range.Pastehtml ("<span id = 'em"+at_index+"' class = 'at_span'>@</span>");
}outro{
document.execCommand ("inserthtml", false, "<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}
E.PreventDefault ();
}
};
Isso requer inserção no cursor; portanto, o alcance é usado.
Em seguida, o menu é exibido, a chave é como posicioná -la. Minha abordagem é muito lixo, que é adicionar um ID ao intervalo inserido e, em seguida, localize o menu de acordo com a posição do ID do span. Se houver uma maneira melhor, por favor me avise.
Específico
A cópia do código é a seguinte:
função at_box_show (at) {
var AT_POS = Avalon ($ (at)). Position ();
$ ('at_box'). style.left = at_pos.left+'px';
$ ('at_box'). style.top = at_pos.top+16+'px';
$ ('at_box'). style.display = 'bloco';
}
var at_index = 0, cur_index = 0;
Avalon.Define ('Editor', função (VM) {
vm.item_click = function () {
$ ('em'+cur_index) .innerhtml = "@"+this.innerhtml;
$ ('at_box'). style.display = 'nenhum';
at_index ++;
};
vm.check_key = function (e) {
var editor = $ ('editor'), a = getCharacterprecedingCaret (editor), intervalo;
if (e.shiftKey && e.KeyCode == 50) {
if (Document.Selection && Document.Selection.Createrange) {
range = document.Selection.Createrange ();
range.Pastehtml ("<span id = 'em"+at_index+"' class = 'at_span'>@</span>");
}outro{
document.execCommand ("inserthtml", false, "<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}
at_box_show ('at'+at_index);
cur_index = at_index;
E.PreventDefault ();
}
};
});
AT_SHOW_BOX localiza AT_Box de acordo com o ID do span recém -inserido e exibe o menu. Cur_index representa o ID do span, onde o cursor está localizado no momento. Defina essa variável porque o usuário pode retroceder e alterar o intervalo inserido, e o AT_Index está aumentando constantemente; portanto, uma variável também é necessária aqui.
O usuário clica no item de amigo no menu para acionar o retorno de chamada item_click. No retorno de chamada, adicione o nome do amigo à extensão atual usando o InserHTML. Em seguida, oculte o menu, at_index ++.
O acima é o escuta de escuta+@, seguido de escuta para exclusão do backspace.
A cópia do código é a seguinte:
função getTextBeforeCursor (contêinerel) {
var precedingchar = "", SEL, Range, PrecedingRange;
if (window.getSelection) {
SEL = window.getSelection ();
if (sel.rangeCount> 0) {
range = Sel.Getrangaat (0) .CloneRange ();
range.collapse (true);
range.setStart (contêinerel, 0);
precedchar = range.cloneContents ();
}
} else if ((SEL = document.selection)) {
range = sel.createrange ();
precedingRange = range.Duplicate ();
PrecedingRange.MoveToElementText (contêinerel);
PrecedingRange.SetNendPoint ("ENDTOSTART", RANGE);
precedingchar = precedingRange.htmlText;
}
retornar precedingchar;
}
A função do getTextBeforCursor é obter o conteúdo antes do cursor. Devido à compatibilidade, essa função pode obter o DocumentFragment que é todo o conteúdo perante o cursor em um navegador padrão e, no IE, você só pode obter texto (não nó). No entanto, essa sequência HTML pode ser convertida em DocumentFragment. Em Avalon, o parsehtml pode ser usado para transformar a sequência HTML em nó. Você também pode obter o nó usando $ (html) [0] no jQuery.
Com essa função, você pode usar o LastChild para determinar se o cursor está no LastChild no HTML em frente ao cursor, e esse LastChild é um período.
Específico
A cópia do código é a seguinte:
var a = getTextBeforCursor ($ ('editor'));
if (e.KeyCode == 8) {
if (!-[1,]) {
var b = Avalon.parsehtml (a) .lastChild;
}outro{
var B = A.LastChild;
}
if (b.NodeType == 1 && b.Nodename == 'span') {
var id = b.id;
cur_index = b.id.substring (2);
at_box_show (b.id);
}outro
$ ('at_box'). style.display = 'nenhum';
}
Finalmente, o cursor entra no rótulo do Span e exibe o menu. Obviamente, isso requer vincular o evento do mouse. O MouseUp está vinculado aqui, porque se o mousedown estiver ligado, você precisará clicar no mouse no rótulo do span novamente antes que o menu possa ser exibido. Quanto ao princípio, é semelhante ao acima.
A cópia do código é a seguinte:
vm.check_mouse = function (e) {
var editor = $ ('editor'), a = getTextBeForEcursor (editor);
if (!-[1,]) {
var b = Avalon.parsehtml (getTextBeforeCursor (editor)). LastChild;
}outro{
var B = A.LastChild;
}
if (b! = null && b.nodetype == 1 && b.nodename == 'span') {
var id = b.id;
cur_index = b.id.substring (2);
at_box_show (b.id);
}outro
$ ('at_box'). style.display = 'nenhum';
};
Observe que, se o cursor estiver no período, ele deverá ser removido e o AT_Box deverá ser posicionado de acordo com este ID e também redefinir CUR_Index.
Quanto ao menu de atualização do Ajax, não farei a correspondência do personagem
Efeito
Firefox
ie8
ie7
ie6
download
O exposto acima é todo o conteúdo descrito neste artigo. Espero que seja útil que todos entendam o JavaScript.