JS Implementation @ mention friends

Source: Internet
Author: User

Reprint Please specify: theviper http://www.cnblogs.com/TheViper

Requirements

1. When you enter @, a matching friend menu pops up

2. When the cursor enters a tag containing "@ friend", the popup menu

3. When backspace is deleted, if the cursor is preceded by a label containing "@ friend", the popup menu

4. Compatible with Ie,firefox.

Specific practices

For the requirement one, it is natural to think about binding the event to 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, it does not work with return false in event callbacks.

After you bind the MouseDown event, you will insert a custom tag that contains "@ Friends". Sina Weibo input box is made with textarea, can not know how to deal with the internal, had to look at Baidu bar paste.

As you can see, post bar is inserted into the <span class= ' at ' ></span> tag. This should be handy for backstage matching with regular expressions.

Specific to

vm.check_key=function(e) {vareditor=$ (' editor ')), range; if(e.shiftkey&&e.keycode==50){                if(Document.selection &&document.selection.createRange) {range=Document.selection.createRange (); Range.pastehtml ("&nbsp;<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>&nbsp;"); }Else{Document.execcommand ("Inserthtml",false, "&nbsp;<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>&nbsp;");            } e.preventdefault (); }        };

This needs to be inserted at the cursor, so a range is used.

Then the menu shows, the key is how to locate. My approach is garbage, which is to add an ID to the inserted span, and then position the menu based on the location of the span ID. If there is a better way, please let me know.

Specific to

    functionAt_box_show (at) {varat_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 '; }    varAt_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) {vareditor=$ (' editor '), a=Getcharacterprecedingcaret (editor), range; if(e.shiftkey&&e.keycode==50){                if(Document.selection &&document.selection.createRange) {range=Document.selection.createRange (); Range.pastehtml ("&nbsp;<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>&nbsp;"); }Else{Document.execcommand ("Inserthtml",false, "&nbsp;<span id= ' at" +at_index+ "' class= ' At_span ' >@</span>&nbsp;"); } 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 where the cursor is currently located. Set this variable because the user may fall back to the span that has been inserted, and the at_index is incremented, so there is a variable.

The user clicks on the Friend item in the menu to trigger the Item_click callback. The callback is to add the friend name to the current span with innserhtml. Then hide the menu, at_index++.

The above is listening [email protected], followed by monitoring backspace delete.

    functionGettextbeforecursor (containerel) {varPrecedingchar = "", 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; }        returnPrecedingchar; }

The function of Gettextbeforecursor is to get the content before the cursor. Because of the compatibility, this function in the standard browser can get all the content before the cursor documentfragment, and in IE can only get text (not node), However, this HTML string can be converted to documentfragment. With parsehtml in Avalon, you can turn the HTML string into node. You can also get node with $ (HTML) [0] in jquery.

With this function, you can then use LastChild to determine if the cursor is in the lastchild of the HTML before the cursor, and the LastChild is span.

Specific to

               varA=gettextbeforecursor ($ (' editor '))); if(e.keycode==8){                if(!-[1,]) {                    varb=avalon.parsehtml (a). LastChild; }Else{                    varb=A.lastchild; }                if(b.nodetype==1&&b.nodename== ' SPAN '){                    varId=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 binding mouse events. This binds MouseUp, because if you bind MouseDown, you need the mouse to click the span tag again to display the menu. As for the principle, similar to the above.

Vm.check_mouse=function(e) {vareditor=$ (' editor '), a=Gettextbeforecursor (editor); if(!-[1,]) {                varb=avalon.parsehtml (Gettextbeforecursor (editor)). LastChild; }Else{                varb=A.lastchild; }            if(b!=NULL&&b.nodetype==1&&b.nodename== ' SPAN '){                varId=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 based on this ID, and also to reset the Cur_index.

As for the Ajax update menu, character matching I won't do it.

Effect

Firefox

Ie8

Ie7

Ie6

Example download

JS Implementation @ mention friends

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.