蓝森林首页 | 返回主页 | 本站地图 | 站内搜索 | 联系信箱 |
 您目前的位置:首页 > 自由软件 > 技术交流 > 应用编程


    

蓝森林 http://www.lslnet.com 2006年8月25日 8:28

[ 转 ]模仿IE自动完成功能,支持Firefox.支持方向键操作

在csdn发了一下,想了一下,在经典也发,不然对不起这边的兄弟,喜欢就顶一下贴。
[html]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
body,div {
        font-family:verdana;
        line-height:100%;
        font-size:9pt;
}
input {
        width:300px;
}
h1 {
        text-align:center;
        font-size:2.2em;
}
#divf {
        margin:10px;
        font-size:0.8em;
        text-align:center;
}
#divc {
        border:1px solid #333333;
}
.des {
        width:500px;
        background-color:lightyellow;
        border:1px solid #333;
        padding:20px;
        margin-top:20px;
}
.mouseover {
        color:#ffffff;
        background-color:highlight;
        width:100%;
        cursor:default;
}
.mouseout {
        color:#000000;
        width:100%;
        background-color:#ffffff;
        cursor:default;
}
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--

// script by blueDestiny
// email : blueDestiny [at] 126 . com

// Object: jsAuto
// browser: ie, mf.
// example:

// step1 :
// create autocomplete container, return object and bind event to the object, and
///create a new jsAuto instance:
// <div id="divautocomplete"></div>
// var autocomplete = new jsAuto("autocomplete","divautocomplete")
// handle event:
// autocomplete.handleEvent(value, returnObjectID)
// <input id="rautocomplete" onkeyup="autocomplete.handleEvent(this.value,"ratocomplete",event)>

// step2 :
// add autocompete item:
// autocomplete.item(string)
// string must be a string var, you can split the string by ","
// autocomplete.item("blueDestiny,never-online,csdn,blueidea")

// http://www.never-online.com

function jsAuto(instanceName,objID)
{
        this._msg = [];
        this._x = null;
        this._o = document.getElementById( objID );
        if (!this._o) return;
        this._f = null;
        this._i = instanceName;
        this._r = null;
        this._c = 0;
        this._s = false;
        this._v = null;
        this._o.style.visibility = "hidden";
        this._o.style.position = "absolute";
        this._o.style.zIndex = "9999";
        return this;
};

jsAuto.prototype.directionKey=function() { with (this)
{
        var e = _e.keyCode ? _e.keyCode : _e.which;
        var l = _o.childNodes.length;
        (_c>l-1 || _c<0) ? _s=false : "";

        if( e==40 && _s )
        {
                _o.childNodes[_c].className="mouseout";
                (_c >= l-1) ? _c=0 : _c ++;
                _o.childNodes[_c].className="mouseover";
        }
        if( e==38 && _s )
        {
                _o.childNodes[_c].className="mouseout";
                _c--<=0 ? _c = _o.childNodes.length-1 : "";
                _o.childNodes[_c].className="mouseover";
        }
        if( e==13 )
        {
                if(_o.childNodes[_c] && _o.style.visibility=="visible")
                {
                        _r.value = _x[_c];
                        _o.style.visibility = "hidden";
                }
        }
        if( !_s )
        {
                _c = 0;
                _o.childNodes[_c].className="mouseover";
                _s = true;
        }
}};

// mouseEvent.
jsAuto.prototype.domouseover=function(obj) { with (this)
{
        _o.childNodes[_c].className = "mouseout";
        _c = 0;
        obj.tagName=="DIV" ? obj.className="mouseover" : obj.parentElement.className="mouseover";
}};
jsAuto.prototype.domouseout=function(obj)
{
        obj.tagName=="DIV" ? obj.className="mouseout" : obj.parentElement.className="mouseout";
};
jsAuto.prototype.doclick=function(msg) { with (this)
{
        if(_r)
        {
                _r.value = msg;
                _o.style.visibility = "hidden";
        }
        else
        {
                alert("javascript autocomplete ERROR :\n\n can not get return object.");
                return;
        }
}};

// object method;
jsAuto.prototype.item=function(msg)
{
        if( msg.indexOf(",")>0 )
        {
                var arrMsg=msg.split(",");
                for(var i=0; i<arrMsg.length; i++)
                {
                        arrMsg[i] ? this._msg.push(arrMsg[i]) : "";
                }
        }
        else
        {
                this._msg.push(msg);
        }
        this._msg.sort();
};
jsAuto.prototype.append=function(msg) { with (this)
{
        _i ? "" : _i = eval(_i);
        _x.push(msg);
        var div = document.createElement("DIV");

        //bind event to object.
        div.onmouseover = function(){_i.domouseover(this)};
        div.onmouseout = function(){_i.domouseout(this)};
        div.onclick = function(){_i.doclick(msg)};
        var re  = new RegExp("(" + _v + ")","i");
        div.style.lineHeight="140%";
        div.className = "mouseout";
        if (_v) div.innerHTML = msg.replace(re , "<strong>$1</strong>");
        div.style.fontFamily = "verdana";

        _o.appendChild(div);
}};
jsAuto.prototype.display=function() { with(this)
{
        if(_f&&_v!="")
        {
                _o.style.left = _r.offsetLeft;
                _o.style.width = _r.offsetWidth;
                _o.style.top = _r.offsetTop + _r.offsetHeight;
                _o.style.visibility = "visible";
        }
        else
        {
                _o.style.visibility="hidden";
        }
}};
jsAuto.prototype.handleEvent=function(fValue,fID,event) { with (this)
{
        var re;
        _e = event;
        var e = _e.keyCode ? _e.keyCode : _e.which;
        _x = [];
        _f = false;
        _r = document.getElementById( fID );
        _v = fValue;
        _i = eval(_i);
        re = new RegExp("^" + fValue + "", "i");
        _o.innerHTML="";

        for(var i=0; i<_msg.length; i++)
        {
                if(re.test(_msg[i]))
                {
                        _i.append(_msg[i]);
                        _f = true;
                }
        }

        _i ? _i.display() : alert("can not get instance");

        if(_f)
        {
                if((e==38 || e==40 || e==13))
                {
                        _i.directionKey();
                }
                else
                {
                        _c=0;
                        _o.childNodes[_c].className = "mouseover";
                        _s=true;
                }
        }
}};
window.onerror=new Function("return true;");
//-->
</SCRIPT>
</HEAD>

<BODY>
<div id="divc">
        <!--this is the autocomplete container.-->
</div>
<h1>Autocomplete Function</h1>
<div align="center">
<input onkeyup="jsAutoInstance.handleEvent(this.value,'auto',event)" id="auto">
</div>
<div id="divf">
        Power By Miracle, never-online
</div>

<SCRIPT LANGUAGE="JavaScript">
<!--
var jsAutoInstance = new jsAuto("jsAutoInstance","divc");
jsAutoInstance.item("a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start");
jsAutoInstance.item("blueDestiny");
jsAutoInstance.item("BlueMiracle,Blue");
jsAutoInstance.item("angela,geniuslau");
jsAutoInstance.item("never-online");
//-->
</SCRIPT>
</BODY>
</HTML>
[/html]

[ 转 ]模仿IE自动完成功能,支持Firefox.

漂亮,代码也漂亮~


有个小小不足,鼠标移过的效果最好是整行

[ 转 ]模仿IE自动完成功能,支持Firefox.

嘿嘿,子乌,每次第一个来的总是你老人家呀

[ 转 ]模仿IE自动完成功能,支持Firefox.

晕。。。老人家。。。。偶虽然上了一点点岁数,不过偶还年轻,偶还有点力气能追上你们年轻人。。。偶还不到30。。。:o


附三篇提示的textbox教程,计划翻译中(嘿嘿,实际上只是计划自己学习而已):

http://www.webreference.com/programming/javascript/ncz/index.html
http://www.webreference.com/programming/javascript/ncz/column2/index.html
http://www.webreference.com/programming/javascript/ncz/column3/

[ 转 ]模仿IE自动完成功能,支持Firefox.

我最近也在翻译一些关于ajax的文章,最近的对脚本的想法也比较多,所以写的js代码也比较多,上次说的那个静态文章分页的一些想法,现在也列入计划中。

PS: 估计你岁数比我大些,:)

[ 转 ]模仿IE自动完成功能,支持Firefox.

子乌,你现在再看看,有没有那个效果了,接下来就是把小键盘的功能实现了。

[ 转 ]模仿IE自动完成功能,支持Firefox.

呵呵,不错!!

顺便再把方向键的功能也加上吧:D

类似ie的自动完成,使用上下键选择

[ 转 ]模仿IE自动完成功能,支持Firefox.

你这里也是用图层实现的啊!呵呵

[ 转 ]模仿IE自动完成功能,支持Firefox.

好东西,我来琢磨琢磨~```

[ 转 ]模仿IE自动完成功能,支持Firefox.

子乌,方向键也可以用了,看看吧:)

[ 转 ]模仿IE自动完成功能,支持Firefox.

嘿嘿,我是不是太挑了点?

上下键,到底或到顶,最好能够循环到另外一头去,明白我意思吗?当你的列表特别长的时候,这个很有用。

还有,当什么都没输入的时候,点击上下键就跳出提示框是否合适?因为用户不一定知道哪些值是已经存在的。

[ 转 ]模仿IE自动完成功能,支持Firefox.

郁闷!

越来越强了!

我喜欢!支持转!

UP!

晕。。。真挑呀,好!满足大家的愿望啦:)

改进了一下,可以用方向键上下移动,并且,如果在第一个节点里按向上键,即到最后一个元素,最后一个元素按下键,到首元素;

晕~,有bug,要等会再能弄好了,现在忙了,呵呵

改进了方向键了。应该没有bug了吧

最好可以按住方向键不放的时候连续上下移动

呵呵,继续挑~

a、内容为空时上下键无效
b、内容为空时直接回车怎么会冒一个Blue出来?

呵呵,我是试图站在用户的角度上挑刺,这种东西是最贴近用户的,用户体验很重要。:D

bug report
1.用鼠标选择自动完成的选项后,text的焦点消失(直接用回车选择正常)
2.在text中任意输入,再清空text,页面会平白无故出现滚动条

建议
1.在自动完成中的可选项过多的情况下,能否考虑给层做个滚动条,而不去滚动页面

b、内容为空时直接回车怎么会冒一个Blue出来?

这个我这里怎么没有?内容为空,Tips应该自动隐藏了呀~

关于 a、内容为空时上下键无效

这个我还在考虑是弹出来好呢,还是不弹出来好~

你试试,正常的流程应该是:

1 我输入B
2 显示B开头的列表
3 我输入回车,高亮那行的字符串输入到文本框中


但现在为空的时候,我直接敲回车,就会插入Blue。不知道别人是否会出现这个情况。

嘿嘿,那几篇文章翻译完之后我打算把你的这些改进也加进去,作为补充:D

我也遇到了Blue的情况,
还有个bug报告:
在text中输入后,自动完成显示出来,这时我如果鼠标在页面的其他位置点击的话,自动完成的层就应该隐藏掉.和ie一样

还请问楼主,jsAutoInstance.item()里边的内容可不可以从ajax数据传递过来,我试了怎么不行
我想做一个搜索,比如先输入一个"重庆",ajax程序从后台取出所有相关项,我想他怎么赋值给jsAutoInstance.item

楼主以及子乌大哥觉得好的话,不妨把ajax加进去,那我觉得就完美了,因为楼主的程序实在很漂亮适用

http://bbs.blueidea.com/viewthread.php?tid=2458951
支持汉字。。 ajax

to javapigpig:
楼主的例子也支持中文哦,至于ajax,可以看看老孤的代码:

http://bbs.blueidea.com/viewthread.php?tid=2383914


to lianfang:

ajax现在的泛滥(原谅我用这种比较贬义的词,个人看法而已,不代表:D)让人有点不知所措,技术的运用要恰当,要得体,而不该象现在这样一窝蜂。

每种技术有每种技术擅长的地方,该用则用,没必要用,就不用。适度,这个度很难把握。

@子乌,
你说的那个问题加个判断就好了,:)现在改好了。接下来的问题个人觉得就是在大数据量下,要给Tips加个滚动条。以及优化的问题了,在大数据量的情况下,我觉得在输入框没有值的情况下,就没有必要给出全部数据的Tips了。


@lianfang,你所说的Ajax情况实际上在用在这上面个人感觉就没有必要了,如果你实在要加的话,完全可以这样的

var s=null;
s = ajax.handleSend(paremeter);
jsAutoInstance.item(s);

bug report
1.自动完成列表不支持一直按住上下键连续滚动

@lianfang

这个不是bug,而是fire Event的时候触发的,现在设置的是onkeyup,你设置为onkeydown即可

请问楼主,tips加滚动条怎么加啊?

ok,已搞定添加滚动条功能
[html]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
body,div {
        font-family:verdana;
        line-height:100%;
        font-size:9pt;
}
input {
        width:300px;
}
h1 {
        text-align:center;
        font-size:2.2em;
}
#divf {
        margin:10px;
        font-size:0.8em;
        text-align:center;
}
#divc {
        border:1px solid #333333;
}
.des {
        width:500px;
        background-color:lightyellow;
        border:1px solid #333;
        padding:20px;
        margin-top:20px;
}
.mouseover {
        color:#ffffff;
        background-color:highlight;
        width:100%;
        cursor:default;
}
.mouseout {
        color:#000000;
        width:100%;
        background-color:#ffffff;
        cursor:default;
}
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--

// script by blueDestiny
// email : blueDestiny [at] 126 . com

// Object: jsAuto
// browser: ie, mf.
// example:

// step1 :
// create autocomplete container, return object and bind event to the object, and
///create a new jsAuto instance:
// <div id="divautocomplete"></div>
// var autocomplete = new jsAuto("autocomplete","divautocomplete")
// handle event:
// autocomplete.handleEvent(value, returnObjectID)
// <input id="rautocomplete" onkeyup="autocomplete.handleEvent(this.value,"ratocomplete",event)>

// step2 :
// add autocompete item:
// autocomplete.item(string)
// string must be a string var, you can split the string by ","
// autocomplete.item("blueDestiny,never-online,csdn,blueidea")

// http://www.never-online.com

function jsAuto(instanceName,objID)
{
        this._msg = [];
        this._x = null;
        this._o = document.getElementById( objID );
        if (!this._o) return;
        this._f = null;
        this._i = instanceName;
        this._r = null;
        this._c = 0;
        this._s = false;
        this._v = null;
        this._o.style.visibility = "hidden";
        this._o.style.position = "absolute";
        this._o.style.zIndex = "9999";
this._o.style.overflow = "auto";
this._o.style.height = "50";
        return this;
};

jsAuto.prototype.directionKey=function() { with (this)
{
        var e = _e.keyCode ? _e.keyCode : _e.which;
        var l = _o.childNodes.length;
        (_c>l-1 || _c<0) ? _s=false : "";

        if( e==40 && _s )
        {
                _o.childNodes[_c].className="mouseout";
                (_c >= l-1) ? _c=0 : _c ++;
                _o.childNodes[_c].className="mouseover";
        }
        if( e==38 && _s )
        {
                _o.childNodes[_c].className="mouseout";
                _c--<=0 ? _c = _o.childNodes.length-1 : "";
                _o.childNodes[_c].className="mouseover";
        }
        if( e==13 )
        {
                if(_o.childNodes[_c] && _o.style.visibility=="visible")
                {
                        _r.value = _x[_c];
                        _o.style.visibility = "hidden";
                }
        }
        if( !_s )
        {
                _c = 0;
                _o.childNodes[_c].className="mouseover";
                _s = true;
        }
}};

// mouseEvent.
jsAuto.prototype.domouseover=function(obj) { with (this)
{
        _o.childNodes[_c].className = "mouseout";
        _c = 0;
        obj.tagName=="DIV" ? obj.className="mouseover" : obj.parentElement.className="mouseover";
}};
jsAuto.prototype.domouseout=function(obj)
{
        obj.tagName=="DIV" ? obj.className="mouseout" : obj.parentElement.className="mouseout";
};
jsAuto.prototype.doclick=function(msg) { with (this)
{
        if(_r)
        {
                _r.value = msg;
                _o.style.visibility = "hidden";
        }
        else
        {
                alert("javascript autocomplete ERROR :\n\n can not get return object.");
                return;
        }
}};

// object method;
jsAuto.prototype.item=function(msg)
{
        if( msg.indexOf(",")>0 )
        {
                var arrMsg=msg.split(",");
                for(var i=0; i<arrMsg.length; i++)
                {
                        arrMsg[i] ? this._msg.push(arrMsg[i]) : "";
                }
        }
        else
        {
                this._msg.push(msg);
        }
        this._msg.sort();
};
jsAuto.prototype.append=function(msg) { with (this)
{
        _i ? "" : _i = eval(_i);
        _x.push(msg);
        var div = document.createElement("DIV");

        //bind event to object.
        div.onmouseover = function(){_i.domouseover(this)};
        div.onmouseout = function(){_i.domouseout(this)};
        div.onclick = function(){_i.doclick(msg)};
        var re  = new RegExp("(" + _v + ")","i");
        div.style.lineHeight="140%";
        div.className = "mouseout";
        if (_v) div.innerHTML = msg.replace(re , "<strong>$1</strong>");
        div.style.fontFamily = "verdana";

        _o.appendChild(div);
}};
jsAuto.prototype.display=function() { with(this)
{
        if(_f&&_v!="")
        {
                _o.style.left = _r.offsetLeft;
                _o.style.width = _r.offsetWidth;
                _o.style.top = _r.offsetTop + _r.offsetHeight;
                _o.style.visibility = "visible";
        }
        else
        {
                _o.style.visibility="hidden";
        }
}};
jsAuto.prototype.handleEvent=function(fValue,fID,event) { with (this)
{
        var re;
        _e = event;
        var e = _e.keyCode ? _e.keyCode : _e.which;
        _x = [];
        _f = false;
        _r = document.getElementById( fID );
        _v = fValue;
        _i = eval(_i);
        re = new RegExp("^" + fValue + "", "i");
        _o.innerHTML="";

        for(var i=0; i<_msg.length; i++)
        {
                if(re.test(_msg[i]))
                {
                        _i.append(_msg[i]);
                        _f = true;
                }
        }

        _i ? _i.display() : alert("can not get instance");

        if(_f)
        {
                if((e==38 || e==40 || e==13))
                {
                        _i.directionKey();
                }
                else
                {
                        _c=0;
                        _o.childNodes[_c].className = "mouseover";
                        _s=true;
                }
        }
}};
window.onerror=new Function("return true;");
//-->
</SCRIPT>
</HEAD>

<BODY>
<div id="divc">
        <!--this is the autocomplete container.-->
</div>
<h1>Autocomplete Function</h1>
<div align="center">
<input onkeyup="jsAutoInstance.handleEvent(this.value,'auto',event)" id="auto">
</div>
<div id="divf">
        Power By Miracle, never-online
</div>

<SCRIPT LANGUAGE="JavaScript">
<!--
var jsAutoInstance = new jsAuto("jsAutoInstance","divc");
jsAutoInstance.item("a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start,a-start,b-start,c-start,d-start,e-start,f-start,g-start,h-start,i-start,j-start,k-start,l-start,m-start,n-start,o-start,p-start,q-start,r-start,s-start,t-start,u-start,v-start,w-start,x-start,y-start,z-start,z-start");
jsAutoInstance.item("blueDestiny");
jsAutoInstance.item("BlueMiracle,Blue");
jsAutoInstance.item("angela,geniuslau");
jsAutoInstance.item("never-online");
//-->
</SCRIPT>
</BODY>
</HTML>
[/html]

继续挑:
我就只想要a。
输入a,自动完成的框出现有两个选择,鼠标点击其他地方(焦点转移),自动完成的框不会自动消失,这是不对的,因为我的输入已经完成了(试试IE,是正确的)。
相信修改是比较容易的,只要失去焦点将完成框“关闭”就行了。我的JS较弱,还忘作者继续完善它。




Copyright © 1999-2000 LSLNET.COM. All rights reserved. 蓝森林网站 版权所有。 E-mail : webmaster@lslnet.com