实现@人员的选择操作

//html页面显示元素

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 5     <title></title>
 6     <meta charset="utf-8" />
 7     <link rel="stylesheet" href="js/jquery-ui.min.css" />
 8 </head>
 9 
10 <body>
11         <div class="input-group">
12                 <div class="messageContent hide" contenteditable="true"></div>
13                 <div class="inputMessageInfo ">输入文字</div>
14                 <!--<span class="taskMessageSend icon-content_send"></span>
15                 <span class="expression icon-image_tag_faces"></span>-->
16             </div>
17 </body>
18 </html>

//样式

 1 <style>
 2     .input-group {
 3     width: 475px;
 4     border: 1px solid rgba(204, 204, 204, 0.86);
 5     border-radius: 4px;
 6     background: #fff;
 7     position: absolute;
 8     bottom: 0;
 9     display: inline-table;
10 }
11 .messageContent {
12     width: 86%;
13     min-height: 40px;
14     max-height: 200px;
15     padding: 11px 10px;
16     color: #a5a3a3;
17     white-space: normal;
18     overflow-y: auto;
19     overflow-x: hidden;
20     outline: none;
21     word-break: break-all;
22     text-align: justify;
23 }
24 .inputMessageInfo {
25     width: 100%;
26     height: 40px;
27     line-height: 40px;
28     text-indent: 5px;
29     border-radius: 4px;
30     color: #a5a3a3;
31     text-indent: 8px;
32 }
33 .atUserList {
34     z-index: 89;
35     bottom: 20px;
36     background: #fff;
37     border-radius: 4px;
38     overflow: auto;
39     position: absolute;
40     -webkit-box-shadow: 0 0 12px rgba(0,0,0,.375);
41     max-height: 210px;
42     min-height: 50px;
43 }
44 .atUserList .atUser {
45     display: flex;
46     justify-content: flex-start;
47     align-content: center;
48     width: 240px;
49     padding: 5px 0;
50     position: relative;
51 }
52 .atUserList .atUser .atUserImg {
53     flex-direction: row;
54     padding: 0 10px;
55 }
56 .atUserList .atUser .atUserImg img {
57     width: 30px;
58     height: 30px;
59     border-radius: 50%;
60 }
61 .atUserList .atUser .atUserInfo {
62     flex-direction: row;
63     flex-grow: 2;
64 }
65 .atUserList .atUser .atUserInfo p {
66     padding: 0;
67     margin: 0;
68     height: 10px;
69     margin-bottom: 5px;
70     line-height: 20px;
71 }
72 .hide{
73     display: none!important;
74 }
75 </style>

//js逻辑实现

  1 <script>
  2     $(function(){
  3           //选择需要@的人员
  4     $(document).on("click",".atUser", function () {
  5         var _this = $(this);
  6         var messageContent = _this.parent().siblings(".input-group").find(".messageContent");
  7         var content = messageContent.html();
  8         var userName = _this.find(".atUserInfo p:first-child").text();
  9         var userData = _this.data("userInfo");
 10         var showAtUser = "<a id=" + userData.ID + " userName=" + userData.Name + " DeptName=" + userData.DeptName + ">@" + userName + "</a>&nbsp;"
 11         var at = content.lastIndexOf("@");
 12         content = content.substring(0, at);
 13         if ($(".atUserList .atUser")) $(".atUserList .atUser").addClass("hide");
 14         messageContent.html(content + showAtUser);
 15        // moveCursor(messageContent.html());
 16         set_focus(messageContent[0]);//将鼠标移到输入框的最后面
 17     });
 18         
 19          $(".input-group").on('keyup', ".messageContent", function (e) {
 20         var _this = $(this);
 21         if (_this.parents(".input-group").prev().hasClass("atUserList")) {
 22             _this.parents(".input-group").prev(".atUserList").remove();
 23         }
 24         var repalyInfo = _this.parents(".inputReplay");
 25         _this.parents(".input-group").before("<div class='atUserList'></div>");
 26         if (repalyInfo && repalyInfo.length > 0) {
 27             _this.parents(".input-group").prev().position({//这里用的了jqueryui的定位
 28                 of: repalyInfo,
 29                 my: "left top",
 30                 at: "left bottom",
 31                 collision: "flipfit"
 32             });
 33         }
 34         showAtUser(_this, e)
 35     }).on('keydown', ".messageContent", function (e) {
 36         var _this = $(this);
 37         if (_this.parents(".input-group").prev().hasClass("atUserList")) {
 38             _this.parents(".input-group").prev(".atUserList").remove();
 39         }
 40         var content = _this.html();
 41         if (e.keyCode == 13) {
 42 //          var self = EMW.Global.User;
 43             //拿到当前用户
 44             if (_this.text().trim() == "" && !_this.find("img").length > 0) {
 45                 if (replayTip) {
 46                     replayTip = false;
 47                     Z.Show("请填写评论内容", function () {
 48                         replayTip = true;
 49                     });
 50                 }
 51                 return false;
 52             } 
 53 //          else {
 54 //              if (_this.parents().hasClass('messageinput')) {
 55 //                  saveMessage(_this, "", "", 1);
 56 //                  //刷新消息
 57 //                  _this.html("");
 58 //                  $(".messageInfos").removeClass("hide");
 59 //              } else {
 60 //                  var sentMessage = _this.parents(".inputReplay").data("sentMessage");
 61 //                  saveMessage(_this, sentMessage, self, 2);
 62 //              }
 63 //          }
 64             return false;
 65         }
 66     }).on("click",".inputMessageInfo",function(){
 67         $(this).prev().removeClass('hide');
 68         $(this).addClass('hide');
 69     });
 70   
 71     
 72     function showAtUser(element, e) {
 73     var selUser;
 74     if (element.find("a").length > 0) {
 75         var oldContent = element.clone();
 76         selUser = element.find("a");
 77         oldContent.find("a").remove();
 78         if (oldContent.text().indexOf("@") < 0) {
 79             return;
 80         }
 81     }
 82     var at = element.text().lastIndexOf("@");
 83     if (at < 0 && (e.keyCode == 8 || e.keyCode == 220)) {
 84         atUser(false);
 85     } else {
 86         var atUserList = atTaskUser();
 87         userList(element.parent().siblings(".atUserList"), atUserList);
 88         atUser(true, selUser);
 89         var userName = element.text().slice(at + 1);
 90         if (at < 0) {
 91             atUser(false);
 92         } else {
 93             atUser(userName || true, selUser);
 94         }
 95     }
 96     if (element.parents(".inputReplay") && element.parents(".inputReplay").length > 0) {
 97         var atUsers = element.parent().prev();
 98         if (atUsers.find(".atUser") && atUsers.find(".atUser").length > 1) {
 99             atUsers.css("height", (atUsers.find(".atUser").length * 42) + "px");
100         }
101     }
102 }
103     function userList(element, users) {
104     showSelUser = element.html("");
105     if (users && users.length > 0) {
106         for (var i = 0; i < users.length; i++) {
107             var user = userInfo(users[i]);
108             showSelUser.append(user.data("userInfo",users[i]));
109         }
110     }
111     //return showSelUser;
112 }
113 function atUser(userName,selUser) {
114    
115      if (userName && userName.length>0) {
116          if (showSelUser && showSelUser.find(".atUser") && showSelUser.find(".atUser").length > 0) {
117              if (userName.trim() == "") {
118                  showSelUser.find(".atUser").removeClass("hide");
119              } else {
120                  showSelUser.find(".atUser[userName*='" + userName + "']").removeClass("hide");
121                  showSelUser.find(".atUser:not([userName*='" + userName + "'])").addClass("hide");
122              }
123         } 
124      } else if (userName) {
125          if (showSelUser && showSelUser.find(".atUser") && showSelUser.find(".atUser").length > 0) {
126             showSelUser.find(".atUser").removeClass("hide");
127         }
128      } else {
129          if (showSelUser &&showSelUser.find(".atUser") && showSelUser.find(".atUser").length > 0) {
130              showSelUser.find(".atUser").addClass("hide");
131              return;
132          }
133      }
134         if (selUser && selUser.length > 0) {
135             for (var i = 0; i < selUser.length; i++) {
136                 var selUserId = $(selUser[i]).attr("id");
137                 if (showSelUser.find(".atUser[id=" + selUserId + "]").length>0) {
138                     showSelUser.find(".atUser[id=" + selUserId + "]").addClass("hide");
139                 }
140             }
141         }
142 }
143 function userInfo(user) {
144     var userInfoContent = $('<div class="atUser hide" userName=' + user.Name + ' id='+user.Id+'>'
145                 + '<div class="atUserImg">'
146                     + '<img src="' + user.Image + '" onerror="11111" >'
147                 + '</div>'
148                 + '<div class="atUserInfo">'
149                     + '<p>' + user.Name + '</p>'
150                     + '<p>' + user.Email + '</p>'
151                 + '</div>'
152                // + '<div class="selTaskUser">' + checkedUser + '</div>'
153             + '</div>')
154     return userInfoContent;
155 }
156         
157         //能被at到的人员
158 function atTaskUser() {
159     var proUsers = [];
160     var minUser =[{Name:"程陈",Phone:"18171843322",Sex:"18",Id:"103605",Email:"944820749"}];
161     var moreUser = [{Name:"程陈1",Phone:"18171843322",Sex:"18",Id:"103609",Email:"944820749"},{Name:"程陈2",Phone:"18171843322",Sex:"18",Id:"103607",Email:"944820749"}]
162     //判断有没有负责人
163     if (minUser && minUser.length > 0) {
164         for (var i = 0; i < minUser.length; i++) {
165             proUsers.push(minUser[i]);
166         }
167     }
168     //判断有没有成员
169     if (moreUser && moreUser.length > 0) {
170         for (var i = 0; i < moreUser.length; i++) {
171             proUsers.push(moreUser[i]);
172         }
173     }
174     var n = {}, r = []; //n为hash表,r为临时数组
175     for (var i = 0; i < proUsers.length; i++) //遍历当前数组
176     {
177         if (!n[proUsers[i].Id]) //如果hash表中没有当前项
178         {
179             n[proUsers[i].Id] = true; //存入hash表
180             r.push(proUsers[i]); //把当前数组的当前项push到临时数组里面
181         }
182     }
183     return r;
184 }
185 
186 //将鼠标移到文本最后
187 function set_focus(el) {
188     el.focus();
189     if (el instanceof jQuery) el = el[0];
190     //el=el[0];  //jquery 对象转dom对象
191     if ($.support.msie) {
192         var range = document.selection.createRange();
193         this.last = range;
194         range.moveToElementText(el);
195         range.select();
196         document.selection.empty(); //取消选中
197     }
198     else {
199         var range = document.createRange();
200         range.selectNodeContents(el);
201         range.collapse(false);
202         var sel = window.getSelection();//适用于firefox和safari
203         sel.removeAllRanges();//取消选中
204         sel.addRange(range);
205     }
206 }
207     })
208 </script>
原文地址:https://www.cnblogs.com/sunnie-cc/p/6549320.html