UPDATE
在@Ziv Weissman和@Fribu的帮助和建议下,我重新编写了整个自动完成功能.
如果有人需要,他/她可以从here下载.
感谢StackOverFlow社区.
我正在创建一个jquery自动完成功能.我创建的功能与单个文本框一起正常工作.但是,只要我在同一页面的另一个文本框中实现它,它就会出现意外行为.它会打开和关闭自动完成列表.
这是我的autofill.js代码:
function setUl(result) { var $ul = $('<ul>'); if (result !== undefined) { $.each(result,function (k,v) { $ul.append('<li data-value="' + v.value + '">' + v.label + '</li>'); }); } return $ul; } $.fn.autofill = function (options) { if (options == undefined) { options = {}; } var $currentInput = $(this); var autoCompleteData = $currentInput.data('autofill'); var listId='autofill-' + (new Date().getTime()).toString(16); $currentInput.on('keyup focus',function (e) { var query = $(this).val(); var result = $.grep(autoCompleteData,function (v) { return v.label.search(new RegExp(query,'i')) !== -1; }); $ul = setUl(result,$currentInput); $ul.attr('id',listId); $ul.addClass('autofill-show'); $ul.attr('data-target',$currentInput.attr('id')); var position = $currentInput.position(); $ul.css({ width: $currentInput.width() + parseInt($currentInput.css('padding-left'),10) + parseInt($currentInput.css('padding-right'),10),position: 'absolute',top: position.top + $currentInput.outerHeight(),left: position.left }); if ($ul.find('li').length >= 6) { $ul.css({ height: '130px','overflow-y': 'scroll' }); } if (result !== undefined) { if ($(e.target).attr('id') !== $currentInput.attr('id') && $($(e.target).parent()[0]).attr('id') !== listId) { destroy($ul); } $currentInput.after($ul); } $currentInput.trigger('onChange',[query,result]); }); $(document).on('click','.autofill-show li',function (e) { if($ul!==undefined && $($(this).parent()[0]).attr('id')==$ul.attr('id')){ $ul.trigger('onSelect',[$(this).text(),$(this).data('value')]); } e.stopImmediatePropagation(); }); $(document).on('onSelect','#'+listId,function (e,label,value) { $currentInput.val(label); if ($.isFunction(options.onSelect)) { options.onSelect(label,value); } if ($(e.target).attr('id') !== $currentInput.attr('id') && $($(e.target).parent()[0]).attr('id') !== listId) { destroy($ul); } e.stopImmediatePropagation(); }); $(document).on('onChange','#'+$currentInput.attr('id'),query,result) { if($ul!==undefined && $($(this).parent()[0]).attr('id')==$ul.attr('id')) { result = $.grep(autoCompleteData,function (v) { return v.label.search(new RegExp('\^' + query + '\$',"gi")) !== -1; }); if ($.isFunction(options.onChange)) { options.onChange(query,result[0]); } } e.stopImmediatePropagation(); }); $(document).on('click',function (e) { console.log($(e.target)); if ($(e.target).attr('id') !== $currentInput.attr('id') && $($(e.target).parent()[0]).attr('id') !== listId) { destroy($ul); } e.stopImmediatePropagation(); }); }; function destroy($ul) { $ul.remove(); }
这是我的css:
.autofill-show{ list-style: outside none none; padding: 0; border: 1px solid #ccc; margin:0; z-index: 9999999; } .autofill-show li{ border: 1px solid #ccc; text-align: center; background: #fff; } .autofill-show li:hover{ background: #9bcea3; cursor: pointer; }
$('#autofill').autofill(); $('#autofill_2').autofill();
解决方法
正如我所提及的,以及其他人的帮助,这是您的活动和选择器的问题.
一种解决方案可以是为创建的UL添加唯一ID,而不是“基于日期时间”.
每次您将破坏特定ID,并重新创建它.
事件将通过HTML(添加onclick = …)触发,并使用jQUERY以当前/父级别进行触发.
我已经更新了这个fiddle
它可能有你的小提琴剩下的东西,我没有时间去完善……我会留给你.
解决方案看起来像这样:
function setUl(result) { var $ul = $('<ul>'); if (result !== undefined) { $.each(result,v) { $ul.append('<li data-value="' + v.value + '" onclick="clickHandle(this)">' + v.label + '</li>'); }); } return $ul; } function clickHandle(ele){ var label = $(ele).text(); var value = $(ele).data('value'); var inputId = $(ele).parent("ul").attr("data-target"); $('#'+inputId).val(label); if ($.isFunction(options.onSelect)) { options.onSelect(label,value); } } $.fn.autofill = function (options) { if (options == undefined) { options = {}; } var $currentInput = $(this); console.log($($currentInput).attr('id')); var autoCompleteData = $currentInput.data('autofill'); var listId='autofill_' + $currentInput.attr('id'); $currentInput.on('keyup focus','i')) !== -1; }); if($('#'+listId)){ $('#'+listId).remove(); } $ul = setUl(result,'overflow-y': 'scroll' }); } if (result !== undefined) { destroy($ul); $currentInput.after($ul); } $currentInput.trigger('onChange',result]); }); //end key up $('#'+listId).on('onSelect',value); } destroy($ul); e.stopImmediatePropagation(); }); $(document).on('onChange',result[0]); } } e.stopImmediatePropagation(); }); $currentInput.on('blur',function (e) { window.setTimeout(function(){ destroy($ul); },100); }); }; function destroy($ul) { $ul.remove(); }