581 lines
20 KiB
HTML
Executable File
581 lines
20 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>登录 - 韬智生产管理系统</title>
|
||
<link rel="icon" type="image/x-icon" href="../icon.ico" />
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||
<link rel="stylesheet" href="./assets/login-animated.css?v=20251231-1427" />
|
||
</head>
|
||
<body>
|
||
<div class="login-page">
|
||
<!-- 左侧角色动画区域 -->
|
||
<div class="characters-section">
|
||
<div class="brand-logo">
|
||
<img src="../icon.ico" alt="Logo" class="logo-icon" />
|
||
<span>韬智生产管理系统</span>
|
||
</div>
|
||
|
||
<div class="characters-container" id="characters-container">
|
||
<!-- 紫色角色 -->
|
||
<div class="character purple" id="char-purple">
|
||
<div class="eyes">
|
||
<div class="eye" id="purple-eye-left">
|
||
<div class="pupil" id="purple-pupil-left"></div>
|
||
</div>
|
||
<div class="eye" id="purple-eye-right">
|
||
<div class="pupil" id="purple-pupil-right"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 黑色角色 -->
|
||
<div class="character black" id="char-black">
|
||
<div class="eyes">
|
||
<div class="eye" id="black-eye-left">
|
||
<div class="pupil" id="black-pupil-left"></div>
|
||
</div>
|
||
<div class="eye" id="black-eye-right">
|
||
<div class="pupil" id="black-pupil-right"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 橙色角色 -->
|
||
<div class="character orange" id="char-orange">
|
||
<div class="eyes-simple">
|
||
<div class="pupil-simple" id="orange-pupil-left"></div>
|
||
<div class="pupil-simple" id="orange-pupil-right"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 黄色角色 -->
|
||
<div class="character yellow" id="char-yellow">
|
||
<div class="eyes-simple">
|
||
<div class="pupil-simple" id="yellow-pupil-left"></div>
|
||
<div class="pupil-simple" id="yellow-pupil-right"></div>
|
||
</div>
|
||
<div class="mouth"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footer-links">
|
||
<a href="#">隐私政策</a>
|
||
<a href="#">服务条款</a>
|
||
<a href="#">联系我们</a>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧登录表单区域 -->
|
||
<div class="login-section">
|
||
<div class="login-container">
|
||
<div class="login-header">
|
||
<h1>欢迎回来!</h1>
|
||
<p>请输入您的登录信息</p>
|
||
</div>
|
||
|
||
<form class="login-form" onsubmit="return false;">
|
||
<div class="form-group">
|
||
<label for="username">用户名</label>
|
||
<input type="text" id="username" class="form-input" placeholder="请输入用户名" required autocomplete="username">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="password">密码</label>
|
||
<div class="password-wrapper">
|
||
<input type="text" id="password" class="form-input" placeholder="请输入密码" required autocomplete="current-password">
|
||
<button type="button" class="password-toggle" id="password-toggle" aria-label="隐藏密码">
|
||
<svg class="eye-icon eye-open" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||
<circle cx="12" cy="12" r="3"></circle>
|
||
</svg>
|
||
<svg class="eye-icon eye-closed" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none;">
|
||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path>
|
||
<line x1="1" y1="1" x2="23" y2="23"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group captcha-group">
|
||
<div class="captcha-input-wrapper">
|
||
<label for="captcha">验证码</label>
|
||
<input type="text" id="captcha" class="form-input" placeholder="请输入验证码" required maxlength="4" autocomplete="off">
|
||
</div>
|
||
<div class="captcha-image-wrapper" id="captcha-image-wrapper" title="点击刷新验证码">
|
||
<img id="captcha-image" class="captcha-image" alt="验证码" />
|
||
</div>
|
||
</div>
|
||
|
||
<div id="error-message" class="error-message" style="display:none;"></div>
|
||
|
||
<button type="button" id="login-btn" class="login-button">
|
||
<span id="login-text">登录</span>
|
||
<span id="login-loader" class="btn-loader" style="display:none;">
|
||
<span class="dot"></span>
|
||
<span class="dot"></span>
|
||
<span class="dot"></span>
|
||
</span>
|
||
</button>
|
||
|
||
<div class="form-footer">
|
||
<span class="copyright">© 2025 韬智科技</span>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 检查是否已登录
|
||
async function checkAuth() {
|
||
try {
|
||
const response = await fetch('/api/auth/me', {
|
||
credentials: 'include'
|
||
});
|
||
if (response.ok) {
|
||
const user = await response.json();
|
||
if (user && user.username) {
|
||
window.location.replace('./index.html#/dashboard');
|
||
}
|
||
}
|
||
} catch(e) {
|
||
// 未登录,继续显示登录页面
|
||
console.log('未登录,显示登录页面');
|
||
}
|
||
}
|
||
|
||
checkAuth();
|
||
|
||
// 登录处理
|
||
const usernameInput = document.getElementById('username');
|
||
const passwordInput = document.getElementById('password');
|
||
const passwordToggle = document.getElementById('password-toggle');
|
||
const captchaInput = document.getElementById('captcha');
|
||
const captchaImage = document.getElementById('captcha-image');
|
||
const captchaImageWrapper = document.getElementById('captcha-image-wrapper');
|
||
const loginBtn = document.getElementById('login-btn');
|
||
const loginText = document.getElementById('login-text');
|
||
const loginLoader = document.getElementById('login-loader');
|
||
const errorMessage = document.getElementById('error-message');
|
||
|
||
function showError(message) {
|
||
errorMessage.textContent = message;
|
||
errorMessage.style.display = 'block';
|
||
setTimeout(() => {
|
||
errorMessage.style.display = 'none';
|
||
}, 3000);
|
||
}
|
||
|
||
function setLoading(loading) {
|
||
if (loading) {
|
||
loginBtn.disabled = true;
|
||
loginText.style.display = 'none';
|
||
loginLoader.style.display = 'flex';
|
||
} else {
|
||
loginBtn.disabled = false;
|
||
loginText.style.display = 'inline';
|
||
loginLoader.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// 加载验证码
|
||
async function loadCaptcha() {
|
||
try {
|
||
const response = await fetch('/api/auth/captcha', {
|
||
credentials: 'include'
|
||
});
|
||
if (response.ok) {
|
||
const data = await response.json();
|
||
if (data.image) {
|
||
captchaImage.src = data.image;
|
||
}
|
||
}
|
||
} catch(e) {
|
||
console.error('加载验证码失败:', e);
|
||
}
|
||
}
|
||
|
||
// 点击图片刷新验证码
|
||
captchaImageWrapper.addEventListener('click', () => {
|
||
captchaInput.value = '';
|
||
captchaImageWrapper.classList.add('refreshing');
|
||
loadCaptcha();
|
||
setTimeout(() => {
|
||
captchaImageWrapper.classList.remove('refreshing');
|
||
}, 300);
|
||
});
|
||
|
||
// 页面加载时获取验证码
|
||
loadCaptcha();
|
||
|
||
async function handleLogin() {
|
||
const username = usernameInput.value.trim();
|
||
const password = passwordInput.value.trim();
|
||
const captcha = captchaInput.value.trim();
|
||
|
||
if (!username) {
|
||
showError('请输入用户名');
|
||
usernameInput.focus();
|
||
return;
|
||
}
|
||
|
||
if (!password) {
|
||
showError('请输入密码');
|
||
passwordInput.focus();
|
||
return;
|
||
}
|
||
|
||
if (!captcha) {
|
||
showError('请输入验证码');
|
||
captchaInput.focus();
|
||
return;
|
||
}
|
||
|
||
if (captcha.length !== 4) {
|
||
showError('验证码为4位数字');
|
||
captchaInput.focus();
|
||
return;
|
||
}
|
||
|
||
setLoading(true);
|
||
|
||
try {
|
||
// 直接使用 fetch,避免 API.login 的 overlay 问题
|
||
const response = await fetch('/api/auth/login', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
credentials: 'include',
|
||
body: JSON.stringify({ username, password, captcha })
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (!response.ok) {
|
||
throw new Error(result.error || '登录失败');
|
||
}
|
||
|
||
if (result.ok) {
|
||
// 登录成功,跳转到主页面
|
||
// 使用 replace 避免 Safari 缓存问题
|
||
window.location.replace('./index.html#/dashboard');
|
||
} else {
|
||
throw new Error('登录失败');
|
||
}
|
||
} catch(e) {
|
||
showError(e.message || '登录失败');
|
||
setLoading(false);
|
||
// 刷新验证码
|
||
captchaInput.value = '';
|
||
loadCaptcha();
|
||
}
|
||
}
|
||
|
||
loginBtn.addEventListener('click', handleLogin);
|
||
|
||
// 回车键登录
|
||
usernameInput.addEventListener('keypress', (e) => {
|
||
if (e.key === 'Enter') {
|
||
passwordInput.focus();
|
||
}
|
||
});
|
||
|
||
passwordInput.addEventListener('keypress', (e) => {
|
||
if (e.key === 'Enter') {
|
||
captchaInput.focus();
|
||
}
|
||
});
|
||
|
||
captchaInput.addEventListener('keypress', (e) => {
|
||
if (e.key === 'Enter') {
|
||
handleLogin();
|
||
}
|
||
});
|
||
|
||
// 自动聚焦用户名输入框
|
||
usernameInput.focus();
|
||
|
||
// ============ 角色动画系统 ============
|
||
let mouseX = 0, mouseY = 0;
|
||
let isTyping = false;
|
||
let showPassword = false;
|
||
|
||
// 获取所有角色元素
|
||
const charPurple = document.getElementById('char-purple');
|
||
const charBlack = document.getElementById('char-black');
|
||
const charOrange = document.getElementById('char-orange');
|
||
const charYellow = document.getElementById('char-yellow');
|
||
|
||
const purpleEyeLeft = document.getElementById('purple-eye-left');
|
||
const purpleEyeRight = document.getElementById('purple-eye-right');
|
||
const purplePupilLeft = document.getElementById('purple-pupil-left');
|
||
const purplePupilRight = document.getElementById('purple-pupil-right');
|
||
|
||
const blackEyeLeft = document.getElementById('black-eye-left');
|
||
const blackEyeRight = document.getElementById('black-eye-right');
|
||
const blackPupilLeft = document.getElementById('black-pupil-left');
|
||
const blackPupilRight = document.getElementById('black-pupil-right');
|
||
|
||
const orangePupilLeft = document.getElementById('orange-pupil-left');
|
||
const orangePupilRight = document.getElementById('orange-pupil-right');
|
||
|
||
const yellowPupilLeft = document.getElementById('yellow-pupil-left');
|
||
const yellowPupilRight = document.getElementById('yellow-pupil-right');
|
||
|
||
// 鼠标跟踪 - 使用requestAnimationFrame节流
|
||
let rafId = null;
|
||
window.addEventListener('mousemove', (e) => {
|
||
mouseX = e.clientX;
|
||
mouseY = e.clientY;
|
||
|
||
if (!rafId) {
|
||
rafId = requestAnimationFrame(() => {
|
||
updateCharacterPositions();
|
||
updatePupilPositions();
|
||
rafId = null;
|
||
});
|
||
}
|
||
});
|
||
|
||
// 计算瞳孔位置
|
||
function calculatePupilPosition(element, maxDistance = 5) {
|
||
if (!element) return { x: 0, y: 0 };
|
||
const rect = element.getBoundingClientRect();
|
||
const centerX = rect.left + rect.width / 2;
|
||
const centerY = rect.top + rect.height / 2;
|
||
|
||
const deltaX = mouseX - centerX;
|
||
const deltaY = mouseY - centerY;
|
||
const distance = Math.min(Math.sqrt(deltaX ** 2 + deltaY ** 2), maxDistance);
|
||
const angle = Math.atan2(deltaY, deltaX);
|
||
|
||
return {
|
||
x: Math.cos(angle) * distance,
|
||
y: Math.sin(angle) * distance
|
||
};
|
||
}
|
||
|
||
// 计算身体倾斜角度和脸部位置
|
||
function calculatePosition(element) {
|
||
if (!element) return { faceX: 0, faceY: 0, bodySkew: 0 };
|
||
|
||
const rect = element.getBoundingClientRect();
|
||
const centerX = rect.left + rect.width / 2;
|
||
const centerY = rect.top + rect.height / 3; // 聚焦头部区域
|
||
|
||
const deltaX = mouseX - centerX;
|
||
const deltaY = mouseY - centerY;
|
||
|
||
// 脸部移动(用于眼睛位置)
|
||
const faceX = Math.max(-15, Math.min(15, deltaX / 20));
|
||
const faceY = Math.max(-10, Math.min(10, deltaY / 30));
|
||
|
||
// 身体倾斜(负值表示向鼠标方向倾斜)
|
||
const bodySkew = Math.max(-6, Math.min(6, -deltaX / 120));
|
||
|
||
return { faceX, faceY, bodySkew };
|
||
}
|
||
|
||
// 更新角色身体位置
|
||
function updateCharacterPositions() {
|
||
const hasPassword = passwordInput.value.length > 0;
|
||
const isPasswordVisible = passwordInput.getAttribute('type') === 'text';
|
||
|
||
// 紫色角色
|
||
const purplePos = calculatePosition(charPurple);
|
||
if (hasPassword && isPasswordVisible) {
|
||
// 密码可见时 - 站高,不倾斜
|
||
charPurple.style.height = '440px';
|
||
charPurple.style.transform = `skewX(0deg)`;
|
||
} else if (isTyping || (hasPassword && !isPasswordVisible)) {
|
||
// 输入邮箱或密码隐藏时 - 站高并倾斜
|
||
charPurple.style.height = '440px';
|
||
charPurple.style.transform = `skewX(${purplePos.bodySkew - 12}deg) translateX(40px)`;
|
||
} else {
|
||
// 正常状态 - 根据鼠标晃动
|
||
charPurple.style.height = '400px';
|
||
charPurple.style.transform = `skewX(${purplePos.bodySkew}deg)`;
|
||
}
|
||
|
||
// 黑色角色
|
||
const blackPos = calculatePosition(charBlack);
|
||
if (hasPassword && isPasswordVisible) {
|
||
// 密码可见时 - 不倾斜
|
||
charBlack.style.transform = `skewX(0deg)`;
|
||
} else if (isLookingAtEachOther) {
|
||
// 互看时 - 倾斜并移动
|
||
charBlack.style.transform = `skewX(${blackPos.bodySkew * 1.5 + 10}deg) translateX(20px)`;
|
||
} else if (isTyping || (hasPassword && !isPasswordVisible)) {
|
||
charBlack.style.transform = `skewX(${blackPos.bodySkew * 1.5}deg)`;
|
||
} else {
|
||
charBlack.style.transform = `skewX(${blackPos.bodySkew}deg)`;
|
||
}
|
||
|
||
// 橙色和黄色角色
|
||
const orangePos = calculatePosition(charOrange);
|
||
const yellowPos = calculatePosition(charYellow);
|
||
|
||
if (hasPassword && isPasswordVisible) {
|
||
// 密码可见时 - 不倾斜
|
||
charOrange.style.transform = `skewX(0deg)`;
|
||
charYellow.style.transform = `skewX(0deg)`;
|
||
} else {
|
||
charOrange.style.transform = `skewX(${orangePos.bodySkew}deg)`;
|
||
charYellow.style.transform = `skewX(${yellowPos.bodySkew}deg)`;
|
||
}
|
||
}
|
||
|
||
// 更新瞳孔位置
|
||
function updatePupilPositions() {
|
||
const hasPassword = passwordInput.value.length > 0;
|
||
const isPasswordVisible = passwordInput.getAttribute('type') === 'text';
|
||
|
||
// 根据状态决定眼睛方向
|
||
if (isLookingAtEachOther) {
|
||
// 输入邮箱时 - 互相看向对方
|
||
purplePupilLeft.style.transform = 'translate(3px, 4px)';
|
||
purplePupilRight.style.transform = 'translate(3px, 4px)';
|
||
blackPupilLeft.style.transform = 'translate(0px, -4px)';
|
||
blackPupilRight.style.transform = 'translate(0px, -4px)';
|
||
// 橙色和黄色跟随鼠标
|
||
const orangeLeftPos = calculatePupilPosition(orangePupilLeft, 5);
|
||
const orangeRightPos = calculatePupilPosition(orangePupilRight, 5);
|
||
orangePupilLeft.style.transform = `translate(${orangeLeftPos.x}px, ${orangeLeftPos.y}px)`;
|
||
orangePupilRight.style.transform = `translate(${orangeRightPos.x}px, ${orangeRightPos.y}px)`;
|
||
const yellowLeftPos = calculatePupilPosition(yellowPupilLeft, 5);
|
||
const yellowRightPos = calculatePupilPosition(yellowPupilRight, 5);
|
||
yellowPupilLeft.style.transform = `translate(${yellowLeftPos.x}px, ${yellowLeftPos.y}px)`;
|
||
yellowPupilRight.style.transform = `translate(${yellowRightPos.x}px, ${yellowRightPos.y}px)`;
|
||
} else if (hasPassword && isPasswordVisible) {
|
||
// 密码可见时 - 所有小人看向左侧
|
||
purplePupilLeft.style.transform = 'translate(-5px, 0px)';
|
||
purplePupilRight.style.transform = 'translate(-5px, 0px)';
|
||
blackPupilLeft.style.transform = 'translate(-4px, 0px)';
|
||
blackPupilRight.style.transform = 'translate(-4px, 0px)';
|
||
orangePupilLeft.style.transform = 'translate(-5px, 0px)';
|
||
orangePupilRight.style.transform = 'translate(-5px, 0px)';
|
||
yellowPupilLeft.style.transform = 'translate(-5px, 0px)';
|
||
yellowPupilRight.style.transform = 'translate(-5px, 0px)';
|
||
} else if (hasPassword && !isPasswordVisible) {
|
||
// 密码隐藏时 - 所有小人看向右下侧
|
||
purplePupilLeft.style.transform = 'translate(4px, 4px)';
|
||
purplePupilRight.style.transform = 'translate(4px, 4px)';
|
||
blackPupilLeft.style.transform = 'translate(4px, 4px)';
|
||
blackPupilRight.style.transform = 'translate(4px, 4px)';
|
||
orangePupilLeft.style.transform = 'translate(5px, 4px)';
|
||
orangePupilRight.style.transform = 'translate(5px, 4px)';
|
||
yellowPupilLeft.style.transform = 'translate(5px, 4px)';
|
||
yellowPupilRight.style.transform = 'translate(5px, 4px)';
|
||
} else {
|
||
// 正常状态 - 跟随鼠标
|
||
const purpleLeftPos = calculatePupilPosition(purpleEyeLeft, 5);
|
||
const purpleRightPos = calculatePupilPosition(purpleEyeRight, 5);
|
||
purplePupilLeft.style.transform = `translate(${purpleLeftPos.x}px, ${purpleLeftPos.y}px)`;
|
||
purplePupilRight.style.transform = `translate(${purpleRightPos.x}px, ${purpleRightPos.y}px)`;
|
||
|
||
const blackLeftPos = calculatePupilPosition(blackEyeLeft, 4);
|
||
const blackRightPos = calculatePupilPosition(blackEyeRight, 4);
|
||
blackPupilLeft.style.transform = `translate(${blackLeftPos.x}px, ${blackLeftPos.y}px)`;
|
||
blackPupilRight.style.transform = `translate(${blackRightPos.x}px, ${blackRightPos.y}px)`;
|
||
|
||
const orangeLeftPos = calculatePupilPosition(orangePupilLeft, 5);
|
||
const orangeRightPos = calculatePupilPosition(orangePupilRight, 5);
|
||
orangePupilLeft.style.transform = `translate(${orangeLeftPos.x}px, ${orangeLeftPos.y}px)`;
|
||
orangePupilRight.style.transform = `translate(${orangeRightPos.x}px, ${orangeRightPos.y}px)`;
|
||
|
||
const yellowLeftPos = calculatePupilPosition(yellowPupilLeft, 5);
|
||
const yellowRightPos = calculatePupilPosition(yellowPupilRight, 5);
|
||
yellowPupilLeft.style.transform = `translate(${yellowLeftPos.x}px, ${yellowLeftPos.y}px)`;
|
||
yellowPupilRight.style.transform = `translate(${yellowRightPos.x}px, ${yellowRightPos.y}px)`;
|
||
}
|
||
}
|
||
|
||
// 眨眼动画
|
||
function blinkEye(eyeLeft, eyeRight) {
|
||
eyeLeft.style.height = '2px';
|
||
eyeRight.style.height = '2px';
|
||
setTimeout(() => {
|
||
eyeLeft.style.height = '';
|
||
eyeRight.style.height = '';
|
||
}, 150);
|
||
}
|
||
|
||
// 随机眨眼
|
||
function scheduleRandomBlink(eyeLeft, eyeRight) {
|
||
const delay = Math.random() * 4000 + 3000;
|
||
setTimeout(() => {
|
||
if (Math.random() > 0.3) {
|
||
blinkEye(eyeLeft, eyeRight);
|
||
}
|
||
scheduleRandomBlink(eyeLeft, eyeRight);
|
||
}, delay);
|
||
}
|
||
|
||
scheduleRandomBlink(purpleEyeLeft, purpleEyeRight);
|
||
scheduleRandomBlink(blackEyeLeft, blackEyeRight);
|
||
|
||
// 添加isLookingAtEachOther状态
|
||
let isLookingAtEachOther = false;
|
||
|
||
// 输入框聚焦 - 角色互看
|
||
usernameInput.addEventListener('focus', () => {
|
||
isTyping = true;
|
||
isLookingAtEachOther = true;
|
||
// 短暂互看后恢复
|
||
setTimeout(() => {
|
||
isLookingAtEachOther = false;
|
||
}, 800);
|
||
});
|
||
|
||
usernameInput.addEventListener('blur', () => {
|
||
if (!passwordInput.value) {
|
||
isTyping = false;
|
||
}
|
||
isLookingAtEachOther = false;
|
||
});
|
||
|
||
// 密码输入
|
||
passwordInput.addEventListener('focus', () => {
|
||
isTyping = true;
|
||
});
|
||
|
||
passwordInput.addEventListener('blur', () => {
|
||
if (!passwordInput.value) {
|
||
isTyping = false;
|
||
}
|
||
});
|
||
|
||
passwordInput.addEventListener('input', () => {
|
||
updateCharacterPositions();
|
||
updatePupilPositions();
|
||
});
|
||
|
||
// 密码可见性切换(默认显示,点击隐藏)
|
||
passwordToggle.addEventListener('click', () => {
|
||
const type = passwordInput.getAttribute('type');
|
||
const eyeOpen = passwordToggle.querySelector('.eye-open');
|
||
const eyeClosed = passwordToggle.querySelector('.eye-closed');
|
||
|
||
if (type === 'text') {
|
||
// 点击后隐藏密码
|
||
passwordInput.setAttribute('type', 'password');
|
||
eyeOpen.style.display = 'none';
|
||
eyeClosed.style.display = 'block';
|
||
passwordToggle.setAttribute('aria-label', '显示密码');
|
||
} else {
|
||
// 点击后显示密码
|
||
passwordInput.setAttribute('type', 'text');
|
||
eyeOpen.style.display = 'block';
|
||
eyeClosed.style.display = 'none';
|
||
passwordToggle.setAttribute('aria-label', '隐藏密码');
|
||
}
|
||
|
||
updatePupilPositions();
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|