问题描述
|
我正在寻找Javascript自动完成实现,其中包括以下内容:
可以在HTML文本区域中使用
允许键入常规文本而无需调用自动完成功能
检测“ 0”字符并在键入时开始自动完成
通过AJAX加载选项列表
我相信这与Twitter在推文中添加标签时的操作类似,但是我找不到很好的,可重用的实现。
jQuery的解决方案将是完美的。
谢谢。
解决方法
我确定您的问题已经解决了很长时间,但是jquery-textcomplete看起来可以完成任务。
, 另一个解决这个问题的出色库At.js
资源
演示版
, 你试过这个了吗
GITHUB:https://github.com/podio/jquery-mentions-input
演示/配置:http://podio.github.io/jquery-mentions-input/
实现起来非常简单。
, 尝试这个:
(function($){
$.widget(\"ui.tagging\",{
// default options
options: {
source: [],maxItemDisplay: 3,autosize: true,animateResize: false,animateDuration: 50
},_create: function() {
var self = this;
this.activeSearch = false;
this.searchTerm = \"\";
this.beginFrom = 0;
this.wrapper = $(\"<div>\")
.addClass(\"ui-tagging-wrap\");
this.highlight = $(\"<div></div>\");
this.highlightWrapper = $(\"<span></span>\")
.addClass(\"ui-corner-all\");
this.highlightContainer = $(\"<div>\")
.addClass(\"ui-tagging-highlight\")
.append(this.highlight);
this.meta = $(\"<input>\")
.attr(\"type\",\"hidden\")
.addClass(\"ui-tagging-meta\");
this.container = $(\"<div></div>\")
.width(this.element.width())
.insertBefore(this.element)
.addClass(\"ui-tagging\")
.append(
this.highlightContainer,this.element.wrap(this.wrapper).parent(),this.meta
);
var initialHeight = this.element.height();
this.element.height(this.element.css(\'lineHeight\'));
this.element.keypress(function(e) {
// activate on @
if (e.which == 64 && !self.activeSearch) {
self.activeSearch = true;
self.beginFrom = e.target.selectionStart + 1;
}
// deactivate on space
if (e.which == 32 && self.activeSearch) {
self.activeSearch = false;
}
}).bind(\"expand keyup keydown change\",function(e) {
var cur = self.highlight.find(\"span\"),val = self.element.val(),prevHeight = self.element.height(),rowHeight = self.element.css(\'lineHeight\'),newHeight = 0;
cur.each(function(i) {
var s = $(this);
val = val.replace(s.text(),$(\"<div>\").append(s).html());
});
self.highlight.html(val);
newHeight = self.element.height(rowHeight)[0].scrollHeight;
self.element.height(prevHeight);
if (newHeight < initialHeight) {
newHeight = initialHeight;
}
if (!$.browser.mozilla) {
if (self.element.css(\'paddingBottom\') || self.element.css(\'paddingTop\')) {
var padInt =
parseInt(self.element.css(\'paddingBottom\').replace(\'px\',\'\')) +
parseInt(self.element.css(\'paddingTop\').replace(\'px\',\'\'));
newHeight -= padInt;
}
}
self.options.animateResize ?
self.element.stop(true,true).animate({
height: newHeight
},self.options.animateDuration) :
self.element.height(newHeight);
var widget = self.element.autocomplete(\"widget\");
widget.position({
my: \"left top\",at: \"left bottom\",of: self.container
}).width(self.container.width()-4);
}).autocomplete({
minLength: 0,delay: 0,maxDisplay: this.options.maxItemDisplay,open: function(event,ui) {
var widget = $(this).autocomplete(\"widget\");
widget.position({
my: \"left top\",of: self.container
}).width(self.container.width()-4);
},source: function(request,response) {
if (self.activeSearch) {
self.searchTerm = request.term.substring(self.beginFrom);
if (request.term.substring(self.beginFrom - 1,self.beginFrom) != \"@\") {
self.activeSearch = false;
self.beginFrom = 0;
self.searchTerm = \"\";
}
if (self.searchTerm != \"\") {
if ($.type(self.options.source) == \"function\") {
self.options.source(request,response);
} else {
var re = new RegExp(\"^\" + escape(self.searchTerm) + \".+\",\"i\");
var matches = [];
$.each(self.options.source,function() {
if (this.label.match(re)) {
matches.push(this);
}
});
response(matches);
}
}
}
},focus: function() {
// prevent value inserted on focus
return false;
},select: function(event,ui) {
self.activeSearch = false;
//console.log(\"@\"+searchTerm,ui.item.label);
this.value = this.value.replace(\"@\" + self.searchTerm,ui.item.label) + \' \';
self.highlight.html(
self.highlight.html()
.replace(\"@\" + self.searchTerm,$(\"<div>\").append(
self.highlightWrapper
.text(ui.item.label)
.clone()
).html()+\' \')
);
self.meta.val((self.meta.val() + \" @[\" + ui.item.value + \":]\").trim());
return false;
}
});
}
});
body,html {
font-family: \"lucida grande\",tahoma,verdana,arial,sans-serif;
}
.ui-tagging {
position: relative;
border: 1px solid #B4BBCD;
height: auto;
}
.ui-tagging .ui-tagging-highlight {
position: absolute;
padding: 5px;
overflow: hidden;
}
.ui-tagging .ui-tagging-highlight div {
color: transparent;
font-size: 13px;
line-height: 18px;
white-space: pre-wrap;
}
.ui-tagging .ui-tagging-wrap {
position: relative;
padding: 5px;
overflow: hidden;
zoom: 1;
border: 0;
}
.ui-tagging div > span {
background-color: #D8DFEA;
font-weight: normal !important;
}
.ui-tagging textarea {
display: block;
font-family: \"lucida grande\",sans-serif;
background: transparent;
border-width: 0;
font-size: 13px;
height: 18px;
outline: none;
resize: none;
vertical-align: top;
width: 100%;
line-height: 18px;
overflow: hidden;
}
.ui-autocomplete {
font-size: 13px;
background-color: white;
border: 1px solid black;
margin-bottom: -5px;
width: 0;
}
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></script>
<textarea></textarea>
, 为此,我创建了一个Meteor程序包。流星的数据模型允许使用自定义呈现列表快速进行多规则搜索。如果您不打算将Meteor用于您的Web应用程序,那么(我相信)您将不会找到任何如此出色的自动完成功能。
使用“ 0”自动填充用户,其中在线用户以绿色显示:
在同一行中,使用元数据和引导程序图标自动完成其他操作:
叉,拉和改善:
https://github.com/mizzao/meteor-autocomplete
, 我找不到任何完全符合我的要求的解决方案,因此得到了以下结果:
我使用jQuerykeypress()
事件检查用户是否按@
字符。
在这种情况下,将使用jQuery UI显示模式对话框。此对话框包含一个自动完成文本字段(此处可以使用许多选项,但我建议使用jQuery Tokeninput)
当用户在对话框中选择一个选项时,会将标签添加到文本字段,然后关闭对话框。
这不是最优雅的解决方案,但它可以工作,并且与我的原始设计相比,不需要额外的按键。
编辑
因此,基本上,我们有了我们的大文本框,用户可以在其中输入文本。他应该能够“标记”用户(这仅意味着在文本中插入“ 7”)。我附加到jQuery keyup事件,并使用(e.which == 64)
检测@
字符以显示带有文本字段的模式,以选择要标记的用户。
解决方案的实质就是带有jQuery Tokeninput文本框的模式对话框。当用户在此处键入时,将通过AJAX加载用户列表。有关如何正确使用它,请参见网站上的示例。当用户关闭对话框时,我将选定的ID插入大文本框中。
, 最近,我不得不面对这个问题,这就是我确定的问题...
通过使用selectionStart获取文本区域中光标位置的字符串索引
将字符串从索引0切到光标位置
将其插入跨度(因为跨度具有多个边框)
使用element.getClientRects()相对于视口获取边框的尺寸。 (这是MDN参考)
计算顶部和左侧并将其馈入下拉菜单
在所有最新的浏览器中都可以使用。没有测试过旧的
这是工作箱
, 另一个提供类似功能的插件:
自动建议
您可以将其与自定义触发器一起使用,也可以将其与任何触发器一起使用。与输入字段,文本区域和contenteditables一起使用。 jQuery不是依赖项。
, 这个小扩展似乎至少在外观上与要求的最接近。由于它很小,因此很容易理解和修改。 http://lookapanda.github.io/jquery-hashtags/
, 这应该工作。关于@开始搜索,只需在每个可能的搜索词的开头添加(动态地或不动态地)符号即可。