上传文件至 /
This commit is contained in:
44
analog-clock.html
Normal file
44
analog-clock.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>模拟时钟组件</title>
|
||||||
|
<link rel="stylesheet" href="../../assets/css/widgets.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="widget glass analog-clock-widget">
|
||||||
|
<div class="clock-face">
|
||||||
|
<div class="clock-hour"></div>
|
||||||
|
<div class="clock-minute"></div>
|
||||||
|
<div class="clock-second"></div>
|
||||||
|
<div class="clock-center"></div>
|
||||||
|
</div>
|
||||||
|
<div class="clock-label">模拟时钟</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 模拟时钟功能
|
||||||
|
function updateAnalogClock() {
|
||||||
|
const now = new Date();
|
||||||
|
const hours = now.getHours() % 12;
|
||||||
|
const minutes = now.getMinutes();
|
||||||
|
const seconds = now.getSeconds();
|
||||||
|
|
||||||
|
// 计算指针角度
|
||||||
|
const hourDegrees = (hours * 30) + (minutes * 0.5);
|
||||||
|
const minuteDegrees = (minutes * 6) + (seconds * 0.1);
|
||||||
|
const secondDegrees = seconds * 6;
|
||||||
|
|
||||||
|
// 更新指针位置
|
||||||
|
document.querySelector('.clock-hour').style.transform = 'translateX(-50%) rotate(' + hourDegrees + 'deg)';
|
||||||
|
document.querySelector('.clock-minute').style.transform = 'translateX(-50%) rotate(' + minuteDegrees + 'deg)';
|
||||||
|
document.querySelector('.clock-second').style.transform = 'translateX(-50%) rotate(' + secondDegrees + 'deg)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化时钟并每秒更新
|
||||||
|
updateAnalogClock();
|
||||||
|
setInterval(updateAnalogClock, 1000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
124
calculator.html
Normal file
124
calculator.html
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>计算器组件</title>
|
||||||
|
<link rel="stylesheet" href="../../assets/css/widgets.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="widget glass">
|
||||||
|
<h3 class="widget-title">计算器</h3>
|
||||||
|
<div class="calculator-display" id="calc-display">0</div>
|
||||||
|
<div class="calculator-buttons">
|
||||||
|
<button class="calc-btn" data-value="C">C</button>
|
||||||
|
<button class="calc-btn" data-value="+">+</button>
|
||||||
|
<button class="calc-btn" data-value="-">-</button>
|
||||||
|
<button class="calc-btn" data-value="/">/</button>
|
||||||
|
<button class="calc-btn" data-value="7">7</button>
|
||||||
|
<button class="calc-btn" data-value="8">8</button>
|
||||||
|
<button class="calc-btn" data-value="9">9</button>
|
||||||
|
<button class="calc-btn" data-value="*">*</button>
|
||||||
|
<button class="calc-btn" data-value="4">4</button>
|
||||||
|
<button class="calc-btn" data-value="5">5</button>
|
||||||
|
<button class="calc-btn" data-value="6">6</button>
|
||||||
|
<button class="calc-btn" data-value=".">.</button>
|
||||||
|
<button class="calc-btn" data-value="1">1</button>
|
||||||
|
<button class="calc-btn" data-value="2">2</button>
|
||||||
|
<button class="calc-btn" data-value="3">3</button>
|
||||||
|
<button class="calc-btn calc-equals" data-value="=">=</button>
|
||||||
|
<button class="calc-btn" data-value="0">0</button>
|
||||||
|
<button class="calc-btn" data-value="00">00</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 计算器功能
|
||||||
|
const display = document.getElementById('calc-display');
|
||||||
|
let currentValue = '0';
|
||||||
|
let previousValue = null;
|
||||||
|
let operator = null;
|
||||||
|
let resetOnNextInput = false;
|
||||||
|
|
||||||
|
function updateDisplay() {
|
||||||
|
display.textContent = currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleNumber(value) {
|
||||||
|
if (resetOnNextInput) {
|
||||||
|
currentValue = '0';
|
||||||
|
resetOnNextInput = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue === '0' && value !== '.') {
|
||||||
|
currentValue = value;
|
||||||
|
} else if (value === '.' && currentValue.includes('.')) {
|
||||||
|
// 不允许重复的小数点
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
currentValue += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOperator(nextOperator) {
|
||||||
|
const inputValue = parseFloat(currentValue);
|
||||||
|
|
||||||
|
if (operator && resetOnNextInput) {
|
||||||
|
operator = nextOperator;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousValue !== null && operator) {
|
||||||
|
try {
|
||||||
|
// 使用 Function 来安全地计算表达式
|
||||||
|
const expression = `${previousValue} ${operator} ${inputValue}`;
|
||||||
|
// 简单的安全检查
|
||||||
|
if (/^[\d\s\+\-\*\/\.]+$/.test(expression)) {
|
||||||
|
const result = new Function('return ' + expression)();
|
||||||
|
currentValue = String(result);
|
||||||
|
previousValue = result;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
currentValue = 'Error';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
previousValue = inputValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator = nextOperator;
|
||||||
|
resetOnNextInput = true;
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClear() {
|
||||||
|
currentValue = '0';
|
||||||
|
previousValue = null;
|
||||||
|
operator = null;
|
||||||
|
resetOnNextInput = false;
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事件监听
|
||||||
|
document.querySelectorAll('.calc-btn').forEach(button => {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
const value = button.getAttribute('data-value');
|
||||||
|
|
||||||
|
if (value === 'C') {
|
||||||
|
handleClear();
|
||||||
|
} else if (['+', '-', '*', '/'].includes(value)) {
|
||||||
|
handleOperator(value);
|
||||||
|
} else if (value === '=') {
|
||||||
|
handleOperator('=');
|
||||||
|
} else {
|
||||||
|
handleNumber(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
updateDisplay();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
209
calendar.html
Normal file
209
calendar.html
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>日历组件</title>
|
||||||
|
<link rel="stylesheet" href="../../assets/css/widgets.css">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="widget glass calendar-widget">
|
||||||
|
<div class="calendar-header">
|
||||||
|
<button class="calendar-nav" id="prev-month"><</button>
|
||||||
|
<h3 id="current-month-year">2024年1月</h3>
|
||||||
|
<button class="calendar-nav" id="next-month">></button>
|
||||||
|
</div>
|
||||||
|
<div class="calendar-grid">
|
||||||
|
<!-- 星期标题 -->
|
||||||
|
<div class="calendar-weekday">日</div>
|
||||||
|
<div class="calendar-weekday">一</div>
|
||||||
|
<div class="calendar-weekday">二</div>
|
||||||
|
<div class="calendar-weekday">三</div>
|
||||||
|
<div class="calendar-weekday">四</div>
|
||||||
|
<div class="calendar-weekday">五</div>
|
||||||
|
<div class="calendar-weekday">六</div>
|
||||||
|
|
||||||
|
<!-- 日期单元格将通过JavaScript动态生成 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 日历功能 - 重构版本
|
||||||
|
(function() {
|
||||||
|
let currentDate = new Date();
|
||||||
|
let selectedDate = null;
|
||||||
|
|
||||||
|
// 渲染日历函数
|
||||||
|
function renderCalendar() {
|
||||||
|
try {
|
||||||
|
const year = currentDate.getFullYear();
|
||||||
|
const month = currentDate.getMonth();
|
||||||
|
|
||||||
|
// 更新月份标题
|
||||||
|
const titleElement = document.getElementById('current-month-year');
|
||||||
|
if (titleElement) {
|
||||||
|
titleElement.textContent = `${year}年${month + 1}月`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取日历网格容器
|
||||||
|
const calendarGrid = document.querySelector('.calendar-grid');
|
||||||
|
if (!calendarGrid) {
|
||||||
|
console.error('日历网格容器未找到');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留星期标题,移除所有日期单元格
|
||||||
|
const weekdayHeaders = Array.from(calendarGrid.querySelectorAll('.calendar-weekday'));
|
||||||
|
calendarGrid.innerHTML = '';
|
||||||
|
|
||||||
|
// 重新添加星期标题
|
||||||
|
weekdayHeaders.forEach(header => calendarGrid.appendChild(header));
|
||||||
|
|
||||||
|
// 获取当月第一天和最后一天
|
||||||
|
const firstDay = new Date(year, month, 1);
|
||||||
|
const lastDay = new Date(year, month + 1, 0);
|
||||||
|
|
||||||
|
const daysInMonth = lastDay.getDate();
|
||||||
|
const startingDay = firstDay.getDay();
|
||||||
|
|
||||||
|
// 获取今天的日期用于比较
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
|
// 添加上月的最后几天
|
||||||
|
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
||||||
|
for (let i = startingDay - 1; i >= 0; i--) {
|
||||||
|
const dayDiv = createDayElement(prevMonthLastDay - i, false);
|
||||||
|
dayDiv.classList.add('other-month');
|
||||||
|
calendarGrid.appendChild(dayDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加当月的天数
|
||||||
|
for (let i = 1; i <= daysInMonth; i++) {
|
||||||
|
const dayDiv = createDayElement(i, true);
|
||||||
|
dayDiv.setAttribute('data-date', `${year}-${month + 1}-${i}`);
|
||||||
|
|
||||||
|
// 高亮今天
|
||||||
|
if (i === today.getDate() && month === today.getMonth() && year === today.getFullYear()) {
|
||||||
|
dayDiv.classList.add('today');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 高亮选中的日期
|
||||||
|
if (selectedDate && i === selectedDate.getDate() && month === selectedDate.getMonth() && year === selectedDate.getFullYear()) {
|
||||||
|
dayDiv.classList.add('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
calendarGrid.appendChild(dayDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加下月的开始几天,确保日历始终显示6行
|
||||||
|
const totalCells = 42; // 6行7列 = 42个单元格(包括星期标题)
|
||||||
|
const currentCells = 7 + startingDay + daysInMonth; // 7个星期标题 + 上月天数 + 当月天数
|
||||||
|
const remainingDays = totalCells - currentCells;
|
||||||
|
|
||||||
|
for (let i = 1; i <= remainingDays; i++) {
|
||||||
|
const dayDiv = createDayElement(i, false);
|
||||||
|
dayDiv.classList.add('other-month');
|
||||||
|
calendarGrid.appendChild(dayDiv);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('渲染日历出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建日期元素
|
||||||
|
function createDayElement(day, isCurrentMonth) {
|
||||||
|
const dayDiv = document.createElement('div');
|
||||||
|
dayDiv.className = 'calendar-day';
|
||||||
|
dayDiv.textContent = day;
|
||||||
|
|
||||||
|
// 只有当前月的日期可以点击选择
|
||||||
|
if (isCurrentMonth) {
|
||||||
|
dayDiv.addEventListener('click', () => handleDayClick(day));
|
||||||
|
dayDiv.setAttribute('tabindex', '0'); // 使其可聚焦
|
||||||
|
dayDiv.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
handleDayClick(day);
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return dayDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理日期点击
|
||||||
|
function handleDayClick(day) {
|
||||||
|
try {
|
||||||
|
const year = currentDate.getFullYear();
|
||||||
|
const month = currentDate.getMonth();
|
||||||
|
selectedDate = new Date(year, month, day);
|
||||||
|
|
||||||
|
// 触发日期选择事件
|
||||||
|
const event = new CustomEvent('date-selected', {
|
||||||
|
detail: { date: selectedDate }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
|
||||||
|
// 重新渲染以更新选中状态
|
||||||
|
renderCalendar();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('处理日期点击出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定导航按钮事件
|
||||||
|
function bindNavigationEvents() {
|
||||||
|
try {
|
||||||
|
const prevButton = document.getElementById('prev-month');
|
||||||
|
const nextButton = document.getElementById('next-month');
|
||||||
|
|
||||||
|
if (prevButton) {
|
||||||
|
prevButton.addEventListener('click', () => {
|
||||||
|
currentDate.setMonth(currentDate.getMonth() - 1);
|
||||||
|
renderCalendar();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextButton) {
|
||||||
|
nextButton.addEventListener('click', () => {
|
||||||
|
currentDate.setMonth(currentDate.getMonth() + 1);
|
||||||
|
renderCalendar();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加键盘导航
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'ArrowLeft') {
|
||||||
|
currentDate.setMonth(currentDate.getMonth() - 1);
|
||||||
|
renderCalendar();
|
||||||
|
} else if (e.key === 'ArrowRight') {
|
||||||
|
currentDate.setMonth(currentDate.getMonth() + 1);
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('绑定导航事件出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化日历
|
||||||
|
function initCalendar() {
|
||||||
|
try {
|
||||||
|
bindNavigationEvents();
|
||||||
|
renderCalendar();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('初始化日历出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当DOM加载完成后初始化
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', initCalendar);
|
||||||
|
} else {
|
||||||
|
initCalendar();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
nav-links.html
Normal file
13
nav-links.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="nav-links" id="nav-links">
|
||||||
|
<a href="http://blog.exyone.me" class="nav-link">📝 博客</a>
|
||||||
|
<a href="http://bbs.exyone.me" class="nav-link">💬 论坛</a>
|
||||||
|
<a href="http://git.exyone.me" class="nav-link" target="_blank">🔧 Git</a>
|
||||||
|
<!-- 实用工具链接 -->
|
||||||
|
<a href="https://google.com" class="nav-link" target="_blank">🔍 Google</a>
|
||||||
|
<a href="https://yandex.com" class="nav-link" target="_blank">🌐 Yandex</a>
|
||||||
|
<a href="https://www.youtube.com" class="nav-link" target="_blank">📺 YouTube</a>
|
||||||
|
<a href="https://www.bilibili.com" class="nav-link" target="_blank">📽️ Bilibili</a>
|
||||||
|
<a href="https://music.163.com/" class="nav-link" target="_blank">🎵 网易云音乐</a>
|
||||||
|
<a href="https://www.bing.com/translator" class="nav-link" target="_blank">🌍 必应翻译</a>
|
||||||
|
<a href="friendwebsite.html" class="nav-link" target="_blank">🤝 友站链接</a>
|
||||||
|
</div>
|
||||||
7
quick-links.html
Normal file
7
quick-links.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<!-- 快速链接 - 合并到顶部栏 -->
|
||||||
|
<div class="quick-links">
|
||||||
|
<a href="https://linkedin.com" class="quick-link" target="_blank" title="LinkedIn">💼</a>
|
||||||
|
<a href="https://facebook.com" class="quick-link" target="_blank" title="Facebook">📘</a>
|
||||||
|
<a href="https://instagram.com" class="quick-link" target="_blank" title="Instagram">📸</a>
|
||||||
|
<a href="mailto:exyone.dev@icloud.com" class="quick-link" title="邮箱">📧</a>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user