在下面的文本框输入“@” 看一下效果吧!
已经解决 IE,FF ,CHORME 主流浏览器的兼容问题。有需要这个JS的朋友可以直接拿去用。
由于我实在无法把这个效果插入到这遍文章里。所以只能让大家下载我演示的文件了。
下载演示文件
思路
首先你是针对网页里面的textarea(这是一个很麻烦的标签) 这个标签的一些操作。
所以关于他的一些API你必须收集到。(下面会有提供)
A:是一个textarea
B:当前光标位置
我们的方案是 首先在页面创建一个(C)具有 visibility:hidden;(占位但是不显示) 属性的DIV。
他的位置,宽度,高度与A文本框一样(这意味着C现在与A已经重叠了)。
然后我们获取到B位置前面的所有文本(可以用js获取到),写入C 里面,在追加一个;
那么ID为FFF 的span标签的位置就是 B的位置。
HTML页面会多了一些这样的标签
可以获取到@符号的位置,其他问题都只是调试的问题了,就不多说了。你可以直接下载源码
textarea 的一些操作
/*
* TT textarea 操作函数
* info(t) 基本信息
* getCursorPosition(t) 光标位置
* setCursorPosition(t, p) 设置光标位置
* add(t,txt) 添加内容到光标处
*/
var TT = {
info:function(t){
var o = t.getBoundingClientRect();
var w = t.offsetWidth;
var h = t.offsetHeight;
return {top:o.top, left:o.left, width:w, height:h};
},
getCursorPosition: function(t){
if (document.selection) {
t.focus();
var ds = document.selection;
var range = null;
range = ds.createRange();
var stored_range = range.duplicate();
stored_range.moveToElementText(t);
stored_range.setEndPoint("EndToEnd", range);
t.selectionStart = stored_range.text.length - range.text.length;
t.selectionEnd = t.selectionStart + range.text.length;
return t.selectionStart;
} else return t.selectionStart
},
setCursorPosition:function(t, p){
var n = p == 'end' ? t.value.length : p;
if(document.selection){
var range = t.createTextRange();
range.moveEnd('character', -t.value.length);
range.moveEnd('character', n);
range.moveStart('character', n);
range.select();
}else{
t.setSelectionRange(n,n);
t.focus();
}
},
add:function (t, txt){
var val = t.value;
var wrap = wrap || '' ;
if(document.selection){
document.selection.createRange().text = txt;
} else {
var cp = t.selectionStart;
var ubbLength = t.value.length;
t.value = t.value.slice(0,t.selectionStart) + txt + t.value.slice(t.selectionStart, ubbLength);
this.setCursorPosition(t, cp + txt.length);
};
},
del:function(t, n){
var p = this.getCursorPosition(t);
var s = t.scrollTop;
t.value = t.value.slice(0,p - n) + t.value.slice(p);
this.setCursorPosition(t ,p - n);
D.FF && setTimeout(function(){t.scrollTop = s},10);
}
}
主要的一些JS
var AutoTips = function(A){
var elem = A.id ? D.$(A.id) : A.elem;
var checkLength = 5;
var _this = {};
var key = '';
_this.start = function(){
if(!D.$(config.boxID)){
var h = html.slice();
var info = TT.info(elem);
var div = D.DC('DIV');
var bs = D.BS();
h = h.replace('$top$',(info.top + bs.top)).
replace('$left$',(info.left + bs.left)).
replace('$width$',info.width).
replace('$height$',info.height).
replace('$SCTOP$','0');
div.innerHTML = h;
document.body.appendChild(div);
}else{
_this.updatePosstion();
}
}
_this.keyupFn = function(e){
var e = e || window.event;
var code = e.keyCode;
if(code == 38 || code == 40 || code == 13) {
if(code==13 && D.$(config.wrap).style.display != 'none'){
_this.enter();
}
return false;
}
var cp = TT.getCursorPosition(elem);
if(!cp) return _this.hide();
var valuep = elem.value.slice(0, cp);
var val = valuep.slice(-checkLength);
var chars = val.match(/(\w+)?@(\w+)$|@$/);
if(chars == null) return _this.hide();
var char = chars[2] ? chars[2] : '';
D.$(config.valuepWrap).innerHTML = valuep.slice(0,valuep.length - char.length).replace(/\n/g,'
').
replace(/\s/g,' ') + config.positionHTML;
_this.showList(char);
}
_this.showList = function(char){
key = char;
var data = DS.inquiry(friendsData, char, 5);
var html = listHTML.slice();
var h = '';
var len = data.length;
if(len == 0){_this.hide();return;}
var reg = new RegExp(char);
var em = ''+ char +'';
for(var i=0; i
h += html.replace(/\$ACCOUNT\$|\$NAME\$/g,data[i]['name']).
replace('$SACCOUNT$',hm).replace('$ID$',data[i]['user']);
}
_this.updatePosstion();
var p = D.$(config.position).getBoundingClientRect();
var bs = D.BS();
var d = D.$(config.wrap).style;
d.top = p.top + 20 + bs.top + 'px';
d.left = p.left - 5 + 'px';
D.$(config.listWrap).innerHTML = h;
_this.show();
}
_this.KeyDown = function(e){
var e = e || window.event;
var code = e.keyCode;
if(code == 38 || code == 40 || code == 13){
return selectList.selectIndex(code);
}
return true;
}
_this.updatePosstion = function(){
var p = TT.info(elem);
var bs = D.BS();
var d = D.$(config.boxID).style;
d.top = p.top + bs.top +'px';
d.left = p.left + bs.left + 'px';
d.width = p.width+'px';
d.height = p.height+'px';
D.$(config.boxID).scrollTop = elem.scrollTop;
}
_this.show = function(){
selectList.list = D.$(config.listWrap).getElementsByTagName('li');
selectList.index = -1;
selectList._this = _this;
_this.cursorSelect(selectList.list);
elem.onkeydown = _this.KeyDown;
D.$(config.wrap).style.display = 'block';
}
_this.cursorSelect = function(list){
for(var i=0; i
return function(){selectList.setSelected(i)};
})(i);
list[i].onclick = _this.enter;
}
}
_this.hide = function(){
selectList.list = null;
selectList.index = -1;
selectList._this = null;
D.ER(elem, 'keydown', _this.KeyDown);
D.$(config.wrap).style.display = 'none';
}
_this.bind = function(){
elem.onkeyup = _this.keyupFn;
elem.onclick = _this.keyupFn;
elem.onblur = function(){setTimeout(_this.hide, 100)}
//elem.onkeyup= fn;
//D.EA(elem, 'keyup', _this.keyupFn, false)
//D.EA(elem, 'keyup', fn, false)
//D.EA(elem, 'click', _this.keyupFn, false);
//D.EA(elem, 'blur', function(){setTimeout(_this.hide, 100)}, false);
}
_this.enter = function(){
TT.del(elem, key.length, key);
TT.add(elem, selectList.list[selectList.index].getElementsByTagName('A')[0].rel+' ');
_this.hide();
return false;
}
return _this;
}
作者:idche

谷歌浏览器提示此标签页的内容正在被共享怎么办?我们在使用谷歌浏览器打开新标签的时候有时候会遇到提示此标签页的内容正在被共享,那么这是怎么回事?下面就让本站来为用户们来仔细的介绍一下谷歌浏览器提示此标签页的内容正在被共享的问题解析吧。 谷歌浏览器提示此标签页的内容正在被共享解决方法 1、打开谷歌浏览器,在浏览器右上角可以看到三个点“自定义和控制Googlechrome”用鼠标点击图标进行图标。 2、点击后,谷歌浏览器的菜单窗口将弹出到下面,鼠标将移动到“更多工具

当使用Win11系统时,有时候会遇到需要输入管理员用户名和密码的提示,本文将探讨在遇到这种情况时应该如何处理。方法一:1、点击【Windows徽标】,然后按【Shift+重启】进入安全模式;或者这样进入安全模式:点击开始菜单,选择设置。选择“更新和安全”;选择“恢复”中的“立即重启”;重启进入选项后选择——疑难解答——高级选项——启动设置—&mdash

在社交媒体的早期,您可以多次更改您的个人资料名称,但现在在任何社交媒体应用程序上更改您的姓名都有其自身的一套限制。如果您一直想更改您在Instagram上的显示名称或用户名,下面的帖子将解释您可以更改它们的频率、如何进行更改,以及当您无法在Instagram上更改您的名称时可以采取哪些措施该平台。如何更改Instagram上的显示名称和用户名?Instagram为您的姓名提供了两个位置——您的显示名称和您的用户名,幸运的是,您可以在移动应用程序中轻松更改这两个位置。显示名称是您通常输入真

OOBE或开箱即用体验是为用户设计的流程,用于指导他们完成安装后步骤的各个阶段。这包括权利和协议页面、登录页面、WiFi或网络连接选项等。如果您收到任何OOBEKeyboard、OOBELOCAL或OOBEREGION问题,则无法继续进行最后的安装步骤。不用担心。您可以使用一些简单的修复程序来解决此问题。解决方法——在你做任何其他事情之前,请尝试这些正常的解决方案-1.当您收到错误提示时,请继续点击“再试一次”提示。至少继续尝试7到8次。2.检查网络连通性。如果您使用的是以太网连接或Wi

现在很多热爱游戏的windows用户都进入了Steam客户端,可以搜索、下载和玩任何好游戏。但是,许多用户的个人资料可能具有完全相同的名称,这使得查找个人资料或什至将Steam个人资料链接到其他第三方帐户或加入Steam论坛以共享内容变得困难。为配置文件分配了一个唯一的17位id,它保持不变,用户无法随时更改,而用户名或自定义URL可以更改。无论如何,一些用户并不知道他们的Steamid,这对于了解这一点非常重要。如果您也不知道如何找到您帐户的Steamid,请不要惊慌。在这篇文

在iOS17中,Apple彻底改变了其全部铃声和文本音调选择,提供了20多种可用于电话、短信、闹钟等的新声音。以下是查看它们的方法。与旧铃声相比,许多新铃声的长度更长,听起来更现代。它们包括琶音、破碎、树冠、小木屋、啁啾、黎明、出发、多洛普、旅程、水壶、水星、银河系、四边形、径向、清道夫、幼苗、庇护所、洒水、台阶、故事时间、戏弄、倾斜、展开和山谷。反射仍然是默认铃声选项。还有10多种新的文本提示音可用于传入短信、语音邮件、传入邮件警报、提醒警报等。要访问新的铃声和文本铃声,首先,请确保您的iPh

铁路12306用户名怎么填写?铁路12306APP中是可以填写用户名的,但是多数的小伙伴不知道铁路12306如何填写用户名,接下来就是小编为用户带来的铁路12306用户名填写方法图文教程,感兴趣的用户快来一起看看吧!铁路12306使用教程铁路12306用户名怎么填写1、首先打开铁路12306APP,主页面点击下方的【注册】;2、然后在注册的功能页面,输入用户名、密码、确认密码等等;3、最后输入完成之后即可填写用户注册。

wifi用户名是指无线路由器的管理用户名,这个用户名和路由器的IP地址以及管理口令的默认值通常都印在无线路由器的底部,在无线路由器的说明书上也能找到;多数路由器的默认管理用户名都是admin,管理口令也是admin。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。