login.html: 密码框增加显示/隐藏切换(眼睛按钮)
This commit is contained in:
parent
f3d252e146
commit
221eb42c3b
90
login.html
90
login.html
@ -4,7 +4,6 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>宇森 · 登录</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=ZCOOL+QingKe+HuangYou&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root{
|
||||
--bg-0:#080c1a; --bg-1:#0e1730; --bg-2:#15213f;
|
||||
@ -16,7 +15,7 @@
|
||||
*{box-sizing:border-box;margin:0;padding:0;}
|
||||
html,body{height:100%;}
|
||||
body{
|
||||
font-family:"Noto Sans SC",system-ui,sans-serif;color:var(--text);
|
||||
font-family:"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC",system-ui,-apple-system,sans-serif;color:var(--text);
|
||||
background:
|
||||
radial-gradient(1000px 620px at 82% -8%, rgba(139,92,246,.16), transparent 60%),
|
||||
radial-gradient(820px 560px at 8% 112%, rgba(76,201,240,.12), transparent 55%),
|
||||
@ -31,7 +30,7 @@
|
||||
|
||||
.wrap{position:relative;z-index:2;width:min(420px,92vw);}
|
||||
.brand{text-align:center;margin-bottom:26px;}
|
||||
.brand .cn{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:38px;letter-spacing:6px;color:#fff;text-shadow:0 0 18px rgba(139,92,246,.6);}
|
||||
.brand .cn{font-family:"PingFang SC","Microsoft YaHei",system-ui,sans-serif;font-weight:900;font-size:42px;letter-spacing:8px;color:#fff;text-shadow:0 0 18px rgba(139,92,246,.6);}
|
||||
.brand .en{font-size:11px;color:var(--magenta);letter-spacing:3px;margin-top:6px;}
|
||||
.brand .tag{font-size:13px;color:var(--text-dim);margin-top:10px;}
|
||||
|
||||
@ -44,6 +43,10 @@
|
||||
.field label{display:block;font-size:12px;color:var(--text-dim);margin-bottom:6px;letter-spacing:1px;}
|
||||
.field input{width:100%;background:rgba(8,12,26,.6);border:1px solid var(--card-bd);border-radius:10px;color:var(--text);padding:11px 13px;font-family:inherit;font-size:14px;outline:none;transition:.2s;}
|
||||
.field input:focus{border-color:var(--violet);box-shadow:0 0 0 3px rgba(139,92,246,.18);}
|
||||
.pw-wrap{position:relative;}
|
||||
.pw-wrap input{padding-right:40px;}
|
||||
.pw-toggle{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:transparent;border:none;color:var(--text-dim);cursor:pointer;font-size:16px;line-height:1;padding:4px 6px;border-radius:6px;transition:.2s;}
|
||||
.pw-toggle:hover{color:#fff;background:rgba(255,255,255,.08);}
|
||||
|
||||
.submit{width:100%;margin-top:6px;font-size:15px;font-weight:700;color:#0b1020;background:linear-gradient(120deg,var(--gold),#f0d49a);padding:12px;border-radius:11px;cursor:pointer;border:none;letter-spacing:2px;transition:.22s;box-shadow:0 0 18px rgba(231,184,92,.35);}
|
||||
.submit:hover{filter:brightness(1.08);}
|
||||
@ -57,8 +60,6 @@
|
||||
.back a{color:var(--cyan);text-decoration:none;}
|
||||
.back a:hover{text-decoration:underline;}
|
||||
|
||||
.hint{margin-bottom:16px;font-size:13px;color:var(--cyan);background:rgba(76,201,240,.10);border:1px solid rgba(76,201,240,.30);border-radius:10px;padding:9px 12px;text-align:center;}
|
||||
|
||||
.hidden{display:none;}
|
||||
</style>
|
||||
</head>
|
||||
@ -71,7 +72,6 @@
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="hint hidden" id="hint">登录后即可进入游戏</div>
|
||||
<div class="tabs">
|
||||
<button id="tabLogin" class="active">登录</button>
|
||||
<button id="tabReg">注册</button>
|
||||
@ -81,32 +81,41 @@
|
||||
<form id="loginForm" autocomplete="off">
|
||||
<div class="field">
|
||||
<label>账号</label>
|
||||
<input id="lLogin" type="text" placeholder="Odoo 用户名 / 邮箱" />
|
||||
<input id="lLogin" type="text" placeholder="Odoo 用户名" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>密码</label>
|
||||
<input id="lPwd" type="password" placeholder="密码" />
|
||||
<div class="pw-wrap">
|
||||
<input id="lPwd" type="password" placeholder="密码" />
|
||||
<button type="button" class="pw-toggle" data-target="lPwd" aria-label="显示密码">👁</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="submit" type="submit">进入世界</button>
|
||||
</form>
|
||||
|
||||
<!-- 注册 -->
|
||||
<form id="regForm" class="hidden" autocomplete="off">
|
||||
<div class="field">
|
||||
<label>昵称</label>
|
||||
<input id="rName" type="text" placeholder="显示名称(可空)" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>账号</label>
|
||||
<input id="rLogin" type="text" placeholder="登录用账号" />
|
||||
<input id="rLogin" type="text" placeholder="登录用账号(字母/数字/._-)" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>邮箱</label>
|
||||
<input id="rEmail" type="email" placeholder="邮箱(可空)" />
|
||||
<label>昵称</label>
|
||||
<input id="rName" type="text" placeholder="默认与账号一致,可改" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>密码</label>
|
||||
<input id="rPwd" type="password" placeholder="至少 6 位" />
|
||||
<div class="pw-wrap">
|
||||
<input id="rPwd" type="password" placeholder="至少 8 位,字母+数字" />
|
||||
<button type="button" class="pw-toggle" data-target="rPwd" aria-label="显示密码">👁</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>确认密码</label>
|
||||
<div class="pw-wrap">
|
||||
<input id="rPwd2" type="password" placeholder="再次输入密码" />
|
||||
<button type="button" class="pw-toggle" data-target="rPwd2" aria-label="显示密码">👁</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="submit" type="submit">创建园丁账号</button>
|
||||
</form>
|
||||
@ -128,8 +137,6 @@
|
||||
// 回跳目标(进入游戏流程带 ?next=world.html)
|
||||
const params = new URLSearchParams(location.search);
|
||||
const nextUrl = params.get('next') || 'world.html';
|
||||
const hint = document.getElementById('hint');
|
||||
if (params.get('next')) hint.classList.remove('hidden');
|
||||
// 已登录则直接跳走
|
||||
(async () => {
|
||||
try { const me = await API.me(); if (me && me.uid) location.href = nextUrl; } catch (e) {}
|
||||
@ -149,6 +156,34 @@
|
||||
tabLogin.onclick = () => switchTab('login');
|
||||
tabReg.onclick = () => switchTab('reg');
|
||||
|
||||
// 密码显示/隐藏切换(眼睛按钮)
|
||||
document.querySelectorAll('.pw-toggle').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const input = document.getElementById(btn.dataset.target);
|
||||
if (!input) return;
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
btn.textContent = '🙈';
|
||||
btn.setAttribute('aria-label', '隐藏密码');
|
||||
} else {
|
||||
input.type = 'password';
|
||||
btn.textContent = '👁';
|
||||
btn.setAttribute('aria-label', '显示密码');
|
||||
}
|
||||
input.focus();
|
||||
});
|
||||
});
|
||||
|
||||
// 昵称默认 = 账号:账号变更时若昵称仍空/等于上次账号值,则同步;用户改过昵称则保留
|
||||
const rLogin = document.getElementById('rLogin');
|
||||
const rName = document.getElementById('rName');
|
||||
let lastLoginVal = '';
|
||||
rLogin.addEventListener('input', () => {
|
||||
const v = rLogin.value.trim();
|
||||
if (rName.value === '' || rName.value === lastLoginVal) rName.value = v;
|
||||
lastLoginVal = v;
|
||||
});
|
||||
|
||||
loginForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
showMsg('');
|
||||
@ -170,16 +205,19 @@
|
||||
regForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
showMsg('');
|
||||
const payload = {
|
||||
name: document.getElementById('rName').value.trim(),
|
||||
login: document.getElementById('rLogin').value.trim(),
|
||||
email: document.getElementById('rEmail').value.trim(),
|
||||
password: document.getElementById('rPwd').value,
|
||||
};
|
||||
if (!payload.login || !payload.password){ showMsg('账号和密码必填', 'err'); return; }
|
||||
const login = document.getElementById('rLogin').value.trim();
|
||||
const name = document.getElementById('rName').value.trim();
|
||||
const password = document.getElementById('rPwd').value;
|
||||
const pwd2 = document.getElementById('rPwd2').value;
|
||||
if (!login) { showMsg('请填写账号', 'err'); return; }
|
||||
if (password.length < 8) { showMsg('密码至少 8 位', 'err'); return; }
|
||||
if (!/[a-zA-Z]/.test(password) || !/\d/.test(password)) {
|
||||
showMsg('密码必须同时包含字母和数字', 'err'); return;
|
||||
}
|
||||
if (password !== pwd2) { showMsg('两次密码输入不一致', 'err'); return; }
|
||||
const btn = regForm.querySelector('.submit'); btn.disabled = true; btn.textContent = '注册中…';
|
||||
try {
|
||||
const r = await API.register(payload);
|
||||
const r = await API.register({ name, login, password });
|
||||
if (r.ok){ location.href = nextUrl; }
|
||||
else { showMsg(r.error || '注册失败', 'err'); }
|
||||
} catch (err) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user