Requirements
1. Enter @, pop-up matching buddy menu
2. When the cursor enters a label containing the @ buddy, the pop-up menu
3. Press BACKSPACE Delete, if the cursor is preceded by a "@ Buddy" tag, pop-up menu
4. Compatible Ie,firefox.
Specific approach
For requirements one, it is natural to think of binding events on the input box. This is to bind the MouseDown, not the MouseUp. Because if it is MouseUp, using event.preventdefault () cannot prevent the keyboard from entering @. In addition, return false in the event callback is not useful here.
After binding the MouseDown event, insert a custom label that contains the @ buddy. Sina Weibo's input box is to do with textarea, can not know its interior is how to deal with, had to see Baidu Bar.
As you can see, the post bar is inserted into the <span class= ' at ' ></span> label. This should be convenient for the background to match with regular expressions.
Specific to
Copy Code code as follows:
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= ' at" +at_index+ "' class= ' At_span ' >@</span>");
}else{
Document.execcommand ("inserthtml", False, "<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>");
}
E.preventdefault ();
}
};
This needs to be inserted at the cursor, so the range is used.
Then the menu shows, the key is how to locate. My approach is garbage, which is to add an ID for the inserted span, and then locate the menu based on the location of the span ID. If there is a better way, please let me know.
Specific to
Copy Code code as follows:
function 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= ' block ';
}
var at_index=0,cur_index=0;
Avalon.define (' editor ', function (VM) {
Vm.item_click=function () {
$ (' at ' +cur_index). innerhtml= "@" +this.innerhtml;
$ (' At_box '). style.display= ' None ';
at_index++;
};
Vm.check_key=function (e) {
var editor=$ (' editor '), A=getcharacterprecedingcaret (editor), range;
if (e.shiftkey&&e.keycode==50) {
if (document.selection && document.selection.createRange) {
Range = Document.selection.createRange ();
Range.pastehtml ("<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>");
}else{
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 locates the At_box based on the newly inserted span ID, and then displays the menu. Cur_index represents the span ID at which the cursor is currently located. Set this variable because the user may go back and change the span already inserted, and the at_index is incremented, so here's a variable.
The user clicks on the Buddy item in the menu and triggers the Item_click callback. The callback is to add the buddy name to the current span with innserhtml. Then hide the menu, at_index++.
The above is the monitor shift+@, followed by the monitoring backspace delete.
Copy Code code as follows:
function Gettextbeforecursor (Containerel) {
var Precedingchar = "", sel, range, Precedingrange;
if (window.getselection) {
sel = Window.getselection ();
if (Sel.rangecount > 0) {
Range = sel.getrangeat (0). Clonerange ();
Range.collapse (TRUE);
Range.setstart (Containerel, 0);
Precedingchar = Range.clonecontents ();
}
else if ((sel = document.selection)) {
Range = Sel.createrange ();
Precedingrange = Range.duplicate ();
Precedingrange.movetoelementtext (Containerel);
Precedingrange.setendpoint ("Endtostart", range);
Precedingchar = Precedingrange.htmltext;
}
return Precedingchar;
}
The role of Gettextbeforecursor is to get the contents of the cursor. Because of compatibility, this function can get the documentfragment of all the contents before the cursor in the standard browser, but only the text (not node) in IE. However, this HTML string can be converted to DocumentFragment. Using parsehtml in Avalon can transform an HTML string into node. jquery can also get node with $ (HTML) [0].
With this function, the lastchild can be used to determine whether the cursor is in the lastchild of the HTML before the cursor, and the LastChild is span.
Specific to
Copy Code code as follows:
var a=gettextbeforecursor ($ (' editor '));
if (e.keycode==8) {
if (!-[1,]) {
var b=avalon.parsehtml (a). LastChild;
}else{
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);
}else
$ (' At_box '). style.display= ' None ';
}
Finally, the cursor enters the Span tab and displays the menu. This obviously requires the binding of mouse events. This binds MouseUp, because if you bind MouseDown, you need to click the Span tab again to display the menu. As for the principle, similar to the above.
Copy Code code as follows:
Vm.check_mouse=function (e) {
var editor=$ (' editor '), A=gettextbeforecursor (editor);
if (!-[1,]) {
var b=avalon.parsehtml (Gettextbeforecursor (editor)). LastChild;
}else{
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);
}else
$ (' At_box '). style.display= ' None ';
};
Note that if the cursor is inside span, it is necessary to remove its id,at_box according to this ID and reset the cur_index.
As for the AJAX update menu, I don't do the character matching.
Effect
Firefox
Ie8
Ie7
Ie6
Download
That's all the stuff in this article, and hopefully it will help you understand JavaScript.