1、使用 span + input 标签实现

设计思路:

  • 使用一个透明的 input 组件来接收验证码
  • 利用 onkeyup 事件,将 input 中的数字写入到 span 中(span的个数和验证码的数量一致)

事件处理:

  • 屏蔽input输入框的所有事件(这里是将input的高度置0),让用户点不到这个input
  • 动态给span标签添加click事件,并且保证一组span中只能有一个持有click事件

效果如下:

javascript输入框实例 js输入框代码_html

代码实现:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title></title>
	<style type="text/css">
		body{
			height: 100vh;
			display: flex;
			justify-content: center;
			align-items: center;
		}
		div{
			position: relative;
		}
		div span{
			display: block;
			float: left;
			margin: 0 0.3125rem;
			width: 2.1875rem;
			height: 2.1875rem;
			line-height: 2.1875rem;
			border: 2px solid black;
			text-align: center;
			border-radius: 0.3125rem;
		}
		div>span:nth-child(1){
			border-color: orange;
		}
		/* 将input隐藏起来 */
		div input{
			width: 0.0625rem;
			height: 0;
			line-height: 1.875rem;
			font-size: 0.5rem;
			position: absolute;
			left: 0.3125rem;
			opacity: 0;
			/* 给他一个层级保证无法点到input */
			z-index: -5;
		}
	</style>
</head>
<body>
	<div>
		<span></span>
		<span></span>
		<span></span>
		<span></span>
		<span></span>
		<span></span>
		<input type="number" oninput="if(value.length>6)value=value.slice(0,6)" checked="checked" onkeyup="showText(this.value)" autofocus="autofocus"/>
	</div>
	<script type="text/javascript">
		window.onload=function(){
			document.getElementsByTagName("span")[0].addEventListener("click",gotFocus)
		}
		function showText(value){
			var cur = document.getElementsByTagName("span")[value.length];
			var pre = document.getElementsByTagName("span")[value.length-1];
			var next = document.getElementsByTagName("span")[value.length+1];
			if(cur){
				cur.innerHTML = "";
				cur.style.borderColor = "orange";
				cur.addEventListener("click",gotFocus);
			}
			if(pre){
				pre.innerHTML = value.charAt(value.length-1);
				pre.style.borderColor = "black";
				pre.removeEventListener("click",gotFocus);
			}
			if(next){
				next.innerHTML = "";
				next.style.borderColor = "black";
				next.removeEventListener("click",gotFocus);
			}
		}
		function gotFocus(e){
			e.stopPropagation();
			document.getElementsByTagName("input")[0].focus();
		}
	</script>
</body>
</html>

注:不可以直接复制验证码粘贴,可以通过修改showText的逻辑来实现复制粘贴验证码

2、使用多个 input 标签实现

设计思路:

  • 根据需要选择多个input标签存放验证码的每一位数字,需要获取多个输入框的数字拼接为最终验证码。

事件处理:

  • 一组input保证只有0个或1个input能够获得焦点
  • 获得焦点的input的value一定为空
  • 根据是否点击删除(keyCode为8)按钮,来确定光标移动方向

效果演示:

javascript输入框实例 js输入框代码_html_02

代码实现:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title></title>
	<style type="text/css">	
		body{
				height: 100vh;
				display: flex;
				justify-content: center;
				align-items: center;
		}
		/* 每一个input输入框的样式 */
		div input{
			width: 2.375rem;
			height: 2.375rem;
			line-height: 2.375rem;
			text-align: center;
			background-color: #eeeeee;
			margin: 0 0.3125rem;
			border-radius: 0.625rem;
			border: none;
		}
		div input:focus{
			/* 去掉input框获得焦点时的外边框 */
			outline: none;
		}
	</style>
</head>
<body>
	<div>
		<!-- number保证输入框获取焦点,拉起的是数字键盘 -->
		<!-- oninput保证输入的是纯数字 -->
		<!-- autofocus设置第一个input自动获得焦点 -->
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()" autofocus="autofocus"/>
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()">
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()">
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()">
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()">
		<input type="number" oninput="value=value.replace(/[^\d]/g,'')" onkeyup="moveCursor()">
	</div>
	<script type="text/javascript">
		
		var index = 0;	//标识哪一个input框获得焦点(光标),获得焦点的input框value值为空
		var key;
		// 获取用户每一次点击键盘的按键值 => 按键值为8时为删除键
		document.onkeydown=function(event){
		  key = event.keyCode;
		}; 
		window.onload=function(){
			// 除了第一个input,其他input无法获取焦点
			var arr = document.getElementsByTagName("input");
			for(var i = 1; i < arr.length; i++){
				arr[i].addEventListener("focus",forbidFoucs);
			}
		};
		function moveCursor(){
			var pre = document.getElementsByTagName("input")[index];
			if(key != 8 && pre.value.length != 0){
				// 若用户点击的是删除键,或者其他非数字按键(非数字按键不会改变input输入框中的value)=> input的焦点需要后移,同时让前一个input无法获取焦点
				pre.addEventListener("focus",forbidFoucs)
				if(index < 5) {
					// 光标最远只能移动到最后一个input,也就是 index 为 5 指向的input
					var obj = document.getElementsByTagName("input")[++index];
					obj.removeEventListener("focus",forbidFoucs);
					obj.focus();
				}else{
					// 当 index 走到 6 时,就需要让最后一个input失去焦点
					pre.blur();
					/**
					 * 此处写业务逻辑代码………………………………
					 */
				}
			}else{
				pre.addEventListener("focus",forbidFoucs);
				if(index > 0){
					// 当用户点击删除按钮的时候,需要删除前一个input中的内容,并将光标前移(限制光标不可跑飞)
					var obj = document.getElementsByTagName("input")[--index];
					obj.removeEventListener("focus",forbidFoucs);
					obj.value = "";
					obj.focus();
				}
			}
		}
		// 禁止用户通过点击获取input的焦点
		function forbidFoucs(){
			console.log(this)
			this.blur();
		}
	</script>
</body>
</html>

注:所有代码在Android手机上已完成测试。