264 lines
7.7 KiB
HTML
264 lines
7.7 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
<title>输入框自动全选和放大提示</title>
|
|||
|
<style>
|
|||
|
/* 基本样式 */
|
|||
|
body {
|
|||
|
font-family: Arial, sans-serif;
|
|||
|
padding: 20px;
|
|||
|
}
|
|||
|
|
|||
|
input {
|
|||
|
width: 200px;
|
|||
|
padding: 10px;
|
|||
|
font-size: 16px;
|
|||
|
border: 1px solid #ccc;
|
|||
|
border-radius: 5px;
|
|||
|
margin-bottom: 10px;
|
|||
|
text-align: right;
|
|||
|
}
|
|||
|
|
|||
|
input:focus {
|
|||
|
color: black;
|
|||
|
}
|
|||
|
|
|||
|
/* 提示数字样式 */
|
|||
|
.number-tip {
|
|||
|
position: absolute;
|
|||
|
font-size: 36px;
|
|||
|
font-weight: bold;
|
|||
|
color: #333;
|
|||
|
background: rgba(255, 255, 255, 0.9);
|
|||
|
border: 1px solid #ccc;
|
|||
|
padding: 10px;
|
|||
|
border-radius: 10px;
|
|||
|
transform: scale(1);
|
|||
|
opacity: 1;
|
|||
|
transition: opacity 0.5s ease, transform 0.5s ease;
|
|||
|
pointer-events: none;
|
|||
|
}
|
|||
|
|
|||
|
.number-tip.hide {
|
|||
|
opacity: 0;
|
|||
|
transform: scale(0.5);
|
|||
|
}
|
|||
|
|
|||
|
/* 颜色样式 */
|
|||
|
.color-0 {
|
|||
|
color: #153fea;
|
|||
|
}
|
|||
|
|
|||
|
.color-1 {
|
|||
|
color: #15f00e;
|
|||
|
}
|
|||
|
|
|||
|
.color-2 {
|
|||
|
color: #6963688a;
|
|||
|
}
|
|||
|
|
|||
|
/* 错误状态样式 */
|
|||
|
.number-tip.error {
|
|||
|
background: rgba(255, 200, 200, 0.9);
|
|||
|
border-color: #ff0000;
|
|||
|
}
|
|||
|
</style>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<input type="text" placeholder="请输入数字 1">
|
|||
|
<input type="text" placeholder="请输入数字 2">
|
|||
|
<input type="text" placeholder="请输入数字 3">
|
|||
|
<div id="numberTip" class="number-tip hide"></div>
|
|||
|
|
|||
|
<script>
|
|||
|
// 获取所有的输入框和提示元素
|
|||
|
const inputBoxes = document.querySelectorAll('input[type="text"]');
|
|||
|
const numberTip = document.getElementById('numberTip');
|
|||
|
|
|||
|
// 添加输入范围配置
|
|||
|
const inputRanges = {
|
|||
|
0: { min: 0, max: 100 }, // 第一个输入框:0-100
|
|||
|
1: { min: 100, max: 1000 }, // 第二个输入框:100-1000
|
|||
|
2: { min: 1000, max: 10000 } // 第三个输入框:1000-10000
|
|||
|
};
|
|||
|
|
|||
|
// 为所有输入框添加事件监听
|
|||
|
inputBoxes.forEach((inputBox, index) => {
|
|||
|
// 输入框获取焦点时
|
|||
|
inputBox.addEventListener('focus', (event) => {
|
|||
|
event.target.select();
|
|||
|
const value = event.target.value;
|
|||
|
if (value !== '') {
|
|||
|
const rawValue = value.replace(/\s/g, '');
|
|||
|
showNumberTip(formatNumberWithColor(rawValue), inputBox, index);
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
inputBox.addEventListener('input', (event) => {
|
|||
|
const value = event.target.value;
|
|||
|
if (value !== '') {
|
|||
|
const rawValue = value.replace(/\s/g, '');
|
|||
|
const numValue = parseFloat(rawValue);
|
|||
|
const range = inputRanges[index];
|
|||
|
|
|||
|
// 只检查最大值,允许临时小于最小值
|
|||
|
if (!isNaN(numValue) && numValue <= range.max) {
|
|||
|
// 保存有效值
|
|||
|
event.target.value = formatNumber(rawValue);
|
|||
|
event.target.dataset.lastValidValue = event.target.value;
|
|||
|
// 显示放大提示
|
|||
|
showNumberTip(formatNumberWithColor(rawValue), inputBox, index, false);
|
|||
|
} else if (!isNaN(numValue) && numValue > range.max) {
|
|||
|
// 如果超出最大值,显示错误提示
|
|||
|
showNumberTip(
|
|||
|
`超出最大值 ${range.max}`,
|
|||
|
inputBox,
|
|||
|
index,
|
|||
|
true
|
|||
|
);
|
|||
|
// 还原到上一个有效值或清空
|
|||
|
if (event.target.dataset.lastValidValue) {
|
|||
|
event.target.value = event.target.dataset.lastValidValue;
|
|||
|
} else {
|
|||
|
event.target.value = '';
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// 输入框失去焦点时
|
|||
|
inputBox.addEventListener('blur', (event) => {
|
|||
|
const value = event.target.value;
|
|||
|
let finalValue = value;
|
|||
|
|
|||
|
// 处理小数点
|
|||
|
if (value.includes('.')) {
|
|||
|
const [integerPart, decimalPart] = value.split('.');
|
|||
|
if (!decimalPart || decimalPart.replace(/[^\d]/g, '').length === 0) {
|
|||
|
finalValue = integerPart;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 检查最小值
|
|||
|
if (finalValue !== '') {
|
|||
|
const numValue = parseFloat(finalValue.replace(/\s/g, ''));
|
|||
|
const range = inputRanges[index];
|
|||
|
|
|||
|
if (!isNaN(numValue)) {
|
|||
|
if (numValue < range.min) {
|
|||
|
// 如果小于最小值,显示错误提示
|
|||
|
showNumberTip(
|
|||
|
`不能小于最小值 ${range.min}`,
|
|||
|
inputBox,
|
|||
|
index,
|
|||
|
true
|
|||
|
);
|
|||
|
// 清空输入或设置为最小值
|
|||
|
event.target.value = '';
|
|||
|
} else if (numValue <= range.max) {
|
|||
|
// 值在有效范围内
|
|||
|
event.target.value = finalValue;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 2秒后隐藏提示
|
|||
|
setTimeout(() => {
|
|||
|
numberTip.classList.add('hide');
|
|||
|
}, 2000);
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
// 修改数字格式化函数,移除输入框的颜色格式化
|
|||
|
function formatNumber(value) {
|
|||
|
// 分割整数部分和小数部分
|
|||
|
const [integerPart, decimalPart] = value.split('.');
|
|||
|
|
|||
|
// 格式化整数部分,只添加空格,不添加颜色
|
|||
|
const formattedInteger = integerPart
|
|||
|
.replace(/[^\d]/g, '')
|
|||
|
.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
|
|||
|
|
|||
|
// 格式化小数部分,只添加空格,不添加颜色
|
|||
|
if (decimalPart !== undefined) {
|
|||
|
const formattedDecimal = decimalPart
|
|||
|
.replace(/[^\d]/g, '')
|
|||
|
.replace(/(\d{3})/g, '$1 ')
|
|||
|
.trim();
|
|||
|
return `${formattedInteger}.${formattedDecimal}`;
|
|||
|
}
|
|||
|
|
|||
|
return formattedInteger;
|
|||
|
}
|
|||
|
|
|||
|
// 修改彩色格式化函数
|
|||
|
function formatNumberWithColor(value) {
|
|||
|
if (!value.includes('.')) {
|
|||
|
// 如果没有小数点,从右向左添加颜色
|
|||
|
return value
|
|||
|
.replace(/[^\d]/g, '')
|
|||
|
.replace(/\B(?=(\d{3})+(?!\d))/g, ' ')
|
|||
|
.split(' ')
|
|||
|
.map((group, index, array) => `<span class="color-${(array.length - 1 - index) % 3}">${group}</span>`)
|
|||
|
.join(' ');
|
|||
|
}
|
|||
|
|
|||
|
// 有小数点的情况
|
|||
|
const [integerPart, decimalPart] = value.split('.');
|
|||
|
|
|||
|
// 整数部分:从右向左添加颜色
|
|||
|
const coloredInteger = integerPart
|
|||
|
.replace(/[^\d]/g, '')
|
|||
|
.replace(/\B(?=(\d{3})+(?!\d))/g, ' ')
|
|||
|
.split(' ')
|
|||
|
.map((group, index, array) => `<span class="color-${(array.length - 1 - index) % 3}">${group}</span>`)
|
|||
|
.join(' ');
|
|||
|
|
|||
|
// 小数部分:从左向右添加颜色
|
|||
|
const coloredDecimal = decimalPart
|
|||
|
.replace(/[^\d]/g, '')
|
|||
|
.replace(/(\d{3})/g, '$1 ')
|
|||
|
.trim()
|
|||
|
.split(' ')
|
|||
|
.map((group, index) => `<span class="color-${index % 3}">${group}</span>`)
|
|||
|
.join(' ');
|
|||
|
|
|||
|
return `${coloredInteger}.${coloredDecimal}`;
|
|||
|
}
|
|||
|
|
|||
|
// 添加一个变量来存储定时器
|
|||
|
let hideTimer;
|
|||
|
|
|||
|
// 更新显示提示的函数
|
|||
|
function showNumberTip(value, inputBox, index, isError = false) {
|
|||
|
if (hideTimer) {
|
|||
|
clearTimeout(hideTimer);
|
|||
|
}
|
|||
|
|
|||
|
numberTip.innerHTML = value;
|
|||
|
numberTip.classList.toggle('error', isError);
|
|||
|
|
|||
|
const rect = inputBox.getBoundingClientRect();
|
|||
|
const tipRect = numberTip.getBoundingClientRect();
|
|||
|
|
|||
|
|
|||
|
let left = rect.left;
|
|||
|
let top = rect.bottom;
|
|||
|
if (top + tipRect.height > window.innerHeight) {
|
|||
|
top = rect.top - tipRect.height;
|
|||
|
}
|
|||
|
|
|||
|
numberTip.style.left = `${left}px`;
|
|||
|
numberTip.style.top = `${top}px`;
|
|||
|
numberTip.classList.remove('hide');
|
|||
|
|
|||
|
hideTimer = setTimeout(() => {
|
|||
|
numberTip.classList.add('hide');
|
|||
|
}, 6000);
|
|||
|
}
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|