javascrip 中 onkeyup 事件在输入法情况下不稳定的山寨解决方案【有代码】

 

    E8前一次版本升级提供了拼音智能快速输入的控件,但客户发现了一个不太好用的地方,中文输入法进行中文输入的时候 onkeyup事件不稳定,很多时候取不到,网上一查,这个问题还是一个普遍存在的问题。

   在IE中触发keydown和keyup, 不触发keypress
输入值能够获得,但不稳定。有时候会延后
   在Firefox:触发keydown和keypress, 不触发keyup
输入值未能获得 [Enter]后会触发keyup, 可获得输入值
   在Opera中keydown, keypress和keyup都不触发,输入值也未能获得
[Enter]后,在opera 9.24中会触发keydown和keypress
输入过程中,Space和enter会触发三者

   对于一个控件需要适合在各种环境上运行的,既然存在这样的一些区别,因此实现方式应该更加巧妙一些,这个问题一直困扰了好几天,后来在网上有人推荐了google的脚本文件http://www.google.cn/ac.js 虽然脚本做了干扰处理,但还是能看出它的一些思路,由于控件还有其它功能需求,不能直接照搬这个脚本文件,于是想到了一个山寨的解决方案。(感觉还是没有google流畅,但比以前的版本好很多了)

    主要思路是:

        不用onkeyup事件,改为 在 onfocus 时设置 setInterval 自动处理的机制判断是否有新的输入值, onblur时通过 clearInterval(oTimer) 方法取消自动处理。

     用到的技术点有几个

       1、用匿名函数的方法为 setInterval  传递参数,注意对象的直接传入会有问题,先传入控件的ID,找到后再传递给匿名方法

       2、如果发现有不同的输入值的时候,利用XMLHTTP获取列表

       3、缓存已经获得过的列表,减少后台操作

       4、用动态的div 和 select 动态展示列表

       5、利用键盘事件选择对应的值

       6、处理特定场景下的特定键值,防止浏览器发生不意愿的动作

      

      主要的技术点是以上几点,写脚本是个细致活,再有什么问题再继续完善了。

       脚本文件如下: 希望能给到大家参考

      

// 应用开发的基础脚本函数:获取下拉列表快速输入,2008-04-16 苏  2009-02-09 孔修改
     var  xmlDroplst  =   new  ActiveXObject( " Msxml2.DOMDocument.3.0 " );   // 客户端XML对象
     var  arrDroplstID;
    arrDroplstID 
=   new  Array();      // 缓存已经XMLHTTP获取过的ID
     var  arrDroplstValue;
    arrDroplstValue 
=   new  Array();
    
var  iDroplstSavedCont  =   0 ;
    
var  objOldValue  =   "" ;     // 保存控件原来的值
     var  xmlhttpDroplst  =   null
    
var  currTextBoxID  =   " -1 " ;
    
var  currDivID  =   " -1 " ;
    
var  currOpendDivName  =   "" ;
    
var  oTimer;
    
//  设置自动检查输入并获取列表
     function  SetInputCheckValid(id,idSelect,idText,idFields,obj)
    {
        
var  args = [];
        
var  object  =  document.getElementById(id);
        
var  objSelect  =  document.getElementById(idSelect);
        
var  objText  =  document.getElementById(idText);
        args.push(id);
        args.push(object);
        args.push(objSelect);
        args.push(objText);
        args.push(idFields);
        args.push(objText);
        oTimer 
=   setInterval( function (){
                                AutoGetItems.apply(
this ,args);
                               },
400 );
        }
        
    
function  SetInputCheckDisable(){clearInterval(oTimer);}
    
function  AutoGetItems(id,object,objSelect,objText,idFields,obj)
    {
         
var  i  =   0 ;
         
var  j = 0 ;
         
var  sCurr  =   '' ;
         
var  soptText = '' ;
         
var  blnAdd  =   false ;
         
var  xmlDroplst  =   new  ActiveXObject( " Msxml2.DOMDocument.3.0 " );   // 客户端XML对象
          if (objText  !=   null ){sCurr  =  objText.value;}
        
// 为空,清除 退出
         if (sCurr  ==   "" )
        {
              
// 清除现有内容
             if (objSelect  !=   null )
               objSelect.options.length 
=   0 ;   // 清除内容
             return ;
        }
        
// 值相同则退出
         if (sCurr  ==  objOldValue)
            
return ;
        objOldValue 
=  sCurr;
        
var  sXml   =  getXmlHttpFields(idFields  +   " _ "   +  escape(sCurr));
        
if (sXml  !=   " -1 " )
        {
            
// 从缓存中获取到
             if (object  !=   null )
            {
                
if (sXml == "" )   // 没有
                {
                    xmlDroplst.loadXML(
" <Root></Root> " );
                }
                
else
                {
                    xmlDroplst.loadXML(sXml);
                 }
                
var  nodes  =  xmlDroplst.documentElement.childNodes;
                
if (objSelect  !=   null )
                {
                   objSelect.options.length 
=   0 ;   // 清除内容
                    for  (i = 0 ;i < nodes.length;i ++ )
                   {
                        soptText 
=  nodes(i).getAttribute( " Text " );
                        
// 动态获取的情况,所以的内容是从后台筛选过的
                        objSelect.add(document.createElement( " OPTION " ));
                        objSelect.options[j].text
=  soptText;
                        objSelect.options[j].value
= j; 
                        j
++ ;
                    }
                }
                
if (j  > 0 )
                  {
                     
// 存在时显示
                     object.style.left  =  absoluteLocation(obj,  ' offsetLeft ' -   2   +   " px " ;       
                     object.style.top 
=  absoluteLocation(obj,  ' offsetTop ' +  obj.offsetHeight  +   2   +   " px "
                     object.style.width 
=  obj.offsetWidth  +   2   +   ' px ' ;
                     hideMe(id,
'' );
                     currOpendDivName 
=  id;
                  }
            }
        }
        
else
        {
           
if ( sCurr  !=   "" )
           {
                
// 异步获取
                 if (xmlhttpDroplst  ==   null )
                     xmlhttpDroplst 
=  CreateDroplstXmlHttpObject();       
                
if (xmlhttpDroplst  !=   null )
                {
                    
try
                    {    
                        xmlhttpDroplst.open(
" GET " " ../Common/frmXmlHttpDroplst.aspx?id= "   +  idFields  +   " &curr= "   +  escape(sCurr),  true ); 
                        
// window.open("../Common/frmXmlHttpDroplst.aspx?id=" + idFields);
                        xmlhttpDroplst.setRequestHeader(  " CONTENT-TYPE  " " application/x-www-form-urlencoded  " ); 
                        xmlhttpDroplst.onreadystatechange 
=   function () 
                                                    { 
                                                        
if  ( xmlhttpDroplst.readyState == 4  ) 
                                                        {   
                                                            sXml 
=  xmlhttpDroplst.responseText;
                                                            
                                                            
if (sXml == "" )   // 没有
                                                            {
                                                                xmlDroplst.loadXML(
" <Root></Root> " );
                                                            }
                                                            
else
                                                            {
                                                                xmlDroplst.loadXML(sXml);
                                                            }
                                                            
// 缓存这次结果
                                                            arrDroplstID[iDroplstSavedCont]  =  idFields  +   " _ "   +  escape(sCurr);
                                                            arrDroplstValue[iDroplstSavedCont] 
=  sXml;
                                                            iDroplstSavedCont
++ ;
                                                            
if (object  !=   null )
                                                            {
                                                                
var  nodes  =  xmlDroplst.documentElement.childNodes;
                                                                
if (objSelect  !=   null )
                                                                {
                                                                   objSelect.options.length 
=   0 ;   // 清除内容
                                                                    for  (i = 0 ;i < nodes.length;i ++ )
                                                                   {
                                                                        soptText 
=  nodes(i).getAttribute( " Text " );
                                                                        
// 动态获取的情况,所以的内容是从后台筛选过的
                                                                        objSelect.add(document.createElement( " OPTION " ));
                                                                        objSelect.options[j].text
=  soptText;
                                                                        objSelect.options[j].value
= j; 
                                                                        j
++ ;
                                                                        
                                                                    }
                                                                }
                                                                
if (j  > 0 )
                                                                  {
                                                                     
// 存在时显示
                                                                     object.style.left  =  absoluteLocation(obj,  ' offsetLeft ' -   2   +   " px " ;       
                                                                     object.style.top 
=  absoluteLocation(obj,  ' offsetTop ' +  obj.offsetHeight  +   2   +   " px "
                                                                     object.style.width 
=  obj.offsetWidth  +   2   +   ' px ' ;
                                                                     hideMe(id,
'' );
                                                                  }
                                                            }
                                                            
                                                         }
                                                    }   
                          xmlhttpDroplst.send(
null );   
                     }
                     
catch (e3)
                     {
                     }
               }
           }
       }
    }
    
    setInterval(
" AutoCloseDiv() " , 3000 );
    
function  setInputID(idText){currTextBoxID  =  idText; }
    
function  setInputIDNone(){currTextBoxID  =   " -1 " ; }
    
function  AutoCloseDiv()
    {
        
if (currTextBoxID  ==   " -1 "   &&  currDivID  ==   " -1 " )
        {
            
try {hideMe(currOpendDivName, " none " );} catch (e3){}
        }
    }
    
function  CreateDroplstXmlHttpObject()
    {
        
try   
        {  
            xmlhttpDroplst 
=   new  ActiveXObject( " MSXML2.XMLHTTP " );  
        }  
        
catch (e)  
        {  
            
try   
            {  
                xmlhttpDroplst 
=   new  ActiveXObject( " Microsoft.XMLHTTP " );  
            }  
            
catch (e2){}  
        }
        
return  xmlhttpDroplst;
    }
    
function  focusToDropDown(idSelect)
    {
         
if (event.keyCode  ==   40 )
         {
            
var  objSelect  =  document.getElementById(idSelect);
            
if (objSelect  !=   null )
            {   
try
                {
                   
// 有控件不可见的情况
                    objSelect.focus();
                    
if (objSelect.lenght  >   0 )
                        objSelect.options[
0 ].selected  =   true ;
                 }
                 
catch (e1)
                 {
                 }
            }
         }
    }
    
function  MoverToDropDownLayer(idSelect)
    {
            
var  objSelect  =  document.getElementById(idSelect);
            
if (objSelect  !=   null )
            {   
                 
try
                {
                   
// 有控件不可见的情况
                    objSelect.focus();
                    
if (objSelect.selectedIndex  ==   - 1 )
                        objSelect.selectedIndex 
=   0 ;
                        
                    currDivID 
=  idSelect;
                }
                 
catch (e1)
                 {
                 }
            }
    }
    
function  absoluteLocation(element, offset) 
    { 
var  c  =   0 while  (element) {  c  +=  element[offset];  element  =  element.offsetParent; }  return  c; 
    } 
    
function  getSelectedLabel(id,idText,obj) 
    {  
         
var  opt  =  obj.options[obj.selectedIndex]; 
         hideMe(id,
' none ' ); 
         
var  objText  =  document.getElementById(idText);
        
if (objText  !=   null )
        {
            objText.value 
=  getIdiomDeal(opt.text);
        }
    } 
    
function  getIdiomDeal(s)
    {
        
var  sRet  =  s;
        
if ( typeof (getUserIdiomDeal)  != " undefined " )
        {
            sRet 
=  getUserIdiomDeal(s);
        }
        
return  sRet;
    }
    
function  selectOnReturn(id,idText,obj)
    {
       
if (event.keyCode  ==   8 )
          event.keyCode 
=   null ;
       
if (event.keyCode == 13 )
       {
            event.returnValue 
=   false ;
            getSelectedLabel(id,idText,obj);
        }
    }
    
function  hideMe(id,status)
    {
        
var  object  =  document.getElementById(id);
        
if (object  !=   null )
        {
            object.style.display 
=  status;
            
if (status  ==   " none " )
            {
                currDivID 
=   " -1 " ;
                currTextBoxID 
=   " -1 " ;
            }
        }
    }
    
function  getItemsForDropdown(id,idSelect,idText,idFields,obj)
    {
         
var  object  =  document.getElementById(id);
         
var  objSelect  =  document.getElementById(idSelect);
          
var  objText  =  document.getElementById(idText);
          
var  objFields  =  document.getElementById(idFields);
         
var  i  =   0 ;
         
var  j = 0 ;
         
var  sCurr  =   '' ;
         
var  soptText = '' ;
         
var  blnAdd  =   false ;
         
         
if (objFields  !=   null )
         {  
var  sXml  =  objFields.value;
            xmlDroplst.loadXML(sXml);
         }
         
if (objText  !=   null ){ sCurr  =  objText.value; }
        
if (object  !=   null )
        {
            
var  nodes  =  xmlDroplst.documentElement.childNodes;
            
if (objSelect  !=   null )
            {
               objSelect.options.length 
=   0 ;   // 清除内容
                for  (i = 0 ;i < nodes.length;i ++ )
               {
                    soptText 
=  nodes(i).getAttribute( " Text " );
                    blnAdd 
=   false ;
                    
if (sCurr  ==   '' )
                    {
                       blnAdd 
=   true ;
                    }
                    
else
                    {
                       
if (soptText.toUpperCase().indexOf(sCurr.toUpperCase())  ==   0 )
                         {
                            blnAdd
= true ;
                         }
                    }
                    
if (blnAdd  ==   true )
                    {
                        objSelect.add(document.createElement(
" OPTION " ));
                        objSelect.options[j].text
=  soptText;
                        objSelect.options[j].value
= j; 
                        j
++ ;
                        
                    }
                }
            }
            object.style.left 
=  absoluteLocation(obj,  ' offsetLeft ' -   2   +   " px " ;       
            object.style.top 
=  absoluteLocation(obj,  ' offsetTop ' +  obj.offsetHeight  +   2   +   " px "
            object.style.width 
=  obj.offsetWidth  +   2   +   ' px ' ;
            hideMe(id,
'' );
            currOpendDivName 
=  id;
        }
    }
    
// 来源于XMLHTTP异步获取,***未改***
     function  getItemsForDropdownXmlHttp(id,idSelect,idText,idFields,obj)
    {
         
var  object  =  document.getElementById(id);
         
var  objSelect  =  document.getElementById(idSelect);
          
var  objText  =  document.getElementById(idText);
         
var  i  =   0 ;
         
var  j = 0 ;
         
var  sCurr  =   '' ;
         
var  soptText = '' ;
         
var  blnAdd  =   false ;
         
var  xmlDroplst  =   new  ActiveXObject( " Msxml2.DOMDocument.3.0 " );   // 客户端XML对象
         
         
if (objText  !=   null ){sCurr  =  objText.value;}
        
var  sXml   =  getXmlHttpFields(idFields);
        
if (sXml  !=   " -1 " )
        {
            
// 从缓存中获取到
             if (object  !=   null )
            {
                
if (sXml == "" )   // 没有
                {
                    xmlDroplst.loadXML(
" <Root></Root> " );
                }
                
else
                {
                    xmlDroplst.loadXML(sXml);
                 }
                
var  nodes  =  xmlDroplst.documentElement.childNodes;
                
if (objSelect  !=   null )
                {
                   objSelect.options.length 
=   0 ;   // 清除内容
                    for  (i = 0 ;i < nodes.length;i ++ )
                   {
                        soptText 
=  nodes(i).getAttribute( " Text " );
                        blnAdd 
=   false ;
                        
if (sCurr  ==   '' )
                        {
                           blnAdd 
=   true ;
                        }
                        
else
                        {
                           
if (soptText.toUpperCase().indexOf(sCurr.toUpperCase())  ==   0 )
                             {
                                blnAdd
= true ;
                             }
                        }
                        
if (blnAdd  ==   true )
                        {
                            objSelect.add(document.createElement(
" OPTION " ));
                            objSelect.options[j].text
=  soptText;
                            objSelect.options[j].value
= j;  
                            
// objSelect.options[j].className = "combo-item";
                            j ++ ;
                        }
                    }
                }
                
if (j  > 0 )
                  {
                     
// 存在时显示
                     object.style.left  =  absoluteLocation(obj,  ' offsetLeft ' -   2   +   " px " ;       
                     object.style.top 
=  absoluteLocation(obj,  ' offsetTop ' +  obj.offsetHeight  +   2   +   " px "
                     object.style.width 
=  obj.offsetWidth  +   2   +   ' px ' ;
                     hideMe(id,
'' );
                     currOpendDivName 
=  id;
                  }
            }
        }
        
else
        {
            
// 异步获取
             if (xmlhttpDroplst  ==   null )
                 xmlhttpDroplst 
=  CreateDroplstXmlHttpObject();       
            
if (xmlhttpDroplst  !=   null )
            {
                
try
                {    
                    xmlhttpDroplst.open(
" GET " " ../Common/frmXmlHttpDroplst.aspx?id= "   +  idFields,  true ); 
                    
// window.open("../Common/frmXmlHttpDroplst.aspx?id=" + idFields);
                    xmlhttpDroplst.setRequestHeader(  " CONTENT-TYPE  " " application/x-www-form-urlencoded  " ); 
                    xmlhttpDroplst.onreadystatechange 
=   function () 
                                                { 
                                                    
if  ( xmlhttpDroplst.readyState == 4  ) 
                                                    {   
                                                        sXml 
=  xmlhttpDroplst.responseText;
                                                        
                                                        
if (sXml == "" )   // 没有
                                                        {
                                                            xmlDroplst.loadXML(
" <Root></Root> " );
                                                        }
                                                        
else
                                                        {
                                                            xmlDroplst.loadXML(sXml);
                                                            
                                                        }
                                                        
// 缓存这次结果
                                                        arrDroplstID[iDroplstSavedCont]  =  idFields;
                                                        arrDroplstValue[iDroplstSavedCont] 
=  sXml;
                                                        iDroplstSavedCont
++ ;
                                                        
if (object  !=   null )
                                                        {
                                                            
var  nodes  =  xmlDroplst.documentElement.childNodes;
                                                            
if (objSelect  !=   null )
                                                            {
                                                               objSelect.options.length 
=   0 ;   // 清除内容
                                                                for  (i = 0 ;i < nodes.length;i ++ )
                                                               {
                                                                    soptText 
=  nodes(i).getAttribute( " Text " );
                                                                    blnAdd 
=   false ;
                                                                    
if (sCurr  ==   '' )
                                                                    {
                                                                       blnAdd 
=   true ;
                                                                    }
                                                                    
else
                                                                    {
                                                                       
if (soptText.toUpperCase().indexOf(sCurr.toUpperCase())  ==   0 )
                                                                         {
                                                                            blnAdd
= true ;
                                                                         }
                                                                    }
                                                                    
if (blnAdd  ==   true )
                                                                    {
                                                                        objSelect.add(document.createElement(
" OPTION " ));
                                                                        objSelect.options[j].text
=  soptText;
                                                                        objSelect.options[j].value
= j; 
                                                                        j
++ ;
                                                                    }
                                                                }

                                                            }
                                                            
if (j  > 0 )
                                                              {
                                                                 
// 存在时显示
                                                                 object.style.left  =  absoluteLocation(obj,  ' offsetLeft ' -   2   +   " px " ;       
                                                                 object.style.top 
=  absoluteLocation(obj,  ' offsetTop ' +  obj.offsetHeight  +   2   +   " px "
                                                                 object.style.width 
=  obj.offsetWidth  +   2   +   ' px ' ;
                                                                 hideMe(id,
'' );
                                                              }
                                                        }
                                                     }
                                                }   
                      xmlhttpDroplst.send(
null );   
                 }
                 
catch (e3)
                 {
                 }
           }
       }
    }
    
// 通过缓存数组获取可以选择的值
     function  getXmlHttpFields(idFields)
    {
        
var  respText  =   " -1 " ;
        
var  i  =   0 ;
        
for (i = 0 ;i < iDroplstSavedCont;i ++ )
        {
            
if (idFields  ==  arrDroplstID[i])
            {
               respText 
=  arrDroplstValue[i];
            }
        }
        
return  respText;
  }

 

 

    整个控件脚本只是一部分,还有相应的aspx 后台代码 ascx代码等,这个就不一一介绍了,E8的客户可以联系我们对这个控件进行升级,或者在提供的全部源码基础上自己完善也可以,呵呵。

 

    希望对大家有所帮助

你可能感兴趣的:(javascrip)