作者:SamanthaMing译者:前端小智来源:kilianvalkhof再次点赞,微信搜索【大运世界】,哔哩哔哩关注【前端小智】这个人没有大厂背景,但态度积极。本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。最近开源了一个Vue组件,但是还不够完善。欢迎大家一起完善,也希望大家能给个star支持一下。谢谢。github地址:https://github.com/qq44924588...input标签的number类型提供了一种处理数字的好方法。我们可以通过min和max属性来设置上下限,可以通过上下键加减1,如果设置了step属性,可以通过上下键加减相应的步长值下键。但是,如果我们希望用户以不同的步骤上下移动怎么办?该步骤不仅确定要添加或删除多少,而且还确定该数字的界限。如果您输入值5,步长10,然后按向上键,您将不会得到15(5+10),而是10(步长的最接近倍数)。那么,我们想让用户可以输入任意数字,想要加10,怎么办呢?如何增强输入类型=数字的体验我们先定义一些按钮操作。当用户在输入标签中使用方向键时,有一些相应的快捷操作:如果用户按下向上或向下键盘,我们需要加或减1;如果他按shift,按up或down键,我们需要对应的加减为10。如果我们按alt,按up或down键,我们需要相应的加减0.1。如果我们在按住ctrl的同时按上下键,就需要相应的加减100。mac对应cmd键,如果输入内容为空,则按照min值进行计算。这是完整的代码,比较简洁,只有20行左右的代码。constisMac=navigator.platform==='MacIntel';constKEY={UP:38,DOWN:40,};document.querySelector("input").addEventListener("keydown",e=>{if([KEY.UP,KEY.DOWN].includes(e.keyCode)){e.preventDefault();constcurrentValue=isNaN(parseFloat(e.target.value))?parseFloat(e.target.getAttribute("min"))||0:parseFloat(e.target.value);constdirection=e.keyCode===KEY.UP?1:-1;constmodifier=(isMac?e.metaKey:e.ctrlKey)?100:e.shiftKey?10:e.altKey?0.1:1;constdecimals=Math.max((currentValue.toString().split(".")[1]||"").length,e.altKey?1:0);constnewValue=currentValue+direction*modifier;e.target.value=newValue.toFixed(decimals);}});这段代码有些部分可能不太好理解,我们一行一行看一下,理解其中的意思。constisMac=navigator.platform==='MacIntel';constKEY={向上:38,向下:40,};在Windows和Linux中,ctrl是我们要使用的键,但在Mac上更常用的是cmd。isMac是一个布尔值,表示是Mac系统还是Windows系统。您在键盘上按下的每个键都有一个唯一的键码。向上箭头键是38,向下箭头键是40。由于我不喜欢代码中的魔术数字,所以我们将它们存储在一个对象中以备后用。document.querySelector('input').addEventListener('keydown',e=>{...}然后监听input的keydown事件,keydown可以告诉我们按下了哪个键,按下了哪个修改键。我们欣赏了感兴趣的修饰键是shift、alt、ctrl和cmd。metaKey对应于Mac上的cmd键和Windows上的windows键。if([KEY.UP,KEY.DOWN].includes(e.keyCode)){e.preventDefault();...}如果用户按下左键或右键,我们什么也不做。我们在代码周围添加了一个if子句,以便它仅在用户按下上键或下键时执行。用户按下向上或向下键,我们调用e.preventDefault()。这可以防止输入被更新,因为我们会自己做。constcurrentValue=isNaN(parseFloat(e.target.value))?parseFloat(e.target.getAttribute("min"))||0:parseFloat(e.target.value);w你可能认为获取值和获取e.target.value一样简单,但是,我们还需要做更多的工作。e.target.value始终是字符串,即使对于npmber类型的输入元素也是如此,因此要进行任何数学运算,我们需要将其转换为数字。因为我们需要能够加/减0.1,所以我们需要使用浮点数而不是整数。是的,如果输入为空,我们调用parseFloat,它返回一个NaN值。由于我们不能添加或减去NaN,因此我们需要检查一些时间。如果输入为空,那么我们将获取最小值(如果存在),否则默认为0。最小值也是一个字符串,因此我们也需要对其进行转换。如果min属性未定义,则变为NaN,而NaN||0解析为0,因此结果是可计算的。constdirection=e.keyCode===KEY.UP?1:-1;从if子句中,我们已经知道用户按下的是向上键还是向下键,所以我们需要检查用户按下的是向上键还是向下键,从而判断是否需要加减。我们将它存储在变量“direction”中,如果向上则值为1,如果向下则为-1,然后我们可以将它与未来的值相乘。const修饰符=(isMac?e.metaKey:e.ctrlKey)?100:e.shiftKey?10:e.altKey?0.1:1;我们找出按下了哪个修饰键。事件属性可以告诉我们。如果我们在按向上或向下键的同时按下shift或alt键,则e.shiftKey、e.altKey的值为true。我们首先使用(isMac?e.metaKey:e.ctrlKey)来检查元键或ctrl键,这取决于我们是否在Mac上。如果是,我们加或减100。如果我们按Shift键,我们加或减10,如果我们按Alt键,我们加0.1。如果没有按下这些键,则按“默认”行为递增或递减1。constdecimals=Math.max((currentValue.toString().split(".")[1]||"").length,e.altKey?1:0);这里有点棘手,因为我们使用的是floats。由于四舍五入,JavaScript中的浮点数可能会产生意想不到的结果。具体来说,如果您添加例如0.1`和0.2,你得到的值是0.30000000000000004,大约是0.3`。做基本计算的时候0的个数太多了,不过没关系,0.3000000000000000004在一个输入元素里看起来不太好。我们只需要0.3。为此,我们需要在计算前知道最大小数位数是多少,也就是当前输入的小数位数,或者按下alt键时的1,取大者。我们存储此值供以后使用。constnewValue=currentValue+direction*modifier;这是最终的结果值。我们知道当前值,增加或减少的数量,以及是否需要增加或减少。我们将修饰符(要添加的数量)乘以方向(即+1或-1),以便我们可以在将其添加到当前值时进行添加或减去。现在我们已经计算出新值,但是由于前面提到的可能很奇怪的舍入,我们不能将它设置为新值作为输入值,因为它可能有很多小数。相反,我们将toFixed与我们之前找到的小数位数一起使用e.target.value=newValue.toFixed(decimals);这就是所有的代码。此输入允许用户快速递增或递减一个值,或精确地锁定一个数字,具体取决于用户按下的修改键。编辑过程中可能存在的BUG无法实时获知。之后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的BUG监控工具Fundebug。原文:https://kilianvalkhof.com/202...每周更新交流文章。可以微信搜索【大千世界】第一时间阅读,回复【福利】还有很多前端视频等着你。本文在GitHub上https://github.com/qq449245884/xiaozhi已收录,欢迎Star。
