完全对比着Gmail的那个输入框来实现功能的,赶紧抢
输入时按,或<Enter>或<Tab>即可自动完成
使用示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>waiting tip</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="autoComplete.js"></script>
<script>
function bodyload(){
var friends = ["james","john", "robert", "michael","juan"];
var mailTo = document.getElementById("mailTo");
var panel = document.getElementById("friendlist");
var autoInput = new AutoInput(mailTo,panel,friends);
}
window.onload = bodyload;
</script>
<body>
<input id="mailTo" type="text" style="width:300px" />
<select id="friendlist" multiple="true" style="width:300px;display:none;" ></select>
</body>
</html>
运行效果
源码
/**
* 输入自动完成,类GMail中发送到输入框
* @param {HTML Element} inputControl
* @param {HTML Element} displayPanel
* @param {Array} queryData
*/
function AutoInput(inputControl,displayPanel,queryData){
var Browser = {
IE: !!(window.attachEvent && !window.opera),
Opera: !!window.opera,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
}
var stopEvent = function(event){
if(Browser.IE){
try{
event.cancelBubble = true;
event.returnValue = false;
}
catch(e){
alert(e);
}
}else{
try{
event.preventDefault();
event.stopPropagation();
}
catch(e){
alert(e);
}
}
}
var strip = function(string) {
return string.replace(/^\s+/, '').replace(/\s+$/, '');
}
var inputControl = inputControl; //输入控件(input text或text area)
var displayPanel = displayPanel; //结果显示面板
var data = queryData; //搜索数据源
var results = []; //搜索结果
var lastSearchText = ""; //最后一次搜索的关键字
var isLastPosition = function(){
return true;
}
//是否存在搜索结果
var hasResults = function (){
return results.length > 0
}
//自动完成单词
var autoComplete = function(){
var _value = inputControl.value;
var _searchText = _value;
var _lastPos = _value.lastIndexOf(',');
if(_lastPos!=-1){
inputControl.value = _value.substr(0, _lastPos + 1) + '"' + getSelectedText() + '"' +',';
}else{
inputControl.value = '"'+getSelectedText() + '"' + ',';
}
clearResults();
inputControl.focus();
}
//使输入框得到焦点(在结果显示面板中键入字符时发生)
var focusInputControl = function(keycode){
var _char = String.fromCharCode(keycode).toLowerCase();
inputControl.value += _char;
clearResults();
inputControl.focus();
}
//获取选中的文本
var getSelectedText = function (){
return displayPanel.options[displayPanel.selectedIndex].text;
}
//搜索数组--!!!在这里改搜索算法
var searchArray = function(searchData,searchText){
var _results = [];
for(var i=0,l=searchData.length;i<l;i++){
var regExp = new RegExp("^"+searchText,"i"); //i选项,忽略大小写
if(searchData[i].match(regExp)){
_results.push(searchData[i]);
}
}
return _results;
}
//获取要作为搜索关键字的部分
var getSearchText = function(){
var _value = inputControl.value;
var _searchText = _value;
var _pos = _value.lastIndexOf(',');
if(_pos!=-1){
_searchText = _value.substr(_pos+1);
}
return _searchText;
}
//搜索并处理结果
var search = function (){
//获取搜索关键字
var _keyword = getSearchText();
if(strip(_keyword)==""){
clearResults();
return;
}
//搜索
if(hasResults() && _keyword.indexOf(lastSearchText)==0){
results = searchArray(results,_keyword);
}else{
results = searchArray(data,_keyword);
}
lastSearchText = _keyword;
//处理搜索结果
if (hasResults()) {
showResult(results);
}
else{
clearResults();
}
}
//获取某个html元素的绝对位置
var GetAbsoluteLocation = function (element)
{
if ( arguments.length != 1 || element == null )
{
return null;
}
var offsetTop = element.offsetTop;
var offsetLeft = element.offsetLeft;
var offsetWidth = element.offsetWidth;
var offsetHeight = element.offsetHeight;
while( element = element.offsetParent )
{
offsetTop += element.offsetTop;
offsetLeft += element.offsetLeft;
}
return { absoluteTop: offsetTop, absoluteLeft: offsetLeft,
offsetWidth: offsetWidth, offsetHeight: offsetHeight };
}
//重设结果显示面板的位置
var resetPositoin = function(){
var position = GetAbsoluteLocation(inputControl);
displayPanel.style.position = "absolute";
displayPanel.style.top = position.absoluteTop + position.offsetHeight + 5 + 'px';
displayPanel.style.left = position.absoluteLeft + 'px';
}
//显示搜索结果,清空结果面板
if (Browser.IE) {
var showResult = function(searchResults){
clearOptions();
for (var i = 0; i < searchResults.length; i++) {
var text = searchResults[i];
displayPanel.options.add(new Option(text, text));
}
resetPositoin();
displayPanel.style.display = "block";
displayPanel.options[0].selected = true;
}
var clearOptions = function(){
for(var i=0,l=displayPanel.options.length;i<l;i++){
displayPanel.options.remove(0);
}
}
}
else {
var showResult = function(searchResults){
var _htmls = "<option>" + searchResults.join("</option><option>") + "</option>";
displayPanel.innerHTML = _htmls;
resetPositoin();
displayPanel.style.display = "block";
displayPanel.options[0].selected = true;
}
var clearOptions = function(){
displayPanel.innerHTML = "";
}
}
var clearResults = function(){
clearOptions();
displayPanel.style.display = "none";
results = [];
}
//处理显示面板keydown
if (Browser.Opera) {
var resultsPanel_keydown = function(event){
if (!hasResults())
return;
var displayPanel = event.srcElement;
var _key = event.keyCode;
if (_key == 188 || _key == 13 || _key == 9) { // , enter tab
autoComplete();
stopEvent(event);
}
else
if (_key == 38) { //up
var index = displayPanel.selectedIndex + 0;
var newIndex = index - 1;
if (index > 0) {
displayPanel.options[index].selected = false;
displayPanel.options[newIndex].selected = true;
}
}
else
if (_key == 40) { //down
var index = displayPanel.selectedIndex + 0;
if (index < displayPanel.options.length - 1) {
var newIndex = index + 1;
displayPanel.options[index].selected = false;
displayPanel.options[newIndex].selected = true;
}
}
else {
focusInputControl(_key);
}
}
}
else {
var resultsPanel_keydown = function(event){
if (!hasResults())
return;
var _key = event.keyCode;
if (_key == 188 || _key == 13 || _key == 9) { // , enter tab
autoComplete();
stopEvent(event);
}
else
if (_key != 38 && _key != 40) {
focusInputControl(_key);
}
}
}
//处理显示面板按下tab键
function resultsPanel_tabdown(event){
var _key = event.keyCode;
if (_key == 9) { //tab
autoComplete();
stopEvent(event); //opera未能停止事件
}
}
//处理输入控件按下tab键
function inputControl_tabdown(event){
var _key = event.keyCode;
if (_key == 9) { //tab
if(hasResults()){
autoComplete();
stopEvent(event); //opera未能停止事件
}
}
}
//处理输入控件keydown
function inputControl_keydown(event){
if(!isLastPosition())return
var _key = event.keyCode;
if(_key==188 || _key==13){ // 按下: 1:, 2:enter 时自动完成
if (hasResults()) {
stopEvent(event);
if(_key==188){
var _value = inputControl.value;
inputControl.value = _value.substr(0,_value.length-1);
}
autoComplete();
}
}
else if(_key==40) // 按下: down(向下箭头)时聚焦到面板显示框,如果存在搜索结果的话
{
if (hasResults()) {
displayPanel.focus();
if(displayPanel.options[1]){
displayPanel.options[0].selected = false;
displayPanel.options[1].selected = true;
}
stopEvent(event);
}
}
else{ //按下: 其他键
search();
}
}
//绑定事件
var addEventListener = function(element, type, handler,stopEvent){
if (element.addEventListener) {
if (stopEvent) {
element.addEventListener(type, handler, true);
}else{
element.addEventListener(type, handler, false);
}
}
else { //ie
if (stopEvent) {
element.attachEvent("on" + type, function(event){
handler(event);
event.cancelBubble = true;
});
}else{
element.attachEvent("on" + type, handler);
}
}
}
addEventListener(inputControl, "keyup", inputControl_keydown);
addEventListener(inputControl, "keydown", inputControl_tabdown);
addEventListener(displayPanel, "keyup", resultsPanel_keydown);
addEventListener(displayPanel, "click", autoComplete);
addEventListener(displayPanel, "keydown", resultsPanel_tabdown);
}