Realtek/doc/buttonClickDemo.html

513 lines
19 KiB
HTML
Raw Permalink Normal View History

2025-11-25 10:21:47 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>短按检测演示 - 1下、2下、10下</title>
<style>
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
background-color: #f5f5f5;
color: #333;
}
.container {
text-align: center;
background-color: white;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
padding: 30px;
max-width: 600px;
width: 90%;
}
h1 {
color: #2c3e50;
margin-bottom: 10px;
}
h2 {
color: #3498db;
margin-top: 0;
font-size: 1.2em;
font-weight: normal;
}
.button-container {
margin: 30px 0;
}
#clickButton {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 50%;
width: 180px;
height: 180px;
font-size: 24px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 8px 15px rgba(102, 126, 234, 0.3);
transition: all 0.2s ease;
outline: none;
position: relative;
overflow: hidden;
}
#clickButton:hover {
transform: translateY(-3px);
box-shadow: 0 12px 20px rgba(102, 126, 234, 0.4);
}
#clickButton:active {
transform: translateY(1px);
box-shadow: 0 4px 10px rgba(102, 126, 234, 0.3);
}
#clickButton.down {
transform: scale(0.95);
background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
}
.info-panel {
display: flex;
justify-content: space-between;
margin: 30px 0;
flex-wrap: wrap;
gap: 20px;
}
.info-card {
background-color: #f8f9fa;
border-radius: 8px;
padding: 20px;
flex: 1;
min-width: 150px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.info-card h3 {
margin: 0 0 10px 0;
color: #495057;
font-size: 1em;
}
.info-card .value {
font-size: 1.8em;
font-weight: bold;
color: #3498db;
}
.log-panel {
background-color: #2d3748;
color: #e2e8f0;
border-radius: 8px;
padding: 20px;
max-height: 300px;
overflow-y: auto;
font-family: monospace;
font-size: 14px;
margin-top: 20px;
width: 100%;
}
.log-entry {
margin: 5px 0;
padding: 3px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.log-entry.info { color: #94a3b8; }
.log-entry.event { color: #fcd34d; }
.log-entry.success { color: #4ade80; }
.log-entry.warning { color: #f97316; }
.log-entry.error { color: #f87171; }
.controls {
margin-top: 20px;
display: flex;
gap: 10px;
flex-wrap: wrap;
justify-content: center;
}
.control-btn {
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
padding: 10px 20px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.control-btn:hover {
background-color: #2980b9;
}
.settings {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #e5e7eb;
width: 100%;
}
.settings h3 {
margin: 0 0 15px 0;
color: #495057;
}
.setting-group {
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0;
flex-wrap: wrap;
gap: 10px;
}
.setting-group label {
font-size: 14px;
color: #666;
min-width: 180px;
}
.setting-group input {
padding: 5px 10px;
border: 1px solid #ddd;
border-radius: 4px;
width: 100px;
}
@media (max-width: 480px) {
#clickButton {
width: 150px;
height: 150px;
font-size: 20px;
}
.info-panel {
flex-direction: column;
}
.info-card {
min-width: auto;
}
}
</style>
</head>
<body>
<div class="container">
<h1>短按检测演示</h1>
<h2>测试短按1下、短按2下和短按10下的效果</h2>
<div class="button-container">
<button id="clickButton">点击我</button>
</div>
<div class="info-panel">
<div class="info-card">
<h3>当前点击次数</h3>
<div id="currentCount" class="value">0</div>
</div>
<div class="info-card">
<h3>检测到的操作</h3>
<div id="detectedAction" class="value">--</div>
</div>
<div class="info-card">
<h3>操作次数</h3>
<div id="actionCounts" class="value">0</div>
</div>
</div>
<div class="controls">
<button class="control-btn" id="simulateSingle">模拟单击</button>
<button class="control-btn" id="simulateDouble">模拟双击</button>
<button class="control-btn" id="simulateTen">模拟十连击</button>
<button class="control-btn" id="resetCounter">重置计数</button>
</div>
<div class="settings">
<h3>参数设置</h3>
<div class="setting-group">
<label for="clickTimeout">点击超时阈值 (毫秒):</label>
<input type="number" id="clickTimeout" value="300" min="50" max="1000">
</div>
<div class="setting-group">
<label for="longPressThreshold">长按判断阈值 (毫秒):</label>
<input type="number" id="longPressThreshold" value="600" min="100" max="2000">
</div>
</div>
<div class="log-panel" id="logPanel">
<div class="log-entry info">=== 短按检测系统已启动 ===</div>
</div>
</div>
<script>
// 按钮短按检测与处理类
class ButtonClickHandler {
constructor() {
// 获取DOM元素
this.button = document.getElementById('clickButton');
this.currentCountEl = document.getElementById('currentCount');
this.detectedActionEl = document.getElementById('detectedAction');
this.actionCountsEl = document.getElementById('actionCounts');
this.logPanel = document.getElementById('logPanel');
this.clickTimeoutInput = document.getElementById('clickTimeout');
this.longPressThresholdInput = document.getElementById('longPressThreshold');
// 配置参数
this.clickTimeout = parseInt(this.clickTimeoutInput.value);
this.longPressThreshold = parseInt(this.longPressThresholdInput.value);
// 状态变量
this.clickCount = 0; // 当前点击序列的点击次数
this.lastClickTime = 0; // 上次点击时间戳
this.isLongPress = false; // 是否为长按
this.isPressed = false; // 按钮是否处于按下状态
this.clickTimer = null; // 点击定时器
this.longPressTimer = null; // 长按定时器
this.actionCounts = { // 记录各操作的执行次数
single: 0,
double: 0,
ten: 0,
long: 0
};
// 绑定事件
this.setupEventListeners();
this.log('系统已初始化');
}
setupEventListeners() {
// 按钮事件
this.button.addEventListener('mousedown', () => this.onButtonDown());
this.button.addEventListener('touchstart', (e) => {
e.preventDefault(); // 防止触摸设备上的默认行为
this.onButtonDown();
});
this.button.addEventListener('mouseup', () => this.onButtonUp());
this.button.addEventListener('mouseleave', () => this.onButtonUp());
this.button.addEventListener('touchend', (e) => {
e.preventDefault();
this.onButtonUp();
});
// 模拟按钮事件
document.getElementById('simulateSingle').addEventListener('click', () => this.simulateSingleClick());
document.getElementById('simulateDouble').addEventListener('click', () => this.simulateDoubleClick());
document.getElementById('simulateTen').addEventListener('click', () => this.simulateTenClicks());
document.getElementById('resetCounter').addEventListener('click', () => this.resetCounters());
// 设置参数更新事件
this.clickTimeoutInput.addEventListener('change', () => {
this.clickTimeout = parseInt(this.clickTimeoutInput.value);
this.log(`点击超时阈值已更新为: ${this.clickTimeout}ms`);
});
this.longPressThresholdInput.addEventListener('change', () => {
this.longPressThreshold = parseInt(this.longPressThresholdInput.value);
this.log(`长按判断阈值已更新为: ${this.longPressThreshold}ms`);
});
}
// 记录日志
log(message, type = 'info') {
const logEntry = document.createElement('div');
logEntry.className = `log-entry ${type}`;
const timestamp = new Date().toLocaleTimeString();
logEntry.textContent = `[${timestamp}] ${message}`;
this.logPanel.appendChild(logEntry);
this.logPanel.scrollTop = this.logPanel.scrollHeight;
}
// 更新UI显示
updateUI() {
this.currentCountEl.textContent = this.clickCount;
// 计算总操作次数
const totalActions = this.actionCounts.single + this.actionCounts.double + this.actionCounts.ten + this.actionCounts.long;
this.actionCountsEl.textContent = totalActions;
}
// 按钮按下事件
onButtonDown() {
this.isPressed = true; // 设置按钮按下状态
this.button.classList.add('down');
this.log('按钮按下', 'event');
// 重置长按标志
this.isLongPress = false;
// 启动长按检测定时器
this.longPressTimer = setTimeout(() => {
this.isLongPress = true;
this.log('检测到长按', 'warning');
this.detectedActionEl.textContent = '长按';
this.actionCounts.long++;
this.updateUI();
this.handleLongPress();
}, this.longPressThreshold);
}
// 按钮释放事件
onButtonUp() {
// 只有在按钮确实被按下的情况下才处理释放事件
if (!this.isPressed) {
this.log('警告: 检测到无效的按钮释放事件', 'error');
return;
}
this.isPressed = false; // 重置按钮按下状态
this.button.classList.remove('down');
this.log('按钮释放', 'event');
// 清除长按定时器
if (this.longPressTimer) {
clearTimeout(this.longPressTimer);
this.longPressTimer = null;
}
// 如果不是长按,则处理短按
if (!this.isLongPress) {
this.handleShortPress();
}
}
// 处理短按
handleShortPress() {
const currentTime = Date.now();
const timeSinceLastClick = currentTime - this.lastClickTime;
// 判断是否为新的点击序列(两次点击间隔超过阈值)
if (timeSinceLastClick > this.clickTimeout) {
// 重置点击计数
this.clickCount = 1;
this.log('开始新的点击序列');
} else {
// 增加点击计数
this.clickCount++;
this.log(`点击序列计数增加到: ${this.clickCount}`);
}
// 更新上次点击时间
this.lastClickTime = currentTime;
this.updateUI();
// 清除之前的定时器
if (this.clickTimer) {
clearTimeout(this.clickTimer);
}
// 启动新的定时器,超时后处理点击序列
this.clickTimer = setTimeout(() => {
this.processClickSequence();
}, this.clickTimeout);
}
// 处理长按
handleLongPress() {
this.log('执行长按操作', 'success');
// 可以在这里添加长按的具体处理逻辑
}
// 处理点击序列
processClickSequence() {
this.log(`点击序列完成: ${this.clickCount} 次短按`, 'success');
// 根据点击次数执行不同的操作
switch (this.clickCount) {
case 1:
this.detectedActionEl.textContent = '单击';
this.actionCounts.single++;
this.handleSingleClick();
break;
case 2:
this.detectedActionEl.textContent = '双击';
this.actionCounts.double++;
this.handleDoubleClick();
break;
case 10:
this.detectedActionEl.textContent = '十连击';
this.actionCounts.ten++;
this.handleTenClicks();
break;
default:
if (this.clickCount > 2 && this.clickCount < 10) {
this.detectedActionEl.textContent = `${this.clickCount}连击`;
this.log(`检测到 ${this.clickCount} 次短按,但没有特定处理逻辑`, 'info');
} else if (this.clickCount > 10) {
this.detectedActionEl.textContent = '多次点击';
this.log(`检测到 ${this.clickCount} 次短按,次数过多`, 'warning');
}
}
this.updateUI();
// 重置点击计数
this.clickCount = 0;
// 延迟后清除显示的操作
setTimeout(() => {
this.detectedActionEl.textContent = '--';
}, 2000);
}
// 处理单击
handleSingleClick() {
this.log('执行单击操作 - 短按1下', 'success');
// 添加视觉反馈
this.button.style.backgroundColor = '#4ade80';
setTimeout(() => {
this.button.style.backgroundColor = '';
}, 300);
}
// 处理双击
handleDoubleClick() {
this.log('执行双击操作 - 短按2下', 'success');
// 添加视觉反馈
this.button.style.backgroundColor = '#3b82f6';
setTimeout(() => {
this.button.style.backgroundColor = '';
}, 300);
}
// 处理十连击
handleTenClicks() {
this.log('执行十连击操作 - 短按10下', 'success');
// 添加视觉反馈
this.button.style.backgroundColor = '#f43f5e';
setTimeout(() => {
this.button.style.backgroundColor = '';
}, 300);
}
// 模拟单次点击
simulateSingleClick() {
this.log('开始模拟单击', 'info');
this.onButtonDown();
setTimeout(() => this.onButtonUp(), 100);
}
// 模拟双击
simulateDoubleClick() {
this.log('开始模拟双击', 'info');
this.simulateSingleClick();
setTimeout(() => this.simulateSingleClick(), 150); // 两次点击间隔小于clickTimeout
}
// 模拟十连击
simulateTenClicks() {
this.log('开始模拟十连击', 'info');
for (let i = 0; i < 10; i++) {
setTimeout(() => this.simulateSingleClick(), i * 150);
}
}
// 重置计数器
resetCounters() {
this.actionCounts = {
single: 0,
double: 0,
ten: 0,
long: 0
};
this.clickCount = 0;
this.detectedActionEl.textContent = '--';
this.updateUI();
this.log('计数器已重置', 'info');
}
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
const buttonHandler = new ButtonClickHandler();
});
</script>
</body>
</html>