`
jianguang_qq
  • 浏览: 92008 次
  • 性别: Icon_minigender_1
  • 来自: 深圳南山
社区版块
存档分类
最新评论

从帖子《可输入的select下拉框》的优化,总结js键盘事件的兼容性

阅读更多


 本文源起javaeye的论坛帖子《可输入的select下拉框》:

<html>
<head>
<title>可输入的select下拉框</title>
</head>
<script>
   
</script>
<body >
<select style='width:150px;z-index:-1' id="aa" name="selectHelpCode" onkeydown="if(event.keyCode == 8){this.options[0].text = '';}" onkeypress="writeSelect(this)">
    <option value=""></option>
    <option value="11">11</option>
    <option value="22">22</option>
    <option value="33">33</option>
</select>

<input type="button" value="点我" onclick="ttt();"/>

<script>
   
    function writeSelect(obj){
        obj.options[0].selected = "select";
        obj.options[0].text = obj.options[0].text + String.fromCharCode(event.keyCode);
        event.returnValue=false;
        return obj.options[0].text;
    }

    function ttt(){
        var ss = document.getElementById("aa").value;
        var jg = "";
       
        if(ss == ""){
            var aas = writeSelect(document.getElementById("aa"));
            jg = aas;
        }else{
            jg =     document.getElementById("aa").value;
        }
       
      alert(jg);
}
    </script>

</body>
</html>

 

楼主创意很不错,但代码不支持ff,另外还有好些优化的空间。 

于是帮楼主优化了下代码:

<select id="select" onkeydown="Select.del(this,event)" onkeypress="Select.write(this,event)">
    <option value=""></option>
    <option value="11">11</option>
    <option value="22">22</option>
    <option value="33">33</option>
</select>
<input type="button" value="点我" id="test" onclick="test();"/>
<script> 
var Select = {
	del : function(obj,e){
		if((e.keyCode||e.which||e.charCode) == 8){
			var opt = obj.options[0];
			opt.text = opt.value = opt.value.substring(0, opt.value.length>0?opt.value.length-1:0);
		}
	},
	write : function(obj,e){
		if((e.keyCode||e.which||e.charCode) == 8)return ;
		var opt = obj.options[0];
		opt.selected = "selected";
		opt.text = opt.value += String.fromCharCode(e.charCode||e.which||e.keyCode);
	
	}
}

function test(){
	alert(document.getElementById("select").value);
}
</script>

 

支持逐个删除。ff上的文支持上好像还有些问题。

 

楼主例子很不错,我在优化过程中遇到很多ie和ff键盘事件兼容性的问题。让学到了好些东西。正准备总结一下,结果上网一搜,发现一篇好文,把我准备做的总结已经做好了,而且做得非常好,直接引用之

  

作者:羽殇仁 转载请注明出处,谢谢。

本篇文章是我的第一百篇blog文章,恭喜一下!

这两天突然想弄弄js的键盘记录,所以就小研究了一下。

主要分四个部分
第一部分:浏览器的按键事件
第二部分:兼容浏览器
第三部分:代码实现和优化
第四部分:总结

第一部分:浏览器的按键事件

用js实现键盘记录,要关注浏览器的三种按键事件类型,即keydown,keypress和keyup,它们分别对应onkeydown、onkeypress和onkeyup这三个事件句柄。一个典型的按键会产生所有这三种事件,依次是keydown,keypress,然后是按键释放时候的keyup。

在这3种事件类型中,keydown和keyup比较底层,而keypress比较高级。这里所谓的高级是指,当用户按下shift + 1时,keypress是对这个按键事件进行解析后返回一个可打印的“!”字符,而keydown和keyup只是记录了shift + 1这个事件。[1]

但是keypress只能针对一些可以打印出来的字符有效,而对于功能按键,如F1-F12、Backspace、Enter、Escape、PageUP、PageDown和箭头方向等,就不会产生keypress事件,但是可以产生keydown和keyup事件。然而在FireFox中,功能按键是可以产生keypress事件的。

传递给keydown、keypress和keyup事件句柄的事件对象有一些通用的属性。如果Alt、Ctrl或Shift和一个按键一起按下,这通过事件的altKey、ctrlKey和shiftKey属性表示,这些属性在FireFox和IE中是通用的。

第二部分:兼容浏览器

凡是涉及浏览器的js,就都要考虑浏览器兼容的问题。
目前常用的浏览器主要有基于IE和基于Mozilla两大类。Maxthon是基于IE内核的,而FireFox和Opera是基于Mozilla内核的。

2.1 事件的初始化

首先需要了解的是如何初始化该事件,基本语句如下:

   function keyDown(){}
   document.onkeydown = keyDown;

当浏览器读到这个语句时,无论按下键盘上的哪个键,都将呼叫KeyDown()函数。

2.2 FireFox和Opera的实现方法

FireFox和Opera等程序实现要比IE麻烦,所以这里先描述一下。

keyDown()函数有一个隐藏的变量--一般的,我们使用字母“e”来表示这个变量。

   function keyDown(e)

变量e表示发生击键事件,寻找是哪个键被按下,要使用which这个属性:

   e.which

e.which将给出该键的索引值,把索引值转化成该键的字母或数字值的方法需要用到静态函数String.fromCharCode(),如下:

   String.fromCharCode(e.which)

把上面的语句放在一起,我们可以在FireFox中得到被按下的是哪一个键:

   function keyDown(e) {
      var keycode = e.which;
      var realkey = String.fromCharCode(e.which);
      alert("按键码: " + keycode + " 字符: " + realkey);
   }
   document.onkeydown = keyDown;

2.3 IE的实现方法

IE的程序不需要e变量,用window.event.keyCode来代替e.which,把键的索引值转化为真实键值方法类似:String.fromCharCode(event.keyCode),程序如下:

   function keyDown() {
      var keycode = event.keyCode;
      var realkey = String.fromCharCode(event.keyCode);
      alert("按键码: " + keycode + " 字符: " + realkey);
   }
   document.onkeydown = keyDown;

2.4 判断浏览器类型

上面了解了在各种浏览器里是如何实现获取按键事件对象的方法,那么下面需要判断浏览器类型,这个方法很多,有比较方便理解的,也有很巧妙的办法,先说一般的方法:就是利用navigator对象的appName属性,当然也可以用userAgent属性,这里用appName来实现判断浏览器类型,IE和Maxthon的appName是“Microsoft Internet Explorer” ,而FireFox和Opera的appName是“Netscape”,所以一个功能比较简单的代码如下:

   function keyUp(e) {
      if(navigator.appName == "Microsoft Internet Explorer")
      {
        var keycode = event.keyCode;
        var realkey = String.fromCharCode(event.keyCode);
      }else
      {
         var keycode = e.which;
          var realkey = String.fromCharCode(e.which);
      }
      alert("按键码: " + keycode + " 字符: " + realkey);
    }
   document.onkeyup = keyUp;

比较简洁的方法是[2]:

   function keyUp(e) {
     var currKey=0,e=e||event;
     currKey=e.keyCode||e.which||e.charCode;
     var keyName = String.fromCharCode(currKey);
     alert("按键码: " + currKey + " 字符: " + keyName);
   }
   document.onkeyup = keyUp;

上面这种方法比较巧妙,简单地解释一下:
首先,e=e||event;这句代码是为了进行浏览器事件对象获取的兼容。js中这句代码的意思是,如果在FireFox或Opera中,隐藏的变量e是存在的,那么e||event返回e,如果在IE中,隐藏变量e是不存在,则返回event。
其次,currKey=e.keyCode||e.which||e.charCode;这句是为了兼容浏览器按键事件对象的按键码属性(详见第三部分),如IE中,只有keyCode属性,而FireFox中有which和charCode属性,Opera中有keyCode和which属性等。

上述代码只是兼容了浏览器,获取了keyup事件对象,简单的弹出了按键码和按键的字符,但是问题出现了,当你按键时,字符键都是大写的,而按shift键时,显示的字符很奇怪,所以就需要优化一下代码了。

第三部分:代码实现和优化

3.1 按键事件的按键码和字符码

按键事件的按键码和字符码缺乏浏览器间的可移植性,对于不同的浏览器和不同的案件事件,按键码和字符码的存储方式都是不同的,按键事件,浏览器和按键事件对象属性关系如下表:

 
如表所示:

在IE中,只有一个keyCode属性,并且它的解释取决于事件类型。对于keydown来说,keyCode存储的是按键码,对于keypress事件来说,keyCode存储的是一个字符码。而IE中没有which和charCode属性,所以which和charCode属性始终为undefined。

FireFox中keyCode始终为0,时间keydown/keyup时,charCode=0,which为按键码。事件keypress时,which和charCode二者的值相同,存储了字符码。

在Opera中,keyCode和which二者的值始终相同,在keydown/keyup事件中,它们存储按键码,在keypress时间中,它们存储字符码,而charCode没有定义,始终是undefined。

3.2 用keydown/keyup还是keypress

第一部分已经介绍了keydown/keyup和keypress的区别,有一条比较通用的规则,keydown事件对于功能按键来说是最有用的,而keypress事件对于可打印按键来说是最有用的[3]。

键盘记录主要是针对于可打印字符和部分功能按键,所以keypress是首选,然而正如第一部分提到的,IE中keypress不支持功能按键,所以应该用keydown/keyup事件来进行补充。

3.3 代码的实现
总体思路,用keypress事件对象获取按键字符,用keydown事件获取功能字符,如Enter,Backspace等。

代码实现如下所示

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD><TITLE>js 按键记录</TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="羽殇仁">
<META NAME="Keywords" CONTENT="js 按键记录">
<META NAME="Description" CONTENT="js 按键 记录">
</HEAD>
<BODY>
<script type="text/javascript">
var keystring = "";//记录按键的字符串
function $(s){return document.getElementById(s)?document.getElementById(s):s;}
function keypress(e)
{
  var currKey=0,CapsLock=0,e=e||event;
  currKey=e.keyCode||e.which||e.charCode;
  CapsLock=currKey>=65&&currKey<=90;
  switch(currKey)
  {
    //屏蔽了退格、制表、回车、空格、方向键、删除键
    case 8: case 9:case 13:case 32:case 37:case 38:case 39:case 40:case 46:keyName = "";break;
    default:keyName = String.fromCharCode(currKey); break;
  }
  keystring += keyName;
}
function keydown(e)
{
  var e=e||event;
  var currKey=e.keyCode||e.which||e.charCode;
  if((currKey>7&&currKey<14)||(currKey>31&&currKey<47))
  {
    switch(currKey)
    {
      case 8: keyName = "[退格]"; break;
      case 9: keyName = "[制表]"; break;
      case 13:keyName = "[回车]"; break;
      case 32:keyName = "[空格]"; break;
      case 33:keyName = "[PageUp]"; break;
      case 34:keyName = "[PageDown]"; break;
      case 35:keyName = "[End]"; break;
      case 36:keyName = "[Home]"; break;
      case 37:keyName = "[方向键左]"; break;
      case 38:keyName = "[方向键上]"; break;
      case 39:keyName = "[方向键右]"; break;
      case 40:keyName = "[方向键下]"; break;
      case 46:keyName = "[删除]"; break;
      default:keyName = ""; break;
    }
    keystring += keyName;
  }
  $("content").innerHTML=keystring;
}
function keyup(e)
{
  $("content").innerHTML=keystring;
}
document.onkeypress=keypress;
document.onkeydown =keydown;
document.onkeyup =keyup;
</script>
<input type="text" />
<input type="button" value="清空记录" onclick="$('content').innerHTML = '';keystring = '';"/>
<br/>请按下任意键查看键盘响应键值:<span id="content"></span>
</BODY>
</HTML>

代码分析:
$():根据ID获取dom
keypress(e):实现对字符码的截获,由于功能按键要用keydown获取,所以在keypress中屏蔽了这些功能按键。
keydown(e):主要是实现了对功能按键的获取。
keyup(e):展示截获的字符串。

代码基本上就算实现完成了!呵呵

第四部分:总结

编写代码的最初目的是能够通过js记录按键,并返回一个字符串。

上述代码只是用js实现了基本的英文按键记录,对于汉字是无能为力,记录汉字,我能想到的办法,当然是用js,是用keydown和keyup记录底层按键事件,汉字解析当然无能为力。当然你可以用DOM的方式直接获取input中的汉字,但这已经离开了本文讨论的用按键事件实现按键记录的本意。

上述代码还可以实现添加剪切板的功能,监控删除的功能等等。。。

引用:

[1]《javascript 权威指南》第五版 O'REILLY Press/机械工业出版社 424页
[2]《javascript 权威指南》第五版 O'REILLY Press/机械工业出版社 427页
[3]《javascript 权威指南》第五版 O'REILLY Press/机械工业出版社 425页

附录:

常用按键码对应的按键列表:


 

 

  • 大小: 11.8 KB
  • 大小: 70.4 KB
分享到:
评论
1 楼 clone168 2009-08-24  
楼主代码写的不错,用对象封装起来,这里我再在原来的基础上稍加修改,希望能更加完善:
<select id="select" onkeydown="Select.del(this,event)" onkeypress="Select.write(this,event)"> 
    <option value=""></option> 
    <option value="11">11</option> 
    <option value="22">22</option> 
    <option value="33">33</option> 
</select> 
<input type="button" value="点我" id="test" onclick="test();"/> 
<script> 
var Key = {
        //这里只是为了避免后面的代码重复,该对象完全可以封装好更多的函数
keyCode : function(e){
return e.keyCode||e.which||e.charCode;
}
}
var Select = {
    del : function(obj,e){ 
if(!obj.options[0].selected) return ;//当前不是可输入的options,返回
        if(Key.keyCode(e) ==
            var opt = obj.options[0]; 
            opt.text = opt.value = opt.value.substring(0, opt.value.length>0?opt.value.length-1:0); 
        } 
    }, 
    write : function(obj,e){ 
        if(Key.keyCode(e) == 8||Key.keyCode(e) == 37||Key.keyCode(e) == 38||Key.keyCode(e) == 39||Key.keyCode(e) == 40)return ; //避免在select中使用上下方向键时往options写内容,当然,这里把左右键也加进来了
        var opt = obj.options[0]; 
        opt.selected = "selected"; 
        opt.text = opt.value += String.fromCharCode(Key.keyCode(e));
    }
}
 
function test(){ 
    alert(document.getElementById("select").value); 

</script>

相关推荐

    可文本输入的下拉框select

    无论是原生JavaScript还是前端框架,实现“可文本输入的下拉框select”都需要对DOM操作、事件监听和数据处理有深入理解。在实际项目中,为了提高可维护性和用户体验,开发者还应考虑以下因素: 1. 键盘导航:确保...

    asp.net可输入可选择下拉框

    2. **JavaScript/jQuery处理**:使用JavaScript或jQuery监听用户的输入事件,如键盘按下、失去焦点等,以便在输入和选择之间切换显示。同时,要处理下拉框的选项选择事件,确保当选中一个选项时,文本框的值与选中的...

    键盘操作select下拉框

    此外,为了兼容各种浏览器和设备,应遵循Web Content Accessibility Guidelines (WCAG)的建议,以确保键盘可访问性。在实际应用中,可能还需要考虑其他键盘快捷键,如`Esc`键取消选择,或者结合使用`Shift`键多选等...

    可输入的下拉框.rar

    3. Select2、Chosen、Autocomplete等库:这些成熟的插件提供了丰富的自定义选项和良好的兼容性,是实现此类功能的常用工具。 4. Vue.js、React等前端框架:它们提供了组件化开发方式,也有对应的可输入下拉框组件。 ...

    下拉框可输入+自动提示+支持键盘事件兼容IE,FF

    标题 "下拉框可输入+自动提示+支持键盘事件兼容IE,FF" 指的是一种前端开发技术,用于创建具有智能搜索和自动提示功能的下拉选择框。这种技术通常应用于网页表单中,提高用户输入数据的效率和体验。在描述中提到的 ...

    JS中Select下拉列表类(支持输入模糊查询)功能

    JS中Select下拉列表类支持输入模糊查询功能的知识点主要包括以下几个方面: 1. HTML结构设计:实现输入模糊查询功能的下拉列表通常包含一个输入框和一个下拉框。输入框用于用户输入查询字符,下拉框则是提供选项供...

    可以输入的下拉框(可用于项目的)

    标题中的“可以输入的下拉框(可用于项目的)”是指一种交互式UI组件,它结合了传统下拉框和文本输入框的功能,用户既可以从中选择已有的选项,也可以自行输入新的内容。这种设计在许多Web应用和软件项目中非常常见,...

    jquery+html自定义select下拉框,下拉框美化

    3. **可访问性**:遵循Web Content Accessibility Guidelines (WCAG),确保键盘导航和屏幕阅读器兼容性。 4. **浏览器兼容性**:测试主要浏览器(如Chrome、Firefox、Safari、Edge)的兼容性,必要时使用polyfills或...

    两种方式生成可输入下拉框。

    ### 方式一:组合input文本框与select下拉框 #### HTML 结构 首先,我们需要一个`&lt;input&gt;`元素用于用户输入,一个`&lt;select&gt;`元素用于展示下拉选项,以及一个按钮触发操作: ```html 请输入或选择"&gt; &lt;select id...

    支持手动输入的下拉框

    - 遵循Web Content Accessibility Guidelines (WCAG),确保键盘导航和支持辅助技术的兼容性。 - 提供清晰的视觉反馈,如高亮选中项和突出显示匹配文本。 6. **响应式设计**: 在不同设备和屏幕尺寸上,下拉框应...

    JS模拟select 下拉框组件

    **JS模拟Select下拉框组件详解** 在网页开发中,Select元素是常用的数据选择控件,但其样式和交互方式往往不能满足设计师和开发者对于用户体验的高要求。为了解决这个问题,开发人员通常会使用JavaScript来模拟...

    JQ JS javascript 多选 多选下拉框 select bootstrap-select

    在网页开发中,多选下拉框是一种常见的用户交互元素,它允许用户...在实际开发中,还需要注意兼容性和性能优化,确保在不同设备和浏览器上的良好表现。同时,理解并熟练运用这些工具,能让你的前端代码更加高效和灵活。

    下拉框和文本框组合共用-可以输入的下拉框ok

    在网页设计和开发中,"下拉框和文本框组合共用-可以输入的下拉框"是一个常见的交互元素,它结合了...在实际应用中,开发者需要关注其实现细节、可访问性、性能优化以及跨平台兼容性等方面,以构建出高质量的交互体验。

    select完美下拉框

    开发者可能会使用CSS来定制`&lt;select&gt;`和`&lt;option&gt;`的样式,但这受限于浏览器的兼容性,对于复杂的样式修改可能无能为力。因此,通常会用JavaScript或jQuery等库来构建自定义组件,模拟下拉框的行为。 JavaScript在...

    jQuery Select下拉框美化表单.zip

    本项目"jQuery Select下拉框美化表单"正是这样一个解决方案,它基于`jquery.selectlist.js`和`jquery-1.9.1.min.js`两个JavaScript文件,旨在为招聘网站等需要展示学历和薪资范围等选项的场景提供更优雅的用户体验。...

    下拉框(select),可以多选,带有分组搜索功能

    在前端开发中,下拉框(Select)是用户界面中常见的一种交互元素,用于提供一组可选项供用户选择。在本场景中,我们讨论的是一个具有特定增强功能的下拉框,它支持多选、分组以及搜索功能。这样的组件在处理大量数据...

    jQuery下拉框美化插件selectList.rar

    2. **跨浏览器兼容性**:考虑到不同的用户可能使用不同的浏览器,selectList确保在主流浏览器(如Chrome、Firefox、Safari、Edge和Internet Explorer)上都能正常工作,提供了良好的兼容性。 3. **模拟下拉框**:...

    原生js实现下拉框功能(支持键盘事件)

    支持键盘事件的下拉框在可访问性上做得更好,同时也提升了用户体验。 在CSS样式方面,为了使下拉框在视觉上符合网页的整体风格,通常需要定义一些样式规则。例如,可以设置下拉框的宽度、边框样式、悬停时的背景色...

    jQuery Select下拉框美化特效.zip

    6. **兼容性**:由于jQuery是一个广泛支持的JavaScript库,所以这个特效应该能在主流浏览器(如Chrome、Firefox、Safari、Edge)上正常工作,确保广泛的用户群体都能享受到美化后的效果。 为了实现这些功能,开发者...

    基于jquery 拖动sliders滑块改变Select下拉框的值.zip

    在前端开发中,交互设计是提升用户体验的关键因素之一。这个项目"基于jQuery 拖动...同时,这个案例也提醒我们,在前端开发中,不仅要关注视觉效果,还要注重代码的可维护性、性能优化以及对不同用户群体的兼容性。

Global site tag (gtag.js) - Google Analytics