日期:2014-05-16  浏览次数:20322 次

[求助]如何用JQuery来实现Ctrl+Space完成输入特定字符提示的自动完成功能
例,在文本框textarea中输入字符串"<设计"后,按下Ctrl+Space键,自动提示出与"<设计"有关的下拉框关联文字内容,然后选择其中一个后,能自动加上关闭符'>'。接着在同一行文字后面,当输入字符串"[保险"后,在次按下Ctrl+Space键,自动提示出与"[保险"有关的下拉框关联表名的文字内容,能自动加上关闭符']'。

例如,输入内容:在<设计模版>里选择一个模版后,在[保险经纪人]表中选择一个经纪人。
在这里输入"<设计"后,按下Ctrl+Space键,弹出一个下拉框提示,选择'设计模版',之后接着在"[保险"后,在按下Ctrl+Space键,弹出一个下拉框提示,选择'保险经纪人',就这样的效果。并且光标置放在封闭符后面时,按下Backspace键后,仅删除"<设计模版>"或"[保险经纪人]"的自动提示内容。

这个就好象在Eclipse的代码框中输入"Obj."后,按下Ctrl+Space键,自动弹出一个下拉框,里面是Obj相关的属性和方法等。
不过我这个要求比较简单,提示的只是与"<设计"有关联的文字内容。例如:"<设计书>"、"<设计模版>"、"<设计方案>"等。
这里有一个特殊的地方,是我觉得不好实现的,那就是,当前面第一个"<设计"的自动完成实现后,后面第二个"[保险"的自动完成该如何实现呢?

以上"<设计"、"[保险"提示出的下拉列表的内容存放在一个MapList中。

不知上面我所说的功能通过JQuery该如何实现,请教这里的大虾们了。
可能的话能把示例代码发到我邮箱吗?hnjyfxl@gmail.com 
不胜感激!!!

------解决方案--------------------
试着做了个,有几个问题:
1. 不能用 textarea,因为其是文本控件,无法插入非文本节点。所以用 div 的 contentEditable 模式代替,用样式模仿 textarea;当然,LZ自己再花点功夫,在运行时把 div 和 textarea 进行实时互换应该也是可以的。
2. 如 #3 楼所说,Ctrl+Space键与输入法快捷键有冲突,所以随便选了一个键 F2 作为代替。弹出下拉列表后可按 ESC 取消;
3. 以下代码在 Win7 IE9 下调试通过,LZ 要想跨浏览器还要自己再花点功夫,估计 bug 也是要花不少功夫整理的。
代码:
<script type="text/javascript">
function ta1_focus()
{
var ta = event.srcElement;
ta.contentEditable = "true";
}
function ta1_keydown()
{
if(event.keyCode == 113) //F2
{
var ta = event.srcElement;
ta.focus();
savePos(ta);
var _range = document.selection.createRange();
if(_range.text.length > 0); //不选中文本
{
_range.text = _range.text;0
_range.select();
}

var ptxt = ta.innerText.substr(0, start);
var _reg = new RegExp(test_txt + "$", "g");
if(_reg.test(ptxt))
{
test_txt = "测试";
document.execCommand("InsertSelectListbox",false,"sel1");
var sel = document.getElementById("sel1");
var _left = sel.offsetLeft;
var _top = sel.offsetTop;
sel.style.position = "absolute";
sel.style.left = _left + "px";
sel.style.top = _top + 12 + "px";

sel.options.add(new Option("测试文本1", "测试文本1", true, true));
sel.options.add(new Option("测试文本2", "测试文本2"));

ta.contentEditable = "false";
sel.focus();
sel.onclick = seltext;
sel.onkeydown = caltext;
}
}
}
var test_txt = "测试";
function seltext()
{
if(test_txt == null || test_txt.length < 1)
{
return;
}
var sel = event.srcElement;
var _text = sel.value;
sel.outerHTML = "";
var ta = document.getElementById("ta1");
var pre = ta.innerText.substr(0, start - test_txt.length);
var post = ta.innerText.substr(start);
ta.innerText = pre + _text + post;

ta.contentEditable = "true";
ta.focus();
var _range = document.selection.createRange();
_range.moveStart("character", start + (_text.length - test_txt.length));
_range.select();
}
function caltext()
{
if(event.keyCode == 27) //ESC
{
var sel = event.srcElement;
sel.outerHTML = "";

var ta = document.getElementById("ta1");
ta.contentEditable = "true";
ta.focus();
var _range = document.selection.createRange();
_range.moveStart("character", start);
_range.select();