513 lines
19 KiB
HTML
513 lines
19 KiB
HTML
<!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> |