当前位置: 首页 > 科技观察

使HTML5数字输入仅接受整数

时间:2023-03-17 10:40:05 科技观察

我在过去两年中看到了很多关于此的文章和帖子,这是一个非常方便的事情。然而,太多的实现仍然存在错误、实现不完整等。总体概念是合理的:使用HTML5属性来限制可以发送到服务器的内容,然后使用Javascript对其进行增强以首先限制用户可以输入的内容.那么让我们来看看这些问题,并更好地实施它。问题1,糟糕的脚本最常见的缺陷是缺少适当的降级功能。如果您正在使用“electron”或“nw.js”构建全栈应用程序,那很好,但这种形式的东西通常在面向公众的网站中没有立足之地。就像我经常说的,高质量的脚本应该增强已经工作的页面,而不是用户使用它的唯一方式。解决方案?使用pattern和step属性来限制负载。问题2,正则表达式模式错误或不完整人们最常用的模式是[-/d]*,它存在允许到处使用减号的问题。虽然肯定可以使用type="number"来解决问题,但这不是一个好的选择。在拦截击键时更是如此,因为减号只能是第一个字符。这也可能是有问题的,因为一些实现“不是”正则表达式,这可能导致误报。解决方案?对于HTML,使用更好的表达式:^[-d]\d*$更稳健和准确。减号可以是匹配开始处的第一个字符,后跟零个或多个小数,直到字符串结束。对于JavaScript,只需使用正则表达式来测试数字,并应用一些更实用的逻辑来检测其他值。简单易行!问题3,在标记中使用事件属性我知道有很多人在JSX垃圾中鼓励这样做,但是如果你正在编写vanilla或其他系统,请看在圣诞之爱的份上,把你的头从直肠里拿出来1997年。在标记中放置“onkeypress”或“onchange”是错失了缓存的机会,并且违反了关注点分离原则。以这种方式将JavaScript放入标记中,就像HTML4Strict中弃用的所有内容一样,是彻头彻尾的愚蠢。就像如果你要用“text-whitebox-shadowcol-4-s”这样的属性在你的HTML上撒尿,承认失败并返回使用所有这些FONT/CENTER标签,COLOR,BGCOLOR,SIZE编写HTML3.2、BORDER和ALIGN属性,以及“布局表”,你们似乎都清楚地怀念着这些。这也意味着您没有完整/正确的事件处理程序访问权限。解决方案?Element.addEventListener,请使用它!问题4,每个输入都必须进行硬编码无论是通过问题3将事件属性放入标记中,还是通过手动获取唯一ID来捕获它们,我发现几乎没有实际使用插件的代码库-玩标记应用程序!解决方案?document.querySelectorAll('input[type="number"][step="1"]')给了我们所有我们想要的整数输入,所以我们可以增强它。问题5,一些脚本阻止使用导航控件和正常编辑!通过拦截并只允许减号和0...9,它们可以防止退格、回车、制表符、箭头、删除、插入等。并非所有浏览器都会将这些作为event.key发送,这取决于您挂钩的事件。例如,“keypress”事件在Firefox和Chrome中被过滤掉,以免破坏正常的表单使用,但在“oldEdge”和Safari中却没有,“keydown”根本没有被过滤掉。解决方案?由于“keypress”事件在浏览器中不一致,请改用keydown。然后我们可以利用所有控制键在Event.key值中返回多个字符这一事实,我们只需要检查Event.key.length>1来表示“继续并允许这些”。如前所述,我们所需要的只是一个简单的输入,首先要有尽可能多的功能,而不需要JavaScript!HTML:只接受整数,如果只想接受正数,可以用pattern="/d+”JavaScript:那么我们可以使用JavaScript来限制用户的输入,这样人们连Invalid值都不允许。(function(){varintegers=document.querySelectorAll('input[type="number"][step="1"]'),intRx=/\d/;for(varinputofintegers){input.addEventListener('keydown',integerChange,false);}functionintegerChange(event){if((event.key.length>1)||((event.key==="-")&&(event.currentTarget.value.length===0))||intRx.test(event.key))return;event.preventDefault();}})();我们首先将其包装在IIFE中以隔离作用域。然后,获取我们想要挂接到页面上的所有输入,并创建我们的正则表达式。我在事件开始时而不是在事件内部创建正则表达式,这样我们就不会浪费时间在每次该死的按键时创建它。这是匿名函数可以引入开销的地方,也是需要告诉那些“函数式程序员”和他们的“副作用”废话的地方。遍历所有输入并为它们分配事件处理程序。上面的处理程序只是检查我们的回报。箭头、退格键、回车键等控制键返回描述它们的全文,因此如果event.key的长度>1,我们不会阻止它们。如果它是减号和第一个字符,则通过返回允许它。如果它是一个数字,请通过返回允许它。如果两者都不是,则阻止该事件。LiveDemo这是一个密码本,包括几个文本字段和多个整数和非整数数值字段,所以你可以看到它只hook了我们想要的字段。https://codepen.io/jason-knight/pen/QWGyrwq我可能考虑添加的一件事是挂钩“更改”事件以拦截粘贴,但由于“模式”属性不允许提交无效值,所以应该没有问题。结论仔细考虑用户可能输入错误的内容,以及如何处理这些错误,但也要记住用户可能输入的与值本身无关的所有其他内容。请始终注意,出于安全或可访问性原因,许多用户主动阻止脚本编写,或使脚本在UA中不可用。增强而不是替换您的基本功能!计划将这些东西应用到所有这些字段,而不是从一开始就使用单个元素。注意效率低下的问题,例如如何多次生成用作回调的匿名函数......或者将脚本放入标记中如何错过跨页面或重新访问的缓存机会。一旦你完成了这些事情,实现这样一个简单的功能就不会再打扰你或惹恼你的用户了。