111 lines
4.8 KiB
HTML
111 lines
4.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Статистика кликов</title>
|
||
<style>
|
||
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7}
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
|
||
.container{max-width:1140px;margin:0 auto;padding:80px 24px}
|
||
.hero{background:var(--ink);color:var(--white)}
|
||
.hero h1{font-size:56px;font-weight:800;line-height:1.05;margin-bottom:24px}
|
||
.hero p{font-size:20px;color:#9aa3b2;max-width:600px;margin-bottom:32px}
|
||
.btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:14px 28px;border-radius:8px;font-weight:700;text-decoration:none;cursor:pointer;margin:4px}
|
||
.section h2{font-size:36px;font-weight:700;margin-bottom:24px}
|
||
.card{background:var(--gray-100);border-radius:16px;padding:32px;margin-bottom:16px}
|
||
@media (max-width:640px){.hero h1{font-size:36px}.section h2{font-size:28px}.container{padding:48px 20px}}
|
||
.counter{margin-left:8px;font-weight:700;color:var(--cyan)}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<section class="hero"><div class="container">
|
||
<h1>Сбор статистики нажатий</h1>
|
||
<p>Нажимайте на кнопки — счётчик будет сохраняться в браузере.</p>
|
||
<div style="margin-top:12px;">
|
||
<label for="userInput" style="margin-right:8px;">Пользователь:</label>
|
||
<input id="userInput" type="text" placeholder="Введите имя" style="padding:4px 8px; border:1px solid var(--gray-500); border-radius:4px;">
|
||
<button id="setUserBtn" class="btn" style="padding:4px 12px; font-size:14px;">Установить</button>
|
||
</div>
|
||
</div></section>
|
||
<section class="section"><div class="container">
|
||
<h2>Кнопки</h2>
|
||
<div id="buttons"></div>
|
||
<div id="aggregation" style="margin-top:24px;"></div>
|
||
</div></section>
|
||
<script>
|
||
// Список кнопок, которые нужно отслеживать
|
||
const buttonLabels = ['Кнопка A', 'Кнопка B', 'Кнопка C'];
|
||
// Ключ в localStorage для всех статистик
|
||
const storageKey = 'clickStats';
|
||
// Текущий пользователь (по умолчанию «guest»)
|
||
let currentUser = localStorage.getItem('currentUser') || 'guest';
|
||
// Объект {user: {label: count}}
|
||
let allStats = JSON.parse(localStorage.getItem(storageKey)) || {};
|
||
// Инициализируем запись для текущего пользователя, если её нет
|
||
if (!allStats[currentUser]) {
|
||
allStats[currentUser] = {};
|
||
buttonLabels.forEach(label => allStats[currentUser][label] = 0);
|
||
}
|
||
// Убедимся, что у всех пользователей присутствуют новые кнопки
|
||
Object.values(allStats).forEach(userStats => {
|
||
buttonLabels.forEach(label => {
|
||
if (!(label in userStats)) userStats[label] = 0;
|
||
});
|
||
});
|
||
localStorage.setItem(storageKey, JSON.stringify(allStats));
|
||
const container = document.getElementById('buttons');
|
||
function renderButtons() {
|
||
container.innerHTML = '';
|
||
buttonLabels.forEach((label, i) => {
|
||
const btn = document.createElement('button');
|
||
btn.className = 'btn';
|
||
btn.textContent = label;
|
||
const cnt = document.createElement('span');
|
||
cnt.className = 'counter';
|
||
cnt.id = 'cnt-' + i;
|
||
cnt.textContent = allStats[currentUser][label];
|
||
btn.addEventListener('click', () => {
|
||
allStats[currentUser][label]++;
|
||
cnt.textContent = allStats[currentUser][label];
|
||
localStorage.setItem(storageKey, JSON.stringify(allStats));
|
||
renderAggregation();
|
||
});
|
||
container.appendChild(btn);
|
||
container.appendChild(cnt);
|
||
});
|
||
}
|
||
function renderAggregation() {
|
||
const aggDiv = document.getElementById('aggregation');
|
||
const totals = {};
|
||
buttonLabels.forEach(label => totals[label] = 0);
|
||
Object.values(allStats).forEach(userStats => {
|
||
buttonLabels.forEach(label => {
|
||
totals[label] += userStats[label] || 0;
|
||
});
|
||
});
|
||
aggDiv.innerHTML = '<h3>Общая статистика</h3>' +
|
||
buttonLabels.map(label => `<div>${label}: <span class="counter">${totals[label]}</span></div>`).join('');
|
||
}
|
||
// UI для установки пользователя
|
||
document.getElementById('setUserBtn').addEventListener('click', () => {
|
||
const input = document.getElementById('userInput').value.trim();
|
||
if (input) {
|
||
currentUser = input;
|
||
localStorage.setItem('currentUser', currentUser);
|
||
if (!allStats[currentUser]) {
|
||
allStats[currentUser] = {};
|
||
buttonLabels.forEach(label => allStats[currentUser][label] = 0);
|
||
}
|
||
renderButtons();
|
||
renderAggregation();
|
||
}
|
||
});
|
||
// Initial render
|
||
renderButtons();
|
||
renderAggregation();
|
||
</script>
|
||
</body>
|
||
</html>
|