Exiger
1. Lorsque vous entrez @, le menu d'amis assorti apparaît
2. Lorsque le curseur entre dans la balise contenant "@friends", le menu apparaîtra
3. Lorsque vous appuyez sur Backpace pour supprimer, si le curseur est devant la balise contenant "@friends", le menu apparaîtra.
4. Compatible avec IE, Firefox.
Pratiques spécifiques
Pour les exigences 1, il est naturel de penser aux événements de liaison à la boîte d'entrée. Ici, vous devez lier Mousedown, pas la souris. Parce que s'il s'agit de souris, en utilisant Event.PreventDefault () ne peut pas empêcher le clavier d'entrer @. De plus, l'utilisation des rappels de retour false dans les événements ici ne fonctionnera pas.
Après avoir lié l'événement MousDown, vous devez insérer une balise personnalisée contenant "@friends". La boîte d'entrée sur Sina Weibo est fabriquée avec TextArea. Je ne peux pas savoir comment il est géré en interne, donc je dois lire Baidu Tieba.
Vous pouvez voir que la balise <span class = 'at'> </span> a été insérée dans la barre de pote. Cela devrait être pratique pour la correspondance d'arrière-plan avec des expressions régulières.
Spécifique
La copie de code est la suivante:
vm.check_key = fonction (e) {
var editor = $ ('editor'), gamme;
if (e.shiftkey && e.keyCode == 50) {
if (document.selection && document.selection.createrange) {
plage = document.selection.creareange ();
range.pastehtml ("<span id = 'at" + at_index + "' class = 'at_span'> @ </span>");
}autre{
document.execcommand ("inserthtml", false, "<span id = 'at" + at_index + "' class = 'at_span'> @ </span>");
}
E.PreventDefault ();
}
};
Cela nécessite l'insertion au curseur, donc la plage est utilisée.
Ensuite, le menu s'affiche, la clé est de savoir comment la positionner. Mon approche est très des ordures, qui est d'ajouter un ID à la portée insérée, puis de localiser le menu en fonction de la position de l'ID de portée. S'il y a une meilleure façon, faites-le moi savoir.
Spécifique
La copie de code est la suivante:
fonction 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 = 'bloc';
}
var at_index = 0, cur_index = 0;
Avalon.define ('Editor', fonction (VM) {
vm.Item_click = function () {
$ ('at' + cur_index) .innerhtml = "@" + this.innerhtml;
$ ('at_box'). style.display = 'aucun';
at_index ++;
};
vm.check_key = fonction (e) {
var editor = $ ('editor'), a = getCacterPrecedingCaret (éditeur), gamme;
if (e.shiftkey && e.keyCode == 50) {
if (document.selection && document.selection.createrange) {
plage = document.selection.creareange ();
range.pastehtml ("<span id = 'at" + at_index + "' class = 'at_span'> @ </span>");
}autre{
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 LOCATE AT_BOX Selon l'ID SPAN nouvellement inséré, puis affiche le menu. Cur_index représente l'ID de portée où se trouve actuellement le curseur. Définissez cette variable car l'utilisateur peut rembobiner et modifier la portée insérée, et AT_INDEX augmente constamment, donc une variable est également nécessaire ici.
L'utilisateur clique sur l'élément d'ami dans le menu pour déclencher le rappel item_click. Dans le rappel, ajoutez le nom de l'ami à la portée actuelle à l'aide d'inserhtml. Cachez ensuite le menu, AT_INDEX ++.
Ce qui précède écoute Shift + @, suivi de l'écoute de la suppression de BackSpace.
La copie de code est la suivante:
fonction getTextBeForECursor (contenerel) {
var PrecedingChar = "", Sel, Range, PrecedingRange;
if (window.getSelection) {
sel = window.getSelection ();
if (sel.RangeCount> 0) {
plage = sel.getRangeat (0) .clonerange ();
plage.collapse (vrai);
range.setStart (contenerel, 0);
PrecedChar = range.clonEcontents ();
}
} else if ((sel = document.selection)) {
plage = sel.Createrange ();
PrecedingRange = range.duplicate ();
PrecedingRange.movetoElementText (contenerel);
PrecedingRange.SetEndpoint ("Endtostart", plage);
PrecedingChar = PrecedingRange.htmlText;
}
retour précédent.
}
La fonction de getTextBeForCursor est d'obtenir le contenu avant le curseur. En raison de la compatibilité, cette fonction peut obtenir un document de document qui est tout le contenu avant le curseur dans un navigateur standard, et dans IE, vous ne pouvez obtenir du texte (pas de nœud). Cependant, cette chaîne HTML peut être convertie en DocumentFragment. Dans Avalon, ParseHTML peut être utilisé pour transformer la chaîne HTML en nœud. Vous pouvez également obtenir un nœud en utilisant $ (html) [0] dans jQuery.
Avec cette fonction, vous pouvez utiliser LastChild pour déterminer si le curseur est dans le Lastchild dans le HTML devant le curseur, et ce dernierChild est une portée.
Spécifique
La copie de code est la suivante:
var a = getTextBeForCursor ($ ('éditeur'));
if (e.KeyCode == 8) {
if (! - [1,]) {
var b = avalon.parsehtml (a) .lastchild;
}autre{
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);
}autre
$ ('at_box'). style.display = 'aucun';
}
Enfin, le curseur entre dans l'étiquette de portée et affiche le menu. Cela nécessite évidemment la liaison de l'événement de la souris. MouseUp est lié ici, car si Mousedown est lié, vous devez cliquer à nouveau sur la souris sur l'étiquette de la portée avant que le menu ne puisse être affiché. Quant au principe, il est similaire à ce qui précède.
La copie de code est la suivante:
vm.check_mouse = fonction (e) {
var editor = $ ('editor'), a = getTextBeForCursor (éditeur);
if (! - [1,]) {
var b = avalon.parsehtml (getTextBeForEcursor (éditeur)). LastChild;
}autre{
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);
}autre
$ ('at_box'). style.display = 'aucun';
};
Notez que si le curseur est dans la travée, il doit être supprimé et que l'AT_BOX doit être positionnée en fonction de cet ID, et également réinitialiser Cur_index.
Quant au menu de mise à jour de l'Ajax, je ne ferai pas le personnage correspondant
Effet
incendier
IE8
IE7
IE6
télécharger
Ce qui précède est tout le contenu décrit dans cet article. J'espère qu'il sera utile pour tout le monde de comprendre JavaScript.