前言:最近接手了一个10年的老前端项目,使用D-cloud MUI 开发的H5+ App(纯js+html+css),讲真,除了N年前自学前端的时候写过几个demo,后来在没码过原生的代码了
上需求:
一个车牌号输入功能,前身是 input实现的没有任何限制,现场(给物流仓库使用的)用起来随意输入,容易输错,要求改进,那来吧一句话的需求,开发跑断腿(没有交互,没有UI,都是前端的活)
先给大家看下实现效果
代码部分
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./index.css" />
<script src="./index.js" defer></script>
</head>
<body>
<div class="license-plate-keyboard">
<div class="license-input-container">
<!-- 创建七个输入框 -->
<div class="license-input" data-index="0" id="char1"></div>
<div class="license-input" data-index="1" id="char2"></div>
<div class="license-input" data-index="2" id="char3"></div>
<div class="license-input" data-index="3" id="char4"></div>
<div class="license-input" data-index="4" id="char5"></div>
<div class="license-input" data-index="5" id="char6"></div>
<div class="license-input" data-index="6" id="char7"></div>
<div
class="license-input default-content last-input"
data-index="7"
id="char8"
></div>
</div>
<div class="keyboard hidden" id="customKeyboard">
<div id="provinces" class="keyboard-grid">
<!-- 省份 -->
</div>
<div id="letters" class="keyboard-grid">
<!-- 字母 -->
</div>
<div id="digits" class="keyboard-grid-num keyboard-grid">
<!-- 数字 -->
</div>
<div class="keyboard-controls">
<button id="toggle-language">切换中文/英文</button>
<button id="delete-btn">删除</button>
</div>
</div>
</div>
</body>
</html>
CSS
.license-plate-keyboard {
width: 100%;
/* max-width: 400px; */
margin: 20px auto;
color: #000;
}
.license-input-container {
display: flex;
justify-content: space-between;
/* margin-bottom: 15px; */
}
.license-input {
width: 32px !important;
height: 32px !important;
line-height: 32px;
text-align: center;
font-size: 18px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f8f8f8;
}
.license-input:first-child {
width: 32px;
height: 32px;
text-align: center;
font-size: 18px;
/* color: #FFF; */
border: 1px solid #ccc;
border-radius: 5px;
background-color: #1890ff;
}
.default-content::before {
content: "新"; /* 提示的默认内容 */
color: #79e951; /* 提示文字颜色 */
}
.keyboard {
display: flex;
flex-direction: column;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
border-top: 1px solid #ccc;
padding: 32px 12px 12px;
z-index: 99;
}
.hidden {
display: none;
}
.keyboard-grid {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 10px;
}
.keyboard-grid-num {
display: grid;
grid-template-columns: repeat(10, 1fr);
gap: 10px;
margin-bottom: 10px;
}
.keyboard-grid button {
width: 100%;
height: 40px;
font-size: 14px;
text-align: center;
background-color: #f0f0f0;
border: 1px solid #ddd;
border-radius: 5px;
cursor: pointer;
}
.keyboard-grid button:hover {
background-color: #e0e0e0;
}
.keyboard-controls {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-top: 10px;
}
.keyboard-controls button {
flex: 1;
padding: 10px;
font-size: 16px;
background-color: #1890ff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.keyboard-controls button:hover {
background-color: #40a9ff;
}
Js
const provinces = ["京", "津", "渝", "沪", "冀", "晋", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "琼", "川", "贵", "云", "陕", "甘", "青", "蒙", "桂", "宁", "新", "藏", "使", "领", "警", "学", "港", "澳"];
const letters = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
let currentLanguage = 'zh'; // 当前语言模式 'zh'为中文,'en'为英文
let lastFocusedInput = null; // 记录最后聚焦的输入框
const inputBoxes = document.querySelectorAll(".license-input"); // 所有输入框
const keyboard = document.getElementById("customKeyboard"); // 键盘容器
// 根据输入框索引切换语言
function toggleLanguageBasedOnInput(index) {
const newLanguage = index === 0 ? 'zh' : 'en';
if (currentLanguage !== newLanguage) {
currentLanguage = newLanguage;
updateKeyboard();
}
}
// 显示键盘
function showKeyboard() {
if (keyboard.classList.contains("hidden")) {
keyboard.classList.remove("hidden");
console.log("Keyboard shown");
}
}
// 隐藏键盘
function hideKeyboard() {
if (!keyboard.classList.contains("hidden")) {
keyboard.classList.add("hidden");
}
}
// 初始化事件监听
function initializeInputEvents() {
inputBoxes.forEach((box, index) => {
// 设置点击时显示键盘并切换语言
box.addEventListener("click", (event) => {
lastFocusedInput = box;
toggleLanguageBasedOnInput(index); // 根据输入框索引切换语言
showKeyboard(); // 显示键盘
event.stopPropagation(); // 防止触发文档点击事件
});
// 保存最后聚焦的输入框
box.addEventListener("focus", (event) => {
lastFocusedInput = event.target; // 记录当前聚焦的输入框
});
});
// 点击文档其他区域隐藏键盘
document.addEventListener("click", hideKeyboard);
// 防止点击键盘本身隐藏
keyboard.addEventListener("click", (event) => event.stopPropagation());
}
// 更新键盘内容
function updateKeyboard() {
// 获取id为provinces的元素
const provinceRow = document.getElementById('provinces');
// 获取id为letters的元素
const letterRow = document.getElementById('letters');
provinceRow.innerHTML = '';
letterRow.innerHTML = '';
const keys = currentLanguage === 'zh' ? provinces : letters;
keys.forEach((key) => {
const button = createKeyboardButton(key); // // 创建键盘按钮
currentLanguage === 'zh' ? provinceRow.appendChild(button) : letterRow.appendChild(button);
});
}
// 创建键盘按钮
function createKeyboardButton(content) {
const button = document.createElement('button');
button.textContent = content;
button.addEventListener('click', () => appendLicensePlate(content));
return button;
}
// 填充字符到输入框
function appendLicensePlate(char) {
if (!lastFocusedInput) return;
if (lastFocusedInput.classList.contains('default-content')) {
lastFocusedInput.classList.remove('default-content');
}
lastFocusedInput.textContent = char;
// 自动切换为英文键盘后移动到下一个输入框
if (currentLanguage === 'zh') {
currentLanguage = 'en';
updateKeyboard();
}
const nextInput = lastFocusedInput.nextElementSibling;
if (nextInput && nextInput.classList.contains('license-input')) {
lastFocusedInput = nextInput;
}
}
// 删除最后一个字符
function deleteLicensePlate() {
if (!lastFocusedInput) return;
if (!lastFocusedInput.classList.contains('default-content') && lastFocusedInput.classList.contains('last-input')) {
lastFocusedInput.classList.add('default-content');
}
// 当前输入框为空时,聚焦到前一个输入框
if (!lastFocusedInput.textContent && lastFocusedInput.previousElementSibling?.classList.contains('license-input')) {
lastFocusedInput = lastFocusedInput.previousElementSibling;
}
// 清除当前焦点输入框的值
lastFocusedInput.textContent = '';
}
// 获取车牌号
function getLicensePlate() {
return Array.from(inputBoxes).map((input) => input.textContent.trim()).join('');
}
// 删除按钮事件
document.getElementById('delete-btn').addEventListener('click', deleteLicensePlate);
// 切换语言按钮事件
document.getElementById('toggle-language').addEventListener('click', () => {
currentLanguage = currentLanguage === 'zh' ? 'en' : 'zh';
updateKeyboard();
});
// 初始化键盘和输入框
document.addEventListener("DOMContentLoaded", () => {
initializeInputEvents();
updateKeyboard();
});