JS Perfect Implementation @ mentioned friend special effects (compatible with the major browsers) _javascript skills

Source: Internet
Author: User

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.