1050 lines
76 KiB
HTML
1050 lines
76 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
|
||
<meta name="format-detection" content="telephone=no">
|
||
<title>孕妈广场</title>
|
||
<!-- 孕妈广场(2026-11-01 第一版,占位内容,纯前端;mama-box 首页「孕妈广场」横滑卡点进来)
|
||
用户原话:「点进去之后变成小红书那种瀑布流,每一个话题都是那样的。先整理出来 15 个话题,先做占位放上。点击详情页的时候可以点赞和评论。」
|
||
· 话题表 topics.js(与首页共用);笔记 / 评论池 data.js(每话题 7 条笔记 + 10 条评论池,评论按笔记 id 确定性抽 3~8 条)。
|
||
· URL:?t=话题id 进对应话题,&n=笔记id 直接打开详情;切 tab 只用 replaceState 改 query,**hash 原样保留**(身份 #openid 在里面)。
|
||
· 点赞 / 收藏 / 评论 / 评论点赞只存本机 localStorage「mmbox.gc.v1」,按 openid 分开;正式版接后端时整块替换 store。
|
||
· 返回:详情层 → history.back() 关层;列表 → 有站内历史就 history.back(),没有就回 ../(保留身份,去掉 t/n)。
|
||
· 禁止下拉回弹:固定外壳 + 容器滚动 + touchmove 拦截(同首页那段:往上找能朝该方向滚的容器,找不到才拦)。 -->
|
||
<style>
|
||
:root{
|
||
--brand:#F4593C;--ink:#2B2320;--ink-2:#6B615B;--muted:#9A8380;--line:#F1E7E1;
|
||
--bg:#F8F3EF;--peach:#FFEDE6;--btn:linear-gradient(135deg,#F77B55,#EE5A3E);
|
||
--safe-b:env(safe-area-inset-bottom);
|
||
}
|
||
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
|
||
html,body{margin:0;padding:0;height:100%;overflow:hidden;overscroll-behavior:none}
|
||
body{background:var(--bg);font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Segoe UI",Roboto,sans-serif;
|
||
color:var(--ink);-webkit-font-smoothing:antialiased;font-size:14px;line-height:1.5;-webkit-text-size-adjust:100%}
|
||
button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:pointer}
|
||
.ic{width:16px;height:16px;flex:none;display:inline-block;vertical-align:middle}
|
||
.hide{display:none!important}
|
||
|
||
/* ---------- 外壳:唯一的滚动容器 ---------- */
|
||
#sc{position:fixed;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:none;
|
||
background:radial-gradient(220px 180px at 100% 0,rgba(255,196,214,.45),rgba(255,196,214,0) 70%),radial-gradient(240px 200px at 0 40px,rgba(255,206,170,.45),rgba(255,206,170,0) 70%),var(--bg)}
|
||
#sc::-webkit-scrollbar{display:none}
|
||
.top{position:sticky;top:0;z-index:20;padding-top:env(safe-area-inset-top);background:rgba(248,243,239,.9);-webkit-backdrop-filter:blur(14px) saturate(160%);backdrop-filter:blur(14px) saturate(160%);transition:box-shadow .2s}
|
||
.top.on{box-shadow:0 4px 14px rgba(160,110,90,.10)}
|
||
.nav{display:flex;align-items:center;gap:6px;height:46px;padding:0 10px}
|
||
.nav .bk{width:36px;height:36px;display:grid;place-items:center;border-radius:50%;color:var(--ink)}
|
||
.nav .bk:active{background:rgba(0,0,0,.05)}
|
||
.nav .bk .ic{width:22px;height:22px}
|
||
.nav h1{flex:1;margin:0;text-align:center;font-size:17px;font-weight:900;letter-spacing:.5px}
|
||
.nav h1 span{background:linear-gradient(transparent 60%,#FFD0DC 60%,#FFD0DC 92%,transparent 92%);padding:0 3px}
|
||
.nav .sp{width:36px}
|
||
|
||
/* ---------- 一级分类:分段按钮(11-01 第三版:用户说「经验 / 家庭不够明显、有点乱」→ 一条底槽三段,选中段实底) ---------- */
|
||
.cats{display:flex;gap:4px;margin:2px 12px 10px;padding:4px;border-radius:16px;background:#F0E4DE}
|
||
.cats button{flex:1;min-width:0;height:38px;display:flex;align-items:center;justify-content:center;gap:3px;border-radius:12px;
|
||
font-size:14.5px;font-weight:800;color:#8A7570;letter-spacing:.3px;transition:background .18s,color .18s,box-shadow .18s}
|
||
.cats button .ic{width:15px;height:15px;color:var(--cf)}
|
||
.cats button.on{background:var(--cf);color:#fff;box-shadow:0 6px 14px -6px var(--cf)}
|
||
.cats button.on .ic{color:#fff}
|
||
.cats button:active{transform:scale(.97)}
|
||
.cats .c-all{--cf:#F4593C}
|
||
/* 四块分类色(11-01 第四版:按用户选题清单分 家庭 / 婚姻 / 职场 / 母婴):kf 实色 · kt 深字 · kl/kl2 浅底两色 */
|
||
.k-family,.c-family{--kf:#E0566F;--kt:#C23A55;--kl:#FFF0F3;--kl2:#FFD9E0}
|
||
.k-marriage,.c-marriage{--kf:#7B5CC4;--kt:#6346B0;--kl:#F4F0FF;--kl2:#E0D5FA}
|
||
.k-work,.c-work{--kf:#3A72B8;--kt:#2C5E9E;--kl:#EEF4FC;--kl2:#D2E2F6}
|
||
.k-baby,.c-baby{--kf:#2E8A7C;--kt:#21705F;--kl:#EBF7F3;--kl2:#CDEBE3}
|
||
.cats .c-family,.cats .c-marriage,.cats .c-work,.cats .c-baby{--cf:var(--kf)}
|
||
|
||
/* ---------- 投稿有奖横幅 ---------- */
|
||
.rw{position:relative;display:flex;align-items:center;gap:12px;margin:2px 12px 0;padding:13px 14px;border-radius:18px;overflow:hidden;width:calc(100% - 24px);text-align:left;
|
||
background:radial-gradient(120px 90px at 100% 0,rgba(255,255,255,.35),transparent 70%),linear-gradient(120deg,#FF8A5B,#F4593C 60%,#E8473A);color:#fff;box-shadow:0 10px 22px -12px #E8473A}
|
||
.rw .gf{width:42px;height:42px;flex:none;display:grid;place-items:center;border-radius:14px;background:rgba(255,255,255,.22)}
|
||
.rw .gf .ic{width:24px;height:24px}
|
||
.rw .rt{flex:1;min-width:0}
|
||
.rw .rt small{display:block;font-size:12px;font-weight:700;opacity:.9;letter-spacing:.5px}
|
||
.rw .rt b{display:block;margin-top:1px;font-size:17px;font-weight:900;letter-spacing:.3px;white-space:nowrap}
|
||
.rw .rt b em{font-style:normal;font-size:20px;color:#FFF3B8}
|
||
.rw .go{flex:none;height:30px;padding:0 11px;border-radius:99px;background:#fff;color:#E8473A;font-size:12.5px;font-weight:800;display:inline-flex;align-items:center}
|
||
.rw.sm{margin-top:12px;padding:10px 12px}
|
||
.rw.sm .gf{width:34px;height:34px;border-radius:11px}
|
||
.rw.sm .gf .ic{width:19px;height:19px}
|
||
.rw.sm .rt b{font-size:14.5px}
|
||
.rw.sm .rt b em{font-size:16px}
|
||
|
||
/* ---------- 区块标题 ---------- */
|
||
.sh{display:flex;align-items:center;gap:6px;margin:18px 14px 8px}
|
||
.sh h2{margin:0;font-size:17px;font-weight:900;letter-spacing:.3px}
|
||
.sh .fire{width:18px;height:18px;color:#FF5A3C}
|
||
.sh small{font-size:12px;font-weight:600;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
|
||
.sh .more{margin-left:auto;font-size:12.5px;font-weight:700;color:var(--muted);display:inline-flex;align-items:center}
|
||
|
||
/* ---------- 热门话题:横滑卡 ---------- */
|
||
.hot{display:flex;gap:10px;padding:0 12px 2px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scroll-snap-type:x mandatory}
|
||
.hot::-webkit-scrollbar{display:none}
|
||
.hot::after{content:"";flex:none;width:2px}
|
||
.hc{flex:none;width:168px;scroll-snap-align:start;display:flex;flex-direction:column;padding:12px 12px 11px;border-radius:18px;text-align:left;background:var(--hb);position:relative;overflow:hidden}
|
||
.hc{--hb:linear-gradient(160deg,var(--kl),var(--kl2));--hk:var(--kf);--ht:var(--kt)}
|
||
.hc .wm{position:absolute;right:-4px;bottom:-14px;font-size:72px;font-weight:900;line-height:1;color:#fff;opacity:.7;font-family:"STKaiti","KaiTi","Kaiti SC",serif;pointer-events:none}
|
||
.hc .kb{align-self:flex-start;position:relative}
|
||
.hc .rk{position:absolute;right:10px;top:10px;height:18px;padding:0 6px;border-radius:6px;background:#FF5A3C;color:#fff;font-size:10.5px;font-weight:800;line-height:18px}
|
||
.hc h3{position:relative;margin:8px 0 0;font-size:15px;font-weight:900;line-height:1.35;color:#2A1E1E}
|
||
.hc p{position:relative;margin:4px 0 0;font-size:11.5px;line-height:1.5;color:#7A6663;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:34px}
|
||
.hc .jn{position:relative;align-self:flex-start;margin-top:10px;height:28px;padding:0 12px;border-radius:99px;background:var(--hk);color:#fff;font-size:12.5px;font-weight:800;display:inline-flex;align-items:center;gap:3px}
|
||
.hc .jn .ic{width:13px;height:13px}
|
||
|
||
/* 分类小徽标:家庭 / 经验(封面、热门卡、话题头、详情共用) */
|
||
.kb{display:inline-flex;align-items:center;gap:3px;height:20px;padding:0 7px 0 5px;border-radius:7px;font-size:11px;font-weight:800;letter-spacing:.5px;color:#fff;white-space:nowrap}
|
||
.kb .ic{width:12px;height:12px}
|
||
.kb{background:var(--kf)}
|
||
|
||
/* ---------- 话题头卡(选了具体话题时) ---------- */
|
||
.th{position:relative;margin:2px 12px 0;padding:14px 16px 14px;border-radius:20px;overflow:hidden;background:var(--hb);box-shadow:0 10px 24px -18px var(--hk)}
|
||
.th{--hb:linear-gradient(150deg,var(--kl),var(--kl2));--hk:var(--kf);--ht:var(--kt)}
|
||
.th .wm{position:absolute;right:-4px;top:-8px;font-size:104px;font-weight:900;line-height:1;color:#fff;opacity:.6;font-family:"STKaiti","KaiTi","Kaiti SC",serif;pointer-events:none}
|
||
.th .x{position:absolute;right:8px;top:8px;width:30px;height:30px;display:grid;place-items:center;border-radius:50%;background:rgba(255,255,255,.7);color:#7A6663}
|
||
.th .x .ic{width:14px;height:14px}
|
||
.th h2{position:relative;margin:8px 0 4px;font-size:21px;font-weight:900;line-height:1.3;color:#2A1E1E;letter-spacing:.3px}
|
||
.th h2 em{font-style:normal;color:var(--ht);margin-right:2px}
|
||
.th p{position:relative;margin:0;max-width:280px;font-size:12.5px;line-height:1.6;color:#5E4E4A}
|
||
.th .tf{position:relative;display:flex;gap:8px;margin-top:12px}
|
||
.th .join{height:34px;padding:0 16px;border-radius:99px;background:var(--hk);color:#fff;font-size:13.5px;font-weight:800;display:inline-flex;align-items:center;gap:4px;box-shadow:0 6px 12px -6px var(--hk)}
|
||
.th .join .ic{width:14px;height:14px}
|
||
.th .sw{height:34px;padding:0 14px;border-radius:99px;background:rgba(255,255,255,.8);color:var(--ht);font-size:13px;font-weight:800}
|
||
|
||
/* ---------- 瀑布流 ---------- */
|
||
.wf{display:flex;align-items:flex-start;gap:8px;padding:10px 12px 0}
|
||
.wf .col{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
|
||
.nc{display:block;width:100%;text-align:left;border-radius:14px;overflow:hidden;background:#fff;box-shadow:0 3px 12px rgba(170,110,90,.08);animation:ncIn .35s ease both}
|
||
.nc:active{transform:scale(.985)}
|
||
@keyframes ncIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
||
.nc .cvw{position:relative}
|
||
.nc .nb{padding:8px 9px 9px}
|
||
.nc h3{margin:0;font-size:13.5px;font-weight:700;line-height:1.45;color:#2A2220;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
||
.nc .nf{display:flex;align-items:center;gap:5px;margin-top:7px}
|
||
.nc .nf img{width:18px;height:18px;border-radius:50%;object-fit:cover;flex:none;background:#FFE3D3}
|
||
.nc .nf .nm{flex:1;min-width:0;font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.lk{flex:none;display:inline-flex;align-items:center;gap:2px;min-width:44px;justify-content:flex-end;height:22px;font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
|
||
.lk .ic{width:15px;height:15px}
|
||
.lk.on{color:#F0453A}
|
||
.lk.pop .ic{animation:pop .35s ease}
|
||
@keyframes pop{40%{transform:scale(1.35)}}
|
||
.nc .tp{display:block;margin-top:4px;font-size:11.5px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nc .tp{color:var(--kt)}
|
||
|
||
.end{padding:22px 0 calc(26px + var(--safe-b));text-align:center}
|
||
.end b{display:block;font-size:12px;font-weight:600;color:#C2ABA4;letter-spacing:2px}
|
||
.end small{display:block;margin-top:8px;font-size:10.5px;color:#CDBBB5;opacity:.85}
|
||
|
||
/* ---------- 封面(em 计:卡片 1em≈13px,详情放大)
|
||
11-01 第三版:用户说列表「太乱」→ 原来 6 种花样(方格纸/横线本/波点胶带/深色引号…)全部去掉,只留一种版式;
|
||
颜色只按分类走:家庭 = 粉、经验 = 青绿,各 3 个深浅轮换。左上角实底「家庭 / 经验」徽标,一眼分清。 ---------- */
|
||
.cv{position:relative;width:100%;overflow:hidden;font-size:13px;isolation:isolate;display:flex;flex-direction:column;padding:.95em 1.05em 1.1em;background:linear-gradient(160deg,var(--c1),var(--c2))}
|
||
.cv .kb{align-self:flex-start;font-size:.85em;height:1.55em;padding:0 .55em 0 .4em;border-radius:.5em;gap:.2em}
|
||
.cv .kb .ic{width:1em;height:1em}
|
||
.cv .ct{flex:1;display:flex;flex-direction:column;justify-content:center;position:relative;z-index:1}
|
||
.cv .t1{font-size:1.65em;font-weight:900;line-height:1.25;letter-spacing:.04em;color:#2A1E1E;word-break:break-all}
|
||
.cv .t2{margin-top:.5em;font-size:.92em;font-weight:700;line-height:1.4;color:var(--tk)}
|
||
/* 照片封面(11-01 用户:广场图片要有一些像真实上传的照片,不要全是文字封面):约三分之一笔记用照片,满铺裁切,左上角仍挂分类徽标 */
|
||
.cv.ph{padding:0;background:#EFE6E1}
|
||
.cv.ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
|
||
.cv.ph .kb{position:absolute;left:.95em;top:.95em;z-index:1;box-shadow:0 2px 6px rgba(0,0,0,.12)}
|
||
.cv .wm{position:absolute;right:-.1em;bottom:-.25em;font-size:5.6em;font-weight:900;line-height:1;color:#fff;opacity:.55;font-family:"STKaiti","KaiTi","Kaiti SC",serif;pointer-events:none;z-index:0}
|
||
|
||
/* ---------- 详情层 ---------- */
|
||
#dt{position:fixed;inset:0;z-index:40;background:#fff;transform:translateX(100%);transition:transform .32s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column}
|
||
#dt.show{transform:none}
|
||
#dt .dnav{flex:none;display:flex;align-items:center;gap:8px;height:calc(50px + env(safe-area-inset-top));padding:env(safe-area-inset-top) 12px 0 6px;background:#fff;border-bottom:1px solid transparent;transition:border-color .2s}
|
||
#dt .dnav.on{border-color:var(--line)}
|
||
#dt .dnav .bk{width:36px;height:36px;display:grid;place-items:center;border-radius:50%}
|
||
#dt .dnav .bk .ic{width:22px;height:22px}
|
||
#dt .dnav img{width:30px;height:30px;border-radius:50%;object-fit:cover;background:#FFE3D3}
|
||
#dt .dnav .who{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25}
|
||
#dt .dnav .who b{font-size:14px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
#dt .dnav .who small{font-size:11px;color:var(--muted)}
|
||
#dt .dnav .fo{flex:none;height:28px;padding:0 13px;border-radius:99px;border:1.5px solid #F4593C;color:#F4593C;font-size:12.5px;font-weight:800}
|
||
#dt .dnav .fo.on{border-color:#E5DAD5;color:var(--muted)}
|
||
#dsc{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:none}
|
||
#dsc::-webkit-scrollbar{display:none}
|
||
.dcv .cv{font-size:24px}
|
||
.dcv .cv .kb{display:none}
|
||
.dbody{padding:16px 18px 6px}
|
||
.dbody h2{margin:0;font-size:19px;font-weight:900;line-height:1.45;letter-spacing:.2px}
|
||
.dbody .tx{margin-top:10px;font-size:15px;line-height:1.85;color:#3A302C;letter-spacing:.2px}
|
||
.dbody .tx p{margin:0 0 14px}
|
||
.dbody .tx p.li{margin:-6px 0 14px;padding-left:1.3em;text-indent:-1.3em}
|
||
.dbody .tx p.li+p.li{margin-top:-10px}
|
||
.dbody .dk{display:flex;align-items:center;gap:6px;margin-bottom:8px}
|
||
.dbody .dk button{height:22px;padding:0 8px;border-radius:7px;font-size:12px;font-weight:800}
|
||
.dbody .dk button{background:var(--kl);color:var(--kt)}
|
||
.dbody .tgs{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
|
||
.dbody .tgs button{height:24px;padding:0 9px;border-radius:99px;background:var(--peach);color:#D9583C;font-size:12.5px;font-weight:700}
|
||
/* 详情正文后:参与本话题 */
|
||
.pj{display:flex;align-items:center;gap:12px;margin:14px 18px 4px;padding:13px 14px;border-radius:16px;background:var(--hb)}
|
||
.pj{--hb:linear-gradient(140deg,var(--kl),var(--kl2));--hk:var(--kf);--ht:var(--kt)}
|
||
.pj .pt{flex:1;min-width:0}
|
||
.pj .pt b{display:block;font-size:14.5px;font-weight:900;color:#2A1E1E}
|
||
.pj .pt small{display:block;margin-top:2px;font-size:12px;color:#6E5C57}
|
||
.pj .pt small em{font-style:normal;font-weight:800;color:#E8473A}
|
||
.pj button{flex:none;height:32px;padding:0 13px;border-radius:99px;background:var(--hk);color:#fff;font-size:13px;font-weight:800}
|
||
|
||
/* ---------- 底部弹层:投稿规则 / 全部话题 ---------- */
|
||
#mask{position:fixed;inset:0;z-index:60;background:rgba(30,20,18,.45);opacity:0;pointer-events:none;transition:opacity .22s}
|
||
#mask.show{opacity:1;pointer-events:auto}
|
||
#sheet{position:fixed;left:0;right:0;bottom:0;z-index:61;max-height:82vh;display:flex;flex-direction:column;border-radius:22px 22px 0 0;background:#FFFBF8;transform:translateY(105%);transition:transform .28s cubic-bezier(.2,.8,.2,1)}
|
||
#sheet.show{transform:none}
|
||
#sheet .sg{width:36px;height:4px;margin:8px auto 0;border-radius:4px;background:#E6D8D2;flex:none}
|
||
#sheet .sbd{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:none;padding:6px 18px calc(18px + var(--safe-b))}
|
||
#sheet h3{margin:8px 0 0;font-size:18px;font-weight:900;text-align:center}
|
||
.rb{margin:14px 0 0;padding:16px 14px;border-radius:18px;text-align:center;color:#fff;background:radial-gradient(140px 90px at 100% 0,rgba(255,255,255,.3),transparent 70%),linear-gradient(120deg,#FF8A5B,#F4593C 60%,#E8473A)}
|
||
.rb small{display:block;font-size:12.5px;font-weight:700;opacity:.9}
|
||
.rb b{display:block;margin-top:4px;font-size:24px;font-weight:900;letter-spacing:.5px}
|
||
.rb b em{font-style:normal;color:#FFF3B8}
|
||
.rb i{display:block;margin-top:2px;font-style:normal;font-size:12px;opacity:.9}
|
||
.stp{margin:16px 0 0;padding:0;list-style:none;counter-reset:s}
|
||
.stp li{position:relative;padding:0 0 14px 38px;font-size:14px;line-height:1.6;color:#3A302C;counter-increment:s}
|
||
.stp li::before{content:counter(s);position:absolute;left:0;top:0;width:26px;height:26px;border-radius:50%;background:#FFEDE6;color:#F4593C;font-size:13px;font-weight:900;display:grid;place-items:center}
|
||
.stp li b{display:block;font-size:14.5px;font-weight:800;color:#2A1E1E}
|
||
.stp li small{display:block;font-size:12.5px;color:var(--muted)}
|
||
.cur-t{margin-top:12px;padding:10px 12px;border-radius:12px;background:#F6EEEA;font-size:13px;color:#6E5C57}
|
||
.cur-t b{color:#2A1E1E}
|
||
.sbtn{display:block;width:100%;height:46px;margin-top:6px;border-radius:99px;background:var(--btn);color:#fff;font-size:16px;font-weight:900;box-shadow:0 8px 16px -8px #EE5A3E}
|
||
.snote{margin-top:10px;text-align:center;font-size:11.5px;color:#B8A49E}
|
||
.tl-h{display:flex;align-items:center;gap:6px;margin:16px 0 8px;font-size:14px;font-weight:900}
|
||
.tl{display:grid;grid-template-columns:1fr 1fr;gap:8px}
|
||
.tl button{display:flex;align-items:center;gap:4px;min-height:42px;padding:6px 10px;border-radius:12px;text-align:left;font-size:13.5px;font-weight:700;line-height:1.35;background:var(--hb);color:#3A2C28}
|
||
.tl button.on{box-shadow:inset 0 0 0 2px var(--hk)}
|
||
.tl button{--hb:var(--kl);--hk:var(--kf)}
|
||
.tl button i{flex:none;font-style:normal;padding:0 4px;border-radius:5px;background:#FF5A3C;color:#fff;font-size:9.5px;font-weight:800;line-height:15px}
|
||
.tl-all{display:block;width:100%;height:40px;margin-top:14px;border-radius:12px;background:#F6EEEA;font-size:14px;font-weight:800;color:#6E5C57}
|
||
.dbody .tm{margin-top:12px;font-size:12px;color:#B8A49E}
|
||
.cm{margin-top:8px;padding:14px 18px 20px;border-top:8px solid #F8F3EF}
|
||
.cm-h{display:flex;align-items:baseline;gap:6px;font-size:15px;font-weight:900}
|
||
.cm-h small{font-size:12.5px;font-weight:500;color:var(--muted)}
|
||
.cm-in{display:flex;align-items:center;gap:8px;margin-top:12px}
|
||
.cm-in .me{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;background:linear-gradient(140deg,#FFC9B5,#F59A7F);color:#fff;font-size:12px;font-weight:800}
|
||
.cm-in button{flex:1;height:34px;padding:0 14px;border-radius:99px;background:#F5EEEA;text-align:left;font-size:13px;color:#B3A19B}
|
||
.ci{display:flex;gap:10px;padding:14px 0 12px;border-bottom:1px solid #F5EDE8}
|
||
.ci:last-child{border-bottom:0}
|
||
.ci>img,.ci>.me{width:32px;height:32px;border-radius:50%;object-fit:cover;flex:none;background:#FFE3D3}
|
||
.ci>.me{display:grid;place-items:center;background:linear-gradient(140deg,#FFC9B5,#F59A7F);color:#fff;font-size:12px;font-weight:800}
|
||
.ci.mine{animation:ncIn .35s ease both}
|
||
.ci-b{flex:1;min-width:0}
|
||
.ci-n{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
|
||
.ci-n b{color:#7A6A64;font-weight:700}
|
||
.ci-n .au{height:16px;padding:0 5px;border-radius:4px;background:#F4593C;color:#fff;font-size:10px;font-weight:800;line-height:16px}
|
||
.ci-n .mt{height:16px;padding:0 5px;border-radius:4px;background:#FFE7E0;color:#EC4D33;font-size:10px;font-weight:800;line-height:16px}
|
||
.ci-n .lk{margin-left:auto}
|
||
.ci-t{margin:3px 0 0;font-size:14.5px;line-height:1.65;color:#2F2624;word-break:break-word}
|
||
.ci-s{margin-top:3px;font-size:11.5px;color:#B8A49E}
|
||
.rp{margin-top:8px;padding:8px 10px;border-radius:10px;background:#F8F3EF;font-size:13px;line-height:1.65;color:#3A302C}
|
||
.rp p{margin:0 0 4px}
|
||
.rp p:last-child{margin-bottom:0}
|
||
.rp b{font-weight:700;color:#7A6A64}
|
||
.rp .au{display:inline-block;height:15px;margin:0 3px 0 -1px;padding:0 4px;border-radius:4px;background:#F4593C;color:#fff;font-size:9.5px;font-weight:800;line-height:15px;vertical-align:1px}
|
||
.cm-end{padding:18px 0 6px;text-align:center;font-size:12px;color:#C9B7B1}
|
||
|
||
.bar{flex:none;display:flex;align-items:center;gap:6px;padding:8px 10px calc(8px + var(--safe-b)) 14px;background:#fff;border-top:1px solid var(--line)}
|
||
.bar .ip{flex:1;min-width:0;display:flex;align-items:center;gap:6px;height:38px;padding:0 6px 0 14px;border-radius:99px;background:#F5EEEA}
|
||
.bar .ip .ic{width:15px;height:15px;color:#B3A19B}
|
||
.bar input{flex:1;min-width:0;height:100%;border:0;background:none;outline:none;font:inherit;font-size:14px;color:var(--ink)}
|
||
.bar input::placeholder{color:#B3A19B}
|
||
.bar .send{flex:none;height:28px;padding:0 12px;border-radius:99px;background:var(--btn);color:#fff;font-size:13px;font-weight:800}
|
||
.bar .send:disabled{opacity:.4}
|
||
.bar .ib{flex:none;display:flex;align-items:center;gap:3px;height:38px;padding:0 6px;font-size:13px;color:#5E504C;font-variant-numeric:tabular-nums}
|
||
.bar .ib .ic{width:23px;height:23px}
|
||
.bar .ib.on.lv{color:#F0453A}
|
||
.bar .ib.on.fv{color:#F2A516}
|
||
.bar .ib.pop .ic{animation:pop .35s ease}
|
||
.bar.typing .ib{display:none}
|
||
.bar:not(.typing) .send{display:none}
|
||
|
||
/* ---------- 投稿(11-01:用户可投稿 → 审核中 → 后台通过/不通过 → 下次打开提醒) ---------- */
|
||
.nav .mine{position:relative;flex:none;height:30px;padding:0 10px;border-radius:99px;background:#fff;border:1px solid #F0E2DA;font-size:12.5px;font-weight:800;color:#6E5A55}
|
||
.nav .mine i{position:absolute;right:-2px;top:-3px;min-width:16px;height:16px;padding:0 4px;border-radius:99px;background:#F0453A;color:#fff;font-size:10px;font-style:normal;font-weight:800;line-height:16px;text-align:center;box-shadow:0 0 0 2px #F8F3EF}
|
||
#cp{position:fixed;inset:0;z-index:50;background:#FFFBF8;display:flex;flex-direction:column;transform:translateY(100%);transition:transform .3s cubic-bezier(.2,.8,.2,1)}
|
||
#cp.show{transform:none}
|
||
#cp .cph{flex:none;display:flex;align-items:center;gap:8px;height:calc(50px + env(safe-area-inset-top));padding:env(safe-area-inset-top) 12px 0 6px;border-bottom:1px solid var(--line);background:#fff}
|
||
#cp .cph .x{width:36px;height:36px;display:grid;place-items:center;border-radius:50%;color:var(--ink)}
|
||
#cp .cph .x .ic{width:18px;height:18px}
|
||
#cp .cph h2{flex:1;margin:0;font-size:16px;font-weight:900;text-align:center}
|
||
#cp .cph .ok{flex:none;height:32px;padding:0 16px;border-radius:99px;background:var(--btn);color:#fff;font-size:14px;font-weight:900}
|
||
#cp .cph .ok:disabled{opacity:.45}
|
||
#cp .cpb{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:none;padding:14px 16px calc(24px + var(--safe-b))}
|
||
.cp-t{display:flex;align-items:center;gap:8px;width:100%;min-height:46px;padding:8px 12px;border-radius:14px;background:var(--kl,#F6EEEA);text-align:left}
|
||
.cp-t .ct2{flex:1;min-width:0;font-size:14px;font-weight:800;color:var(--kt,#6E5C57);line-height:1.4}
|
||
.cp-t .ch{flex:none;font-size:12px;font-weight:700;color:var(--muted);display:inline-flex;align-items:center}
|
||
.cp-rw{margin-top:10px;padding:9px 12px;border-radius:12px;background:#FFF1EB;font-size:12.5px;color:#9A5A44}
|
||
.cp-rw em{font-style:normal;font-weight:900;color:#E8473A}
|
||
.cp-in{display:block;width:100%;margin-top:14px;padding:4px 2px 10px;border:0;border-bottom:1px solid var(--line);background:none;outline:none;font:inherit;font-size:19px;font-weight:900;color:var(--ink)}
|
||
.cp-in::placeholder,.cp-ta::placeholder{color:#C2B0AA;font-weight:600}
|
||
.cp-ta{display:block;width:100%;min-height:260px;margin-top:12px;padding:2px;border:0;background:none;outline:none;resize:none;font:inherit;font-size:15.5px;line-height:1.8;color:#3A302C}
|
||
.cp-cnt{margin-top:4px;font-size:12px;color:var(--muted);text-align:right}
|
||
.cp-cnt b{color:#E8473A}
|
||
.cp-cnt.ok b{color:#2E8A7C}
|
||
.cp-pics{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
|
||
.cp-pics .pt,.cp-pics .add{position:relative;width:calc((100% - 16px) / 3);aspect-ratio:1;border-radius:12px;overflow:hidden;background:#F3EAE5}
|
||
.cp-pics .pt img{width:100%;height:100%;object-fit:cover}
|
||
.cp-pics .pt.up::after{content:"上传中…";position:absolute;inset:0;display:grid;place-items:center;background:rgba(255,255,255,.6);font-size:12px;color:#6E5C57}
|
||
.cp-pics .pt.bad::after{content:"上传失败";position:absolute;inset:0;display:grid;place-items:center;background:rgba(255,255,255,.75);font-size:12px;color:#E8473A}
|
||
.cp-pics .pt button{position:absolute;right:4px;top:4px;width:22px;height:22px;border-radius:50%;background:rgba(0,0,0,.5);color:#fff;font-size:15px;line-height:22px}
|
||
.cp-pics .add{display:grid;place-items:center;border:1.5px dashed #E2CFC7;background:#FFF8F4;color:#B8A49E;font-size:12px}
|
||
.cp-pics .add .ic{display:block;margin:0 auto 4px;width:22px;height:22px}
|
||
.cp-tip{margin-top:16px;font-size:12px;line-height:1.7;color:#B8A49E}
|
||
/* 我的投稿 */
|
||
.my-e{padding:26px 0 10px;text-align:center;color:var(--muted);font-size:13.5px}
|
||
.my-it{padding:12px 0;border-bottom:1px solid #F3E9E4}
|
||
.my-it:last-child{border-bottom:0}
|
||
.my-h{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
|
||
.my-h .tn{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.st{flex:none;height:20px;padding:0 7px;border-radius:6px;font-size:11.5px;font-weight:800;line-height:20px}
|
||
.st.pending{background:#FFF1DE;color:#C27612}
|
||
.st.approved{background:#DDF2EE;color:#21705F}
|
||
.st.rejected{background:#F2ECEA;color:#8A7570}
|
||
.my-it b{display:block;margin-top:5px;font-size:15px;font-weight:800;color:#2A1E1E}
|
||
.my-it p{margin:4px 0 0;font-size:12.5px;line-height:1.6;color:#7A6663}
|
||
.my-it p.why{padding:7px 10px;border-radius:10px;background:#F6F0EE}
|
||
.my-it p.rw2{padding:7px 10px;border-radius:10px;background:#FFF1EB;color:#9A5A44}
|
||
.my-it p.rw2 em{font-style:normal;font-weight:900;color:#E8473A}
|
||
/* 审核结果 / 提交成功弹窗 */
|
||
#rs{position:fixed;inset:0;z-index:70;display:grid;place-items:center;padding:24px;background:rgba(30,20,18,.5);opacity:0;pointer-events:none;transition:opacity .2s}
|
||
#rs.show{opacity:1;pointer-events:auto}
|
||
#rs .rsb{width:100%;max-width:320px;padding:22px 20px 18px;border-radius:22px;background:#FFFBF8;text-align:center;transform:scale(.94);transition:transform .2s}
|
||
#rs.show .rsb{transform:none}
|
||
#rs .rsi{width:58px;height:58px;margin:0 auto;border-radius:50%;display:grid;place-items:center;background:#FFEDE6;color:#F4593C}
|
||
#rs .rsi .ic{width:30px;height:30px}
|
||
#rs .rsi.ok{background:#DDF2EE;color:#2E8A7C}
|
||
#rs .rsi.no{background:#F2ECEA;color:#8A7570}
|
||
#rs h3{margin:12px 0 0;font-size:18px;font-weight:900}
|
||
#rs .rst{margin:6px 0 0;font-size:13.5px;line-height:1.7;color:#6E5C57}
|
||
#rs .rst b{color:#2A1E1E}
|
||
#rs .rst em{font-style:normal;font-weight:900;color:#E8473A}
|
||
#rs .rsw{margin-top:10px;padding:8px 10px;border-radius:10px;background:#F6F0EE;font-size:12.5px;line-height:1.6;color:#7A6663;text-align:left}
|
||
#rs .rsk{display:block;width:100%;height:42px;margin-top:16px;border-radius:99px;background:var(--btn);color:#fff;font-size:15px;font-weight:900}
|
||
/* 真实投稿:封面「精选」角标、详情配图 */
|
||
.cv .jx{position:absolute;right:.7em;top:.8em;z-index:2;height:1.55em;padding:0 .55em;border-radius:.5em;background:linear-gradient(135deg,#FFB547,#F4803C);color:#fff;font-size:.85em;font-weight:800;line-height:1.55em}
|
||
.dbody .pics{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:0 0 14px}
|
||
.dbody .pics img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:10px;background:#F3EAE5}
|
||
.dbody .pics img:only-child{grid-column:1/-1;aspect-ratio:auto}
|
||
|
||
.toast{position:fixed;left:50%;top:44%;z-index:80;max-width:280px;padding:10px 16px;border-radius:12px;background:rgba(40,30,28,.86);color:#fff;font-size:13.5px;line-height:1.6;text-align:center;transform:translate(-50%,8px);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
|
||
.toast.show{opacity:1;transform:translate(-50%,0)}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||
<symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-heart" viewBox="0 0 24 24"><path d="M12 20.3s-7.6-4.6-9.2-9.4C1.7 7.6 3.9 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.3 0 5.5 3.1 4.4 6.4-1.6 4.8-9.2 9.4-9.2 9.4z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-heart-f" viewBox="0 0 24 24"><path d="M12 20.3s-7.6-4.6-9.2-9.4C1.7 7.6 3.9 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.3 0 5.5 3.1 4.4 6.4-1.6 4.8-9.2 9.4-9.2 9.4z" fill="currentColor"/></symbol>
|
||
<symbol id="i-star" viewBox="0 0 24 24"><path d="M12 3.6l2.6 5.3 5.8.8-4.2 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.2-4.1 5.8-.8z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-star-f" viewBox="0 0 24 24"><path d="M12 3.6l2.6 5.3 5.8.8-4.2 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.2-4.1 5.8-.8z" fill="currentColor"/></symbol>
|
||
<symbol id="i-chat" viewBox="0 0 24 24"><path d="M4.5 18.8V7.6A3 3 0 017.5 4.6h9a3 3 0 013 3v6a3 3 0 01-3 3H8.8z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-pen" viewBox="0 0 24 24"><path d="M4 20h4L19 9l-4-4L4 16z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-grid" viewBox="0 0 24 24"><path d="M4.5 4.5h6v6h-6zM13.5 4.5h6v6h-6zM4.5 13.5h6v6h-6zM13.5 13.5h6v6h-6z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-home" viewBox="0 0 24 24"><path d="M3.8 11.2L12 4.3l8.2 6.9M6.2 9.4v10h11.6v-10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 17.6s-2.9-1.7-2.9-3.6c0-1 .8-1.7 1.6-1.7.6 0 1 .3 1.3.8.3-.5.7-.8 1.3-.8.8 0 1.6.7 1.6 1.7 0 1.9-2.9 3.6-2.9 3.6z" fill="currentColor"/></symbol>
|
||
<symbol id="i-bulb" viewBox="0 0 24 24"><path d="M9 17.5h6M9.8 20.5h4.4M12 3.5a6 6 0 00-3.6 10.8c.5.4.8 1 .8 1.6v1.6h5.6v-1.6c0-.6.3-1.2.8-1.6A6 6 0 0012 3.5z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-gift" viewBox="0 0 24 24"><path d="M4 10.5h16v3H4zM5.5 13.5h13v6.5h-13zM12 10.5V20M12 10.5c-1.2-2.6-4.8-4.4-6-2.6-1 1.6 1.6 2.6 6 2.6zm0 0c1.2-2.6 4.8-4.4 6-2.6 1 1.6-1.6 2.6-6 2.6z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-fire" viewBox="0 0 24 24"><path d="M12 21c-4 0-6.5-2.7-6.5-6.2 0-3.6 2.9-5.6 3.6-9.3 2.6 1.4 3.6 3.6 3.6 5.4 1-.6 1.6-1.8 1.7-3 2.4 1.9 4.1 4.3 4.1 7 0 3.5-2.5 6.1-6.5 6.1z" fill="currentColor"/></symbol>
|
||
<symbol id="i-x" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></symbol>
|
||
<symbol id="i-right" viewBox="0 0 24 24"><path d="M9 5l7 7-7 7" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-ring" viewBox="0 0 24 24"><path d="M12 20.3s-7.6-4.6-9.2-9.4C1.7 7.6 3.9 4.5 7.2 4.5c2 0 3.6 1.1 4.8 2.8 1.2-1.7 2.8-2.8 4.8-2.8 3.3 0 5.5 3.1 4.4 6.4-1.6 4.8-9.2 9.4-9.2 9.4z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-bag" viewBox="0 0 24 24"><path d="M4 8.5h16v10.5H4zM9 8.5V6.2c0-.9.7-1.7 1.7-1.7h2.6c.9 0 1.7.8 1.7 1.7v2.3M4 13h16" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-baby" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="2"/><path d="M9.2 14.6c1.6 1.4 4 1.4 5.6 0" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="9.3" cy="10.6" r="1.1" fill="currentColor"/><circle cx="14.7" cy="10.6" r="1.1" fill="currentColor"/></symbol>
|
||
<symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.5l4.5 4.5L19 7.5" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></symbol>
|
||
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5" fill="none" stroke="currentColor" stroke-width="2"/><path d="M12 7.5V12l3 2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></symbol>
|
||
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></symbol>
|
||
</svg>
|
||
|
||
<div id="sc">
|
||
<div class="top" id="top">
|
||
<div class="nav">
|
||
<button class="bk" id="back" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button>
|
||
<h1><span>孕妈广场</span></h1>
|
||
<button class="mine" id="mineBtn" type="button">我的投稿<i id="mineDot" class="hide"></i></button>
|
||
</div>
|
||
<div class="cats" id="cats" role="tablist" aria-label="分类"></div>
|
||
</div>
|
||
<div id="head"></div>
|
||
<div class="sh" id="fh"></div>
|
||
<div class="wf" id="wf"><div class="col"></div><div class="col"></div></div>
|
||
<div class="end"><b>— 到底啦 —</b><small>内容为示例占位,正式版将替换为妈妈们的真实分享</small></div>
|
||
</div>
|
||
|
||
<div id="dt" aria-hidden="true">
|
||
<div class="dnav" id="dnav">
|
||
<button class="bk" id="dback" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button>
|
||
<img id="dav" alt="">
|
||
<span class="who"><b id="dnm"></b><small id="dst"></small></span>
|
||
<button class="fo" id="dfo" type="button">关注</button>
|
||
</div>
|
||
<div id="dsc"></div>
|
||
<div class="bar" id="bar">
|
||
<label class="ip"><svg class="ic"><use href="#i-pen"/></svg><input id="cin" type="text" maxlength="200" placeholder="说点什么…" enterkeyhint="send"><button class="send" id="csend" type="button" disabled>发送</button></label>
|
||
<button class="ib lv" id="blk" type="button" aria-label="点赞"><svg class="ic"><use href="#i-heart"/></svg><span></span></button>
|
||
<button class="ib fv" id="bfv" type="button" aria-label="收藏"><svg class="ic"><use href="#i-star"/></svg><span></span></button>
|
||
<button class="ib" id="bcm" type="button" aria-label="评论"><svg class="ic"><use href="#i-chat"/></svg><span></span></button>
|
||
</div>
|
||
</div>
|
||
<div id="cp" aria-hidden="true">
|
||
<div class="cph"><button class="x" id="cpX" type="button" aria-label="关闭"><svg class="ic"><use href="#i-x"/></svg></button><h2>写我的故事</h2><button class="ok" id="cpOk" type="button">提交</button></div>
|
||
<div class="cpb">
|
||
<button type="button" class="cp-t" id="cpT"></button>
|
||
<div class="cp-rw">投稿被选中,奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆</div>
|
||
<input class="cp-in" id="cpTitle" type="text" maxlength="30" placeholder="起个标题(4~30 字)">
|
||
<textarea class="cp-ta" id="cpBody" maxlength="3000" placeholder="写下你的真实经历:发生了什么、当时怎么想、后来怎么做的……写得越具体,越容易被选中。"></textarea>
|
||
<div class="cp-cnt" id="cpCnt"></div>
|
||
<div class="cp-pics" id="cpPics"><label class="add" id="cpAdd"><span><svg class="ic"><use href="#i-plus"/></svg>配图(选填)</span><input id="cpFile" type="file" accept="image/*" hidden></label></div>
|
||
<div class="cp-tip">· 提交后进入审核,审核结果会在这里提醒你;通过的故事会展示在孕妈广场。<br>· 请写自己的真实经历,不要发广告、联系方式或别人的隐私。<br>· 草稿会自动保存在这台手机上。</div>
|
||
</div>
|
||
</div>
|
||
<div id="rs" role="dialog" aria-modal="true"><div class="rsb" id="rsb"></div></div>
|
||
<div id="mask"></div>
|
||
<div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div>
|
||
<div class="toast" id="toast"></div>
|
||
|
||
<script src="topics.js?v=26110123"></script>
|
||
<script src="data.js?v=26110123"></script>
|
||
<script>
|
||
(function () {
|
||
'use strict';
|
||
var $ = function (s, c) { return (c || document).querySelector(s); };
|
||
var T = window.GC_TOPICS || [], D = window.GC_DATA || {};
|
||
var TBY = {}; T.forEach(function (t) { TBY[t.id] = t; });
|
||
var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); };
|
||
var seed = function (t) { var x = 7; t = String(t); for (var i = 0; i < t.length; i++) x = (x * 31 + t.charCodeAt(i)) | 0; return Math.abs(x); };
|
||
var kfmt = function (n) { return n >= 10000 ? (n / 10000).toFixed(1).replace(/\.0$/, '') + '万' : n >= 1000 ? (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k' : String(n); };
|
||
/* 点赞 / 收藏 / 评论数:一万以内写实数,点一下能看见 +1 */
|
||
var cfmt = function (n) { return n >= 10000 ? (n / 10000).toFixed(1).replace(/\.0$/, '') + '万' : String(n); };
|
||
function rng(s) { var x = seed(s) || 1; return function () { x = (x * 1103515245 + 12345) & 0x7fffffff; return x / 0x7fffffff; }; }
|
||
|
||
/* ---------- 身份:同首页 hashParam,hash 优先、query 兜底 ---------- */
|
||
function param(name) {
|
||
try {
|
||
var h = (location.hash.slice(1) || '') + '&' + (location.search.slice(1) || '');
|
||
var m = h.match(new RegExp('(?:^|[&#])' + name + '=([^&#]*)'));
|
||
return m ? decodeURIComponent(m[1]).split('?')[0] : '';
|
||
} catch (e) { return ''; }
|
||
}
|
||
var OPENID = param('openid');
|
||
var MYNAME = param('nickname') || '孕妈'; /* 授权回填的昵称在 hash 里;没有就叫「孕妈」,后面另挂「我」标 */
|
||
|
||
/* ---------- 头像:沿用首页 assets/img/mom/ 写实头像 ---------- */
|
||
var AV = ['m01','m02','m03','m04','m05','m06','m07','m08','m09','m10','m11','m12','m13','m14','m15','m16','m17','m18','m19','m20','m21','m22',
|
||
'p01','p02','p03','p04','p05','p06','p07','p08','p09','p10','p11','p12','p13','p14','s01','s02','s03','s04','s05','s06','s07','s08','s09','s10',
|
||
'k01','k02','k03','k04','k05','k06','k07','k08','k09','k10','k11','k12','k13'];
|
||
var avSrc = function (key) { return '../assets/img/mom/' + AV[seed(key) % AV.length] + '.jpg'; };
|
||
var avOf = function (n) { return n.avatar || avSrc(n.author); }; /* 真实投稿用本人头像,占位笔记用头像池 */
|
||
|
||
/* ---------- 笔记:data.js 的原始内容 + 确定性补字段(id / 封面样式 / 比例 / 评论) ---------- */
|
||
var NOTES = [], NBY = {}; /* 真实投稿到达后会往前插(loadApproved),所以 NOTES / MIXED 用 var 可重赋值 */
|
||
var RATIO = [1.12, 0.94, 1.04, 0.88, 1.18, 0.98, 0.9];
|
||
T.forEach(function (t, ti) {
|
||
var d = D[t.id]; if (!d) return;
|
||
(d.notes || []).forEach(function (n, i) {
|
||
var o = {
|
||
id: t.id + '-' + (i + 1), t: t.id, i: i, title: n.title, cover: n.cover || n.title, coverSub: n.coverSub || '',
|
||
author: n.author, stage: n.stage, likes: +n.likes || 0, body: n.body || '',
|
||
ratio: n.photo ? 1.3 : RATIO[(ti + i * 3) % RATIO.length], tone: (ti + i) % 3, photo: n.photo || ''
|
||
};
|
||
NOTES.push(o); NBY[o.id] = o;
|
||
});
|
||
});
|
||
/* 「全部」的混排:各话题轮流取一条(同一话题不扎堆),每轮按 id 哈希打散 */
|
||
var MIXED = (function () {
|
||
var out = [], byT = T.map(function (t) { return NOTES.filter(function (n) { return n.t === t.id; }); });
|
||
for (var r = 0; r < 10; r++) {
|
||
var round = [];
|
||
byT.forEach(function (l) { if (l[r]) round.push(l[r]); });
|
||
round.sort(function (a, b) { return seed(a.id + 'm') % 97 - seed(b.id + 'm') % 97; });
|
||
out = out.concat(round);
|
||
}
|
||
return out;
|
||
})();
|
||
var AGO = ['3 分钟前', '18 分钟前', '1 小时前', '2 小时前', '5 小时前', '昨天 21:40', '昨天 08:12', '10-29', '10-27', '10-25'];
|
||
function commentsOf(n) {
|
||
if (n.real) return []; /* 真实投稿不配占位评论 */
|
||
var pool = (D[n.t] && D[n.t].comments) || [], r = rng(n.id + 'c');
|
||
var idx = pool.map(function (_, k) { return k; });
|
||
for (var k = idx.length - 1; k > 0; k--) { var j = Math.floor(r() * (k + 1)); var x = idx[k]; idx[k] = idx[j]; idx[j] = x; }
|
||
var cnt = Math.min(pool.length, 3 + (seed(n.id) % 6));
|
||
return idx.slice(0, cnt).map(function (k, m) {
|
||
var c = pool[k];
|
||
return { key: n.id + '#' + k, n: c.n, s: c.s, t: c.t, likes: Math.floor(r() * 180) + 2, ago: AGO[Math.min(AGO.length - 1, m * 2 + Math.floor(r() * 2))],
|
||
r: (c.r || []).map(function (x, q) { return { n: x.n, t: x.t, au: q === 0 && r() < .35 }; }) };
|
||
});
|
||
}
|
||
|
||
/* ---------- 本机存储 mmbox.gc.v1:{ <openid|_guest>: { like:{}, fav:{}, cl:{}, cm:{id:[{t,ts}]} } } ---------- */
|
||
var SK = 'mmbox.gc.v1', UK = OPENID || '_guest';
|
||
function loadAll() { try { return JSON.parse(localStorage.getItem(SK) || '{}') || {}; } catch (e) { return {}; } }
|
||
var ALL = loadAll();
|
||
var ME = ALL[UK] || (ALL[UK] = {});
|
||
['like', 'fav', 'cl', 'cm', 'fo'].forEach(function (k) { if (!ME[k] || typeof ME[k] !== 'object') ME[k] = {}; });
|
||
function save() { try { ALL[UK] = ME; localStorage.setItem(SK, JSON.stringify(ALL)); } catch (e) {} }
|
||
var liked = function (id) { return !!ME.like[id]; };
|
||
var likeN = function (n) { return n.likes + (liked(n.id) ? 1 : 0); };
|
||
var favN = function (n) { return Math.round(n.likes * .38) + 3 + (ME.fav[n.id] ? 1 : 0); };
|
||
var myCm = function (id) { return ME.cm[id] || []; };
|
||
var cmN = function (n) { return commentsOf(n).length + myCm(n.id).length; };
|
||
|
||
function toast(msg) {
|
||
var t = $('#toast'); t.textContent = msg; t.classList.add('show');
|
||
clearTimeout(toast._t); toast._t = setTimeout(function () { t.classList.remove('show'); }, 1800);
|
||
}
|
||
function haptic() { if (navigator.vibrate) navigator.vibrate(8); }
|
||
|
||
/* ---------- 封面:一种版式,颜色只按分类(家庭粉 / 经验青绿)× 3 个深浅 ---------- */
|
||
var PAL = {
|
||
family: { ink: '#C23A55', c: [['#FFE6EB', '#FFC6D2'], ['#FFEAE2', '#FFCBB8'], ['#FCE8F2', '#F5C4DC']] },
|
||
marriage: { ink: '#6346B0', c: [['#EFE9FF', '#D6C8F6'], ['#F5E8FA', '#E2C6EF'], ['#E9EBFF', '#C9CEF5']] },
|
||
work: { ink: '#2C5E9E', c: [['#E4EFFB', '#BED5F1'], ['#E5F2F8', '#BFDDEB'], ['#ECEFF6', '#CBD3E6']] },
|
||
baby: { ink: '#21705F', c: [['#E0F3EE', '#B8E3D8'], ['#E6F3E3', '#C2E2BE'], ['#E1EFF5', '#B9D9E7']] }
|
||
};
|
||
var CAT_IC = { family: 'i-home', marriage: 'i-ring', work: 'i-bag', baby: 'i-baby' };
|
||
var CAT_SHORT = { family: '家庭', marriage: '婚姻', work: '职场', baby: '母婴' };
|
||
var CAT_SUB = { family: '婆家、原生家庭、长辈、亲戚、日常拉扯', marriage: '夫妻相处、落差、分工、情绪、细碎磨合',
|
||
work: '在岗孕妈、产检、边界、顾虑、复工', baby: '身体感受、囤货、预算、疼痛、未知焦虑' };
|
||
var kbHTML = function (cat) { return '<span class="kb k-' + cat + '"><svg class="ic"><use href="#' + CAT_IC[cat] + '"/></svg>' + CAT_SHORT[cat] + '</span>'; };
|
||
function coverHTML(n, h) {
|
||
var t = TBY[n.t], pl = PAL[t.cat], c = pl.c[n.tone];
|
||
if (n.photo) return '<div class="cv ph" style="' + (h ? 'height:' + h : '') + '"><img src="' + esc(n.photo) + '" alt="" loading="lazy">' + kbHTML(t.cat) + '</div>';
|
||
return '<div class="cv" style="--c1:' + c[0] + ';--c2:' + c[1] + ';--tk:' + pl.ink + ';' + (h ? 'height:' + h : '') + '">' + kbHTML(t.cat) + (n.real ? '<span class="jx">精选投稿</span>' : '') +
|
||
'<div class="ct"><div class="t1">' + esc(n.cover) + '</div><div class="t2">' + esc(n.coverSub) + '</div></div><i class="wm" aria-hidden="true">' + esc(t.g) + '</i></div>';
|
||
}
|
||
function likeHTML(n) {
|
||
var on = liked(n.id);
|
||
return '<span class="lk' + (on ? ' on' : '') + '" data-like="' + n.id + '" role="button" aria-label="点赞"><svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + cfmt(likeN(n)) + '</span>';
|
||
}
|
||
function cardHTML(n, showTopic) {
|
||
var t = TBY[n.t];
|
||
return '<button type="button" class="nc" data-id="' + n.id + '"><div class="cvw">' +
|
||
coverHTML(n, 'calc(var(--cw) * ' + n.ratio + ')') + '</div>' +
|
||
'<div class="nb"><h3>' + esc(n.title) + '</h3>' + (showTopic ? '<span class="tp k-' + t.cat + '"># ' + esc(t.name) + '</span>' : '') + '<div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>';
|
||
}
|
||
|
||
/* ---------- 列表 ---------- */
|
||
/* cur 当前话题('' = 不限话题);catF 一级分类('' 全部 / family 家庭 / marriage 婚姻 / work 职场 / baby 母婴)。选了话题时 catF 恒等于该话题的 cat */
|
||
var cur = '', catF = '';
|
||
var CATS = [['', '全部', 'i-grid'], ['family', '家庭', 'i-home'], ['marriage', '婚姻', 'i-ring'], ['work', '职场', 'i-bag'], ['baby', '母婴', 'i-baby']];
|
||
var CAT_ORDER = ['family', 'marriage', 'work', 'baby'];
|
||
var CAT_NAME = { family: '家庭方向', marriage: '婚姻方向', work: '职场方向', baby: '母婴方向' };
|
||
var inCat = function (t) { return !catF || t.cat === catF; };
|
||
/* 投稿奖励(11-01 用户定):话题投稿被选中 → 30 元现金 + 500 兜豆 */
|
||
var REWARD = '<em>¥30</em> 现金 + <em>500</em> 兜豆';
|
||
function renderCats() {
|
||
$('#cats').innerHTML = CATS.map(function (x) {
|
||
return '<button type="button" role="tab" data-c="' + x[0] + '" class="c-' + (x[0] || 'all') + (catF === x[0] ? ' on' : '') + '" aria-selected="' + (catF === x[0]) + '">' +
|
||
'<svg class="ic"><use href="#' + x[2] + '"/></svg>' + x[1] + '</button>';
|
||
}).join('');
|
||
}
|
||
function rewardHTML(sm) {
|
||
return '<button type="button" class="rw' + (sm ? ' sm' : '') + '" data-rule="1"><span class="gf"><svg class="ic"><use href="#i-gift"/></svg></span>' +
|
||
'<span class="rt"><small>参与话题投稿 · 被选中奖励</small><b>' + REWARD + '</b></span><span class="go">怎么参与<svg class="ic" style="width:12px;height:12px"><use href="#i-right"/></svg></span></button>';
|
||
}
|
||
/* 热门话题:带 hot 的排前面,其余按原顺序;跟着一级分类过滤 */
|
||
function hotList() {
|
||
var l = T.filter(inCat), hot = l.filter(function (t) { return t.hot; });
|
||
if (!catF) { /* 「全部」下四块轮流排,避免前几张全是同一块 */
|
||
var by = CAT_ORDER.map(function (c) { return hot.filter(function (t) { return t.cat === c; }); }), rr = [];
|
||
for (var r = 0; r < 5; r++) by.forEach(function (x) { if (x[r]) rr.push(x[r]); });
|
||
hot = rr;
|
||
}
|
||
return hot.concat(l.filter(function (t) { return !t.hot; }));
|
||
}
|
||
function renderHead() {
|
||
var t = TBY[cur], el = $('#head'), fh = $('#fh');
|
||
if (!t) {
|
||
var hl = hotList();
|
||
el.innerHTML = rewardHTML() +
|
||
'<div class="sh"><svg class="fire"><use href="#i-fire"/></svg><h2>热门话题</h2><button type="button" class="more" data-all="1">全部 ' + hl.length + ' 个<svg class="ic" style="width:13px;height:13px"><use href="#i-right"/></svg></button></div>' +
|
||
'<div class="hot">' + hl.slice(0, catF ? 10 : 12).map(function (x) {
|
||
return '<div class="hc k-' + x.cat + '" data-t="' + x.id + '" role="button"><i class="wm" aria-hidden="true">' + esc(x.g) + '</i>' + (x.hot ? '<span class="rk">热</span>' : '') + kbHTML(x.cat) +
|
||
'<h3># ' + esc(x.name) + '</h3><p>' + esc((D[x.id] || {}).desc || '') + '</p>' +
|
||
'<button type="button" class="jn" data-join="' + x.id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button></div>';
|
||
}).join('') + '</div>';
|
||
fh.innerHTML = '<h2>' + (catF ? CAT_NAME[catF] : '大家在聊') + '</h2>' + (catF ? '<small>' + CAT_SUB[catF] + '</small>' : '');
|
||
return;
|
||
}
|
||
var d = D[t.id] || {};
|
||
el.innerHTML = '<div class="th k-' + t.cat + '"><i class="wm" aria-hidden="true">' + esc(t.g) + '</i><button type="button" class="x" data-t="" aria-label="看全部"><svg class="ic"><use href="#i-x"/></svg></button>' +
|
||
kbHTML(t.cat) + '<h2><em>#</em>' + esc(t.name) + '</h2><p>' + esc(d.desc || '') + '</p>' +
|
||
'<div class="tf"><button type="button" class="join" data-join="' + t.id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button><button type="button" class="sw" data-all="1">换个话题</button></div></div>' + rewardHTML(true);
|
||
fh.innerHTML = '<h2>这个话题下的分享</h2>';
|
||
}
|
||
function renderFeed() {
|
||
var list = cur ? NOTES.filter(function (n) { return n.t === cur; }) : MIXED.filter(function (n) { return inCat(TBY[n.t]); });
|
||
var wf = $('#wf'), cols = wf.children;
|
||
cols[0].innerHTML = ''; cols[1].innerHTML = '';
|
||
var cw = cols[0].clientWidth || 175;
|
||
wf.style.setProperty('--cw', cw + 'px');
|
||
/* 真瀑布流:每张卡放进当前更矮的那一列(逐张量高,标题一行/两行也算进去) */
|
||
var hs = [0, 0], tmp = document.createElement('div');
|
||
list.forEach(function (n, k) {
|
||
tmp.innerHTML = cardHTML(n, !cur);
|
||
var el = tmp.firstChild; el.style.animationDelay = Math.min(k, 10) * 30 + 'ms';
|
||
var c = hs[0] <= hs[1] ? 0 : 1;
|
||
cols[c].appendChild(el);
|
||
hs[c] += el.offsetHeight + 8;
|
||
});
|
||
}
|
||
function setQuery(t, n) {
|
||
var q = new URLSearchParams(location.search);
|
||
if (t) q.set('t', t); else q.delete('t');
|
||
if (!t && catF) q.set('c', catF); else q.delete('c'); /* 只选了分类没选话题时记在 ?c=,刷新 / 详情返回还在原分类 */
|
||
if (n) q.set('n', n); else q.delete('n');
|
||
q.delete('mine');
|
||
var s = q.toString();
|
||
return location.pathname + (s ? '?' + s : '') + location.hash; /* hash(身份)原样保留 */
|
||
}
|
||
function selectTopic(t, smooth) {
|
||
if (!TBY[t]) t = '';
|
||
cur = t;
|
||
if (t) catF = TBY[t].cat; /* 首页带 ?t= 进来 / 点详情里的话题标签:分类跟着切到该话题所属类 */
|
||
renderCats(); renderHead(); renderFeed();
|
||
history.replaceState(history.state, '', setQuery(cur, ''));
|
||
var sc = $('#sc'); if (smooth !== false) sc.scrollTop = 0;
|
||
}
|
||
$('#cats').addEventListener('click', function (e) {
|
||
var b = e.target.closest('button[data-c]');
|
||
if (!b || (b.dataset.c === catF && !cur)) return;
|
||
catF = b.dataset.c; haptic();
|
||
selectTopic(''); /* 换分类回到该类「全部」,避免停在别类话题上 */
|
||
});
|
||
$('#head').addEventListener('click', function (e) {
|
||
var j = e.target.closest('[data-join]'); if (j) { haptic(); openRule(j.dataset.join); return; }
|
||
if (e.target.closest('[data-rule]')) { openRule(''); return; }
|
||
if (e.target.closest('[data-all]')) { openTopics(); return; }
|
||
var b = e.target.closest('[data-t]'); if (b) { haptic(); selectTopic(b.dataset.t); }
|
||
});
|
||
|
||
/* ---------- 底部弹层:投稿规则 / 全部话题 ---------- */
|
||
var sheetOn = '';
|
||
function openSheet(kind, html) {
|
||
sheetOn = kind; $('#sbd').innerHTML = html; $('#sbd').scrollTop = 0;
|
||
$('#mask').classList.add('show'); $('#sheet').classList.add('show');
|
||
}
|
||
var pickFor = '';
|
||
function closeSheet() { sheetOn = ''; $('#mask').classList.remove('show'); $('#sheet').classList.remove('show'); }
|
||
function openRule(tid) {
|
||
var t = TBY[tid];
|
||
openSheet('rule', '<h3>话题投稿有奖</h3>' +
|
||
'<div class="rb"><small>投稿被选中,每篇奖励</small><b>' + REWARD + '</b></div>' +
|
||
(t ? '<div class="cur-t">你要参与的话题:<b># ' + esc(t.name) + '</b></div>' : '') +
|
||
'<ol class="stp">' +
|
||
'<li><b>选一个话题</b><small>在「热门话题」或「全部话题」里挑你有话说的那个</small></li>' +
|
||
'<li><b>写下你的真实经历</b><small>家里的暖事、踩过的坑、过来人的经验都可以</small></li>' +
|
||
'<li><b>编辑挑选,被选中就发奖励</b><small>选中的故事会展示在孕妈广场,奖励发给作者</small></li></ol>' +
|
||
'<button type="button" class="sbtn" data-write="' + (t ? t.id : '') + '">写我的故事</button>' +
|
||
'<div class="snote">提交后进入审核,审核结果会在孕妈广场提醒你</div>');
|
||
}
|
||
function openTopics() {
|
||
var grp = function (cat) {
|
||
return '<div class="tl-h">' + kbHTML(cat) + CAT_NAME[cat] + '</div><div class="tl k-' + cat + '">' + T.filter(function (t) { return t.cat === cat; }).map(function (t) {
|
||
return '<button type="button" data-pick="' + t.id + '" class="' + (cur === t.id ? 'on' : '') + '"># ' + esc(t.name) + (t.hot ? '<i>热</i>' : '') + '</button>';
|
||
}).join('') + '</div>';
|
||
};
|
||
openSheet('topics', '<h3>全部话题</h3>' + (catF ? [catF] : []).concat(CAT_ORDER.filter(function (c) { return c !== catF; })).map(grp).join('') +
|
||
'<button type="button" class="tl-all" data-pick="">看全部分享</button>');
|
||
}
|
||
$('#mask').addEventListener('click', closeSheet);
|
||
$('#sheet').addEventListener('click', function (e) {
|
||
var p = e.target.closest('[data-pick]');
|
||
if (p && pickFor === 'compose') { closeSheet(); pickFor = ''; if (p.dataset.pick) setCpTopic(p.dataset.pick); return; }
|
||
if (p) { closeSheet(); haptic(); if (!p.dataset.pick) catF = ''; selectTopic(p.dataset.pick); return; }
|
||
var w = e.target.closest('[data-write]');
|
||
if (w) { closeSheet(); openCompose(w.dataset.write || cur); return; }
|
||
if (e.target.closest('[data-mywrite]')) { closeSheet(); openCompose(cur); }
|
||
});
|
||
|
||
/* 卡片:点心形就地点赞,点别处进详情 */
|
||
function toggleLike(id) {
|
||
if (ME.like[id]) delete ME.like[id]; else ME.like[id] = 1;
|
||
save(); haptic();
|
||
}
|
||
function syncCardLike(id) {
|
||
var n = NBY[id];
|
||
document.querySelectorAll('.lk[data-like="' + id + '"]').forEach(function (el) {
|
||
var on = liked(id);
|
||
el.classList.toggle('on', on);
|
||
el.innerHTML = '<svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + cfmt(likeN(n));
|
||
if (on) { el.classList.remove('pop'); void el.offsetWidth; el.classList.add('pop'); }
|
||
});
|
||
}
|
||
$('#wf').addEventListener('click', function (e) {
|
||
var lk = e.target.closest('[data-like]');
|
||
if (lk) { e.stopPropagation(); toggleLike(lk.dataset.like); syncCardLike(lk.dataset.like); return; }
|
||
var c = e.target.closest('.nc');
|
||
if (c) openNote(c.dataset.id, true);
|
||
});
|
||
|
||
/* ---------- 详情 ---------- */
|
||
var openId = '', pushed = false;
|
||
/* 正文按 \n 分段;「1. 」「2、」开头的行当清单项:悬挂缩进、条间距更紧 */
|
||
function bodyHTML(s) {
|
||
return String(s).split(/\n+/).map(function (p) { return p.trim(); }).filter(Boolean).map(function (p) {
|
||
return /^\d{1,2}[.、.]\s*/.test(p) ? '<p class="li">' + esc(p) + '</p>' : '<p>' + esc(p) + '</p>';
|
||
}).join('');
|
||
}
|
||
function commentHTML(c, mine) {
|
||
if (mine) {
|
||
return '<div class="ci mine"><span class="me">我</span><div class="ci-b"><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span></div>' +
|
||
'<p class="ci-t">' + esc(c.t) + '</p><div class="ci-s">' + agoOf(c.ts) + '</div></div></div>';
|
||
}
|
||
var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0);
|
||
var rp = c.r.length ? '<div class="rp">' + c.r.map(function (x) { return '<p><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + ':' + esc(x.t) + '</p>'; }).join('') + '</div>' : '';
|
||
return '<div class="ci"><img src="' + avSrc(c.n) + '" alt="" loading="lazy"><div class="ci-b"><div class="ci-n"><b>' + esc(c.n) + '</b>' +
|
||
'<span class="lk' + (on ? ' on' : '') + '" data-cl="' + esc(c.key) + '" data-base="' + c.likes + '" role="button"><svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + n + '</span></div>' +
|
||
'<p class="ci-t">' + esc(c.t) + '</p><div class="ci-s">' + esc(c.s || '') + ' · ' + c.ago + '</div>' + rp + '</div></div>';
|
||
}
|
||
function agoOf(ts) {
|
||
var s = Math.max(0, (Date.now() - ts) / 1000);
|
||
if (s < 60) return '刚刚';
|
||
if (s < 3600) return Math.floor(s / 60) + ' 分钟前';
|
||
if (s < 86400) return Math.floor(s / 3600) + ' 小时前';
|
||
var d = new Date(ts); return (d.getMonth() + 1) + '-' + d.getDate();
|
||
}
|
||
function renderComments(n) {
|
||
var mine = myCm(n.id).slice().reverse(), cs = commentsOf(n);
|
||
$('#cmh').innerHTML = '评论 <small>共 ' + cmN(n) + ' 条</small>';
|
||
$('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + cs.map(function (c) { return commentHTML(c); }).join('');
|
||
}
|
||
function syncBar(n, popK) {
|
||
var lv = $('#blk'), fv = $('#bfv'), on = liked(n.id), fo = !!ME.fav[n.id];
|
||
lv.classList.toggle('on', on); lv.querySelector('use').setAttribute('href', on ? '#i-heart-f' : '#i-heart'); lv.querySelector('span').textContent = cfmt(likeN(n));
|
||
fv.classList.toggle('on', fo); fv.querySelector('use').setAttribute('href', fo ? '#i-star-f' : '#i-star'); fv.querySelector('span').textContent = cfmt(favN(n));
|
||
$('#bcm span').textContent = cfmt(cmN(n));
|
||
if (popK) { var b = popK === 'lv' ? lv : fv; b.classList.remove('pop'); void b.offsetWidth; b.classList.add('pop'); }
|
||
}
|
||
function openNote(id, push) {
|
||
var n = NBY[id]; if (!n) return;
|
||
var t = TBY[n.t];
|
||
openId = id;
|
||
$('#dav').src = avOf(n);
|
||
$('#dnm').textContent = n.author;
|
||
$('#dst').textContent = n.stage || '';
|
||
var fo = $('#dfo'); fo.classList.toggle('on', !!ME.fo[n.author]); fo.textContent = ME.fo[n.author] ? '已关注' : '关注';
|
||
var h = Math.round(window.innerWidth * (n.photo ? 1.1 : .72)); /* 详情封面统一矮一点,正文早点露出来 */
|
||
var day = 26 + (seed(n.id) % 6), mon = day > 31 ? 11 : 10;
|
||
var when = n.real ? (function (d) { return (d.getMonth() + 1) + '-' + d.getDate(); })(new Date(n.at)) : mon + '-' + (day > 31 ? day - 31 : day);
|
||
$('#dsc').innerHTML = '<div class="dcv">' + coverHTML(n, h + 'px') + '</div>' +
|
||
'<div class="dbody"><div class="dk">' + kbHTML(t.cat) + '<button type="button" class="k-' + t.cat + '" data-go="' + t.id + '"># ' + esc(t.name) + '</button></div>' +
|
||
'<h2>' + esc(n.title) + '</h2><div class="tx">' + bodyHTML(n.body) + '</div>' +
|
||
((n.images || []).length ? '<div class="pics">' + n.images.map(function (u) { return '<img src="' + esc(u) + '" alt="" loading="lazy">'; }).join('') + '</div>' : '') +
|
||
'<div class="tm">' + when + (n.stage ? ' · ' + esc(n.stage) : '') + (n.real ? ' · 妈妈投稿' : '') + '</div></div>' +
|
||
'<div class="pj k-' + t.cat + '"><span class="pt"><b>你也有类似的经历?</b><small>投稿被选中得 ' + REWARD + '</small></span><button type="button" data-join="' + t.id + '">参与话题</button></div>' +
|
||
'<div class="cm" id="cmw"><div class="cm-h" id="cmh"></div>' +
|
||
'<div class="cm-in"><span class="me">我</span><button type="button" id="cmgo">留下你的温柔一句…</button></div>' +
|
||
'<div id="cml"></div><div class="cm-end">— 没有更多评论了 —</div></div>';
|
||
renderComments(n); syncBar(n);
|
||
$('#cin').value = ''; $('#bar').classList.remove('typing'); $('#csend').disabled = true;
|
||
$('#dsc').scrollTop = 0; $('#dnav').classList.remove('on');
|
||
var dt = $('#dt'); dt.classList.add('show'); dt.setAttribute('aria-hidden', 'false');
|
||
if (push) { history.pushState({ gcNote: id }, '', setQuery(cur, id)); pushed = true; }
|
||
else history.replaceState(history.state, '', setQuery(cur, id));
|
||
}
|
||
function hideNote() {
|
||
var dt = $('#dt'); dt.classList.remove('show'); dt.setAttribute('aria-hidden', 'true');
|
||
$('#cin').blur();
|
||
var id = openId; openId = '';
|
||
if (id) syncCardLike(id);
|
||
}
|
||
function closeNote() {
|
||
if (!openId) return;
|
||
if (pushed) { history.back(); return; } /* popstate 里 hideNote */
|
||
hideNote(); history.replaceState(history.state, '', setQuery(cur, ''));
|
||
}
|
||
window.addEventListener('popstate', function () {
|
||
if (sheetOn) closeSheet();
|
||
pushed = false;
|
||
if (openId) hideNote();
|
||
});
|
||
$('#dback').addEventListener('click', closeNote);
|
||
$('#dfo').addEventListener('click', function () {
|
||
var n = NBY[openId]; if (!n) return;
|
||
if (ME.fo[n.author]) delete ME.fo[n.author]; else ME.fo[n.author] = 1;
|
||
save(); haptic();
|
||
this.classList.toggle('on', !!ME.fo[n.author]); this.textContent = ME.fo[n.author] ? '已关注' : '关注';
|
||
});
|
||
$('#dsc').addEventListener('scroll', function () { $('#dnav').classList.toggle('on', this.scrollTop > 8); }, { passive: true });
|
||
$('#dsc').addEventListener('click', function (e) {
|
||
var jn = e.target.closest('[data-join]'); if (jn) { haptic(); openRule(jn.dataset.join); return; }
|
||
var g = e.target.closest('[data-go]');
|
||
if (g) { var to = g.dataset.go; closeNote(); setTimeout(function () { if (!to) catF = ''; selectTopic(to); }, 60); return; }
|
||
var cl = e.target.closest('[data-cl]');
|
||
if (cl) {
|
||
var k = cl.dataset.cl, on;
|
||
if (ME.cl[k]) delete ME.cl[k]; else ME.cl[k] = 1;
|
||
save(); haptic(); on = !!ME.cl[k];
|
||
cl.classList.toggle('on', on);
|
||
cl.innerHTML = '<svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + (+cl.dataset.base + (on ? 1 : 0));
|
||
if (on) { cl.classList.remove('pop'); void cl.offsetWidth; cl.classList.add('pop'); }
|
||
return;
|
||
}
|
||
if (e.target.closest('#cmgo')) $('#cin').focus();
|
||
});
|
||
$('#blk').addEventListener('click', function () {
|
||
var n = NBY[openId]; if (!n) return;
|
||
toggleLike(n.id); syncBar(n, liked(n.id) ? 'lv' : '');
|
||
});
|
||
$('#bfv').addEventListener('click', function () {
|
||
var n = NBY[openId]; if (!n) return;
|
||
if (ME.fav[n.id]) delete ME.fav[n.id]; else ME.fav[n.id] = 1;
|
||
save(); haptic(); syncBar(n, ME.fav[n.id] ? 'fv' : '');
|
||
toast(ME.fav[n.id] ? '已收藏,在这台手机上随时能找到' : '已取消收藏');
|
||
});
|
||
$('#bcm').addEventListener('click', function () {
|
||
var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' });
|
||
});
|
||
var cin = $('#cin');
|
||
cin.addEventListener('focus', function () { $('#bar').classList.add('typing'); });
|
||
cin.addEventListener('blur', function () { setTimeout(function () { if (!cin.value.trim()) $('#bar').classList.remove('typing'); }, 120); });
|
||
cin.addEventListener('input', function () { $('#csend').disabled = !cin.value.trim(); });
|
||
cin.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); send(); } });
|
||
$('#csend').addEventListener('click', send);
|
||
function send() {
|
||
var n = NBY[openId], v = cin.value.trim();
|
||
if (!n || !v) return;
|
||
(ME.cm[n.id] = myCm(n.id)).push({ t: v.slice(0, 200), ts: Date.now() });
|
||
save(); haptic();
|
||
cin.value = ''; $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing');
|
||
renderComments(n); syncBar(n);
|
||
var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' });
|
||
toast('评论已发出');
|
||
}
|
||
|
||
/* ================= 投稿(2026-11-01) =================
|
||
用户原话:「用户的账号可以去投稿……提交之后会显示『正在被审核』。如果用户的稿件被通过,后台会给他一个提醒」。
|
||
接口 box_app /api/mp/public/mama-box/plaza/*(只认 openid):
|
||
POST post {topic,title,body,images[]} → 稿件(pending)· GET mine → {list, unread} · POST mine/seen {ids}
|
||
GET posts?limit= → 已通过的稿件(不含 openid),混进广场展示,封面标「精选投稿」。
|
||
审核在管理后台「孕妈广场投稿」页;通过 = 被选中,奖励 ¥30 现金 + 500 兜豆由运营线下发放、后台标记。
|
||
· 提醒:每次打开广场拉 mine,unread(审核有结果且没提醒过)逐条弹窗,关掉后 seen。首页广场模块也会挂一条提示(app.js initPlaza)。
|
||
· 草稿存本机 mmbox.gc.draft.v1(按 openid),关掉写稿页不丢。 */
|
||
var API = '/api/mp/public/mama-box/plaza', UNION = param('unionid');
|
||
var idq = function () { return 'openid=' + encodeURIComponent(OPENID) + (UNION ? '&unionid=' + encodeURIComponent(UNION) : ''); };
|
||
var getJ = function (u, opt) { return fetch(u, opt).then(function (r) { return r.json(); }); };
|
||
var ST_NAME = { pending: '审核中', approved: '已通过', rejected: '未通过' };
|
||
var MINE = [];
|
||
|
||
/* 已通过的稿件 → 混进笔记流(话题流和「全部」都排最前) */
|
||
function loadApproved() {
|
||
getJ(API + '/posts?limit=100').then(function (j) {
|
||
var l = (j && j.result && (j.result.list || j.result)) || [];
|
||
if (!Array.isArray(l) || !l.length) return;
|
||
var add = [];
|
||
l.forEach(function (p, k) {
|
||
if (!TBY[p.topic] || NBY['u-' + p.id]) return;
|
||
var o = { id: 'u-' + p.id, t: p.topic, real: true, title: p.title, cover: p.title.length > 9 ? p.title.slice(0, 8) + '…' : p.title, coverSub: '来自妈妈的真实投稿',
|
||
author: p.nickname || '孕妈', avatar: p.avatar || '', stage: p.stage || '', likes: 0, body: p.body || '', images: p.images || [],
|
||
at: p.approvedAt || p.at || Date.now(), ratio: RATIO[k % RATIO.length], tone: k % 3 };
|
||
NBY[o.id] = o; add.push(o);
|
||
});
|
||
if (!add.length) return;
|
||
NOTES = add.concat(NOTES); MIXED = add.concat(MIXED);
|
||
renderFeed();
|
||
if (deep && NBY[deep] && !openId) openNote(deep, false); /* 分享出去的真实投稿链接:稿件到了再开 */
|
||
}).catch(function () {});
|
||
}
|
||
|
||
/* 我的投稿 */
|
||
function loadMine(cb) {
|
||
if (!OPENID) return;
|
||
getJ(API + '/mine?' + idq()).then(function (j) {
|
||
var r = j && j.result; if (!r) return;
|
||
MINE = r.list || [];
|
||
var un = r.unread || [];
|
||
var d = $('#mineDot'); d.textContent = un.length || ''; d.classList.toggle('hide', !un.length);
|
||
if (cb) cb(); else if (un.length) showResults(un);
|
||
}).catch(function () {});
|
||
}
|
||
function fmtDay(ms) { var d = new Date(ms); return (d.getMonth() + 1) + '月' + d.getDate() + '日'; }
|
||
function openMine() {
|
||
var h = '<h3>我的投稿</h3>';
|
||
if (!OPENID) h += '<div class="my-e">请从小程序里打开孕妈广场,才能查看你的投稿</div>';
|
||
else if (!MINE.length) h += '<div class="my-e">还没有投稿,写下你的第一个故事吧</div>';
|
||
else h += MINE.map(function (p) {
|
||
var t = TBY[p.topic];
|
||
return '<div class="my-it"><div class="my-h"><span class="tn"># ' + esc(t ? t.name : p.topicName || '') + '</span><span>' + fmtDay(p.at) + '</span><span class="st ' + p.status + '">' + (ST_NAME[p.status] || '') + '</span></div>' +
|
||
'<b>' + esc(p.title) + '</b>' +
|
||
(p.status === 'pending' ? '<p>正在审核中,有结果会第一时间提醒你</p>' : '') +
|
||
(p.status === 'rejected' ? '<p class="why">没通过的原因:' + esc(p.reason || '暂不符合展示要求') + '</p>' : '') +
|
||
(p.status === 'approved' ? '<p class="rw2">已被选中,奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆 · ' + (p.reward === 'paid' ? '已发放' : '待发放') + '</p>' : '') + '</div>';
|
||
}).join('');
|
||
h += '<button type="button" class="sbtn" data-mywrite="1" style="margin-top:16px">写新的故事</button>';
|
||
openSheet('mine', h);
|
||
}
|
||
$('#mineBtn').addEventListener('click', function () { haptic(); loadMine(openMine); openMine(); });
|
||
|
||
/* 审核结果弹窗:逐条弹,全部看完一次性 seen */
|
||
function showResults(list) {
|
||
var q = list.slice(), ids = list.map(function (p) { return p.id; });
|
||
(function next() {
|
||
var p = q.shift();
|
||
if (!p) {
|
||
fetch(API + '/mine/seen?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ids: ids }) }).catch(function () {});
|
||
$('#mineDot').classList.add('hide');
|
||
return;
|
||
}
|
||
var ok = p.status === 'approved';
|
||
showRs(ok ? 'ok' : 'no', ok ? '你的投稿通过啦' : '这篇投稿没有通过',
|
||
'《<b>' + esc(p.title) + '</b>》' + (ok ? '已被选中,将展示在孕妈广场。<br>奖励 <em>¥30</em> 现金 + <em>500</em> 兜豆,工作人员会尽快发放。' : '暂时没有通过审核,可以修改后重新投稿。'),
|
||
ok ? '' : '原因:' + esc(p.reason || '暂不符合展示要求'), q.length ? '下一条' : '知道了', next);
|
||
})();
|
||
}
|
||
function showRs(kind, title, text, why, btn, cb) {
|
||
$('#rsb').innerHTML = '<div class="rsi ' + kind + '"><svg class="ic"><use href="#' + (kind === 'ok' ? 'i-check' : kind === 'no' ? 'i-x' : 'i-clock') + '"/></svg></div>' +
|
||
'<h3>' + title + '</h3><p class="rst">' + text + '</p>' + (why ? '<div class="rsw">' + why + '</div>' : '') + '<button type="button" class="rsk" id="rsk">' + btn + '</button>';
|
||
$('#rs').classList.add('show');
|
||
$('#rsk').onclick = function () { $('#rs').classList.remove('show'); if (cb) setTimeout(cb, 220); };
|
||
}
|
||
|
||
/* 写稿页 */
|
||
var DK = 'mmbox.gc.draft.v1', cpTopic = '', pics = [], ups = 0;
|
||
function draft(v) {
|
||
try {
|
||
var all = JSON.parse(localStorage.getItem(DK) || '{}') || {};
|
||
if (v === undefined) return all[UK] || {};
|
||
if (v) all[UK] = v; else delete all[UK];
|
||
localStorage.setItem(DK, JSON.stringify(all));
|
||
} catch (e) { return {}; }
|
||
}
|
||
function setCpTopic(id) {
|
||
cpTopic = TBY[id] ? id : '';
|
||
var t = TBY[cpTopic], b = $('#cpT');
|
||
b.className = 'cp-t' + (t ? ' k-' + t.cat : '');
|
||
b.innerHTML = (t ? kbHTML(t.cat) + '<span class="ct2"># ' + esc(t.name) + '</span>' : '<span class="ct2">选择要参与的话题</span>') +
|
||
'<span class="ch">' + (t ? '换话题' : '去选') + '<svg class="ic" style="width:13px;height:13px"><use href="#i-right"/></svg></span>';
|
||
saveDraft();
|
||
}
|
||
function cnt() {
|
||
var n = $('#cpBody').value.trim().length, c = $('#cpCnt');
|
||
c.className = 'cp-cnt' + (n >= 300 ? ' ok' : '');
|
||
c.innerHTML = '已写 <b>' + n + '</b> 字 · ' + (n < 50 ? '至少 50 字' : n < 300 ? '写到 300 字以上更容易被选中' : '很棒,继续写也可以');
|
||
}
|
||
function saveDraft() { draft({ t: cpTopic, a: $('#cpTitle').value, b: $('#cpBody').value }); }
|
||
function openCompose(tid) {
|
||
if (!OPENID) { toast('请从小程序里打开孕妈广场再投稿'); return; }
|
||
if (openId) closeNote();
|
||
var d = draft();
|
||
$('#cpTitle').value = d.a || ''; $('#cpBody').value = d.b || '';
|
||
setCpTopic(tid || d.t || '');
|
||
cnt();
|
||
$('#cp').classList.add('show'); $('#cp').setAttribute('aria-hidden', 'false');
|
||
}
|
||
function closeCompose() { saveDraft(); $('#cp').classList.remove('show'); $('#cp').setAttribute('aria-hidden', 'true'); document.activeElement && document.activeElement.blur(); }
|
||
$('#cpX').addEventListener('click', closeCompose);
|
||
$('#cpT').addEventListener('click', function () { pickFor = 'compose'; openTopics(); });
|
||
$('#cpTitle').addEventListener('input', saveDraft);
|
||
$('#cpBody').addEventListener('input', function () { cnt(); saveDraft(); });
|
||
function shrink(f) {
|
||
return new Promise(function (res) {
|
||
var u = URL.createObjectURL(f), im = new Image();
|
||
im.onload = function () {
|
||
var k = Math.min(1, 1600 / Math.max(im.width, im.height)), c = document.createElement('canvas');
|
||
c.width = Math.round(im.width * k); c.height = Math.round(im.height * k);
|
||
c.getContext('2d').drawImage(im, 0, 0, c.width, c.height); URL.revokeObjectURL(u);
|
||
c.toBlob(function (b) { res(b || f); }, 'image/jpeg', .85);
|
||
};
|
||
im.onerror = function () { URL.revokeObjectURL(u); res(f); };
|
||
im.src = u;
|
||
});
|
||
}
|
||
var syncAdd = function () { $('#cpAdd').classList.toggle('hide', pics.length >= 6); };
|
||
$('#cpFile').addEventListener('change', function () {
|
||
var f = this.files && this.files[0]; this.value = '';
|
||
if (!f || pics.length >= 6) return;
|
||
var it = { url: null, el: document.createElement('span') };
|
||
it.el.className = 'pt up';
|
||
it.el.innerHTML = '<img alt=""><button type="button" aria-label="删除这张">×</button>';
|
||
it.el.querySelector('img').src = URL.createObjectURL(f);
|
||
it.el.querySelector('button').onclick = function () { pics = pics.filter(function (x) { return x !== it; }); it.el.remove(); syncAdd(); };
|
||
$('#cpPics').insertBefore(it.el, $('#cpAdd')); pics.push(it); syncAdd(); ups++;
|
||
shrink(f).then(function (b) { var fd = new FormData(); fd.append('file', b, 'plaza.jpg'); return fetch('/api/upload', { method: 'POST', body: fd }); })
|
||
.then(function (r) { return r.json(); }).then(function (j) { it.url = j && j.result && j.result.url || null; if (!it.url) throw 0; it.el.classList.remove('up'); })
|
||
.catch(function () { toast('图片上传失败,可以删掉重新选'); it.el.classList.remove('up'); it.el.classList.add('bad'); })
|
||
.then(function () { ups--; });
|
||
});
|
||
$('#cpOk').addEventListener('click', function () {
|
||
var btn = this, title = $('#cpTitle').value.trim(), body = $('#cpBody').value.trim();
|
||
if (!cpTopic) { toast('先选一个要参与的话题'); return; }
|
||
if (title.length < 4) { toast('标题至少 4 个字'); return; }
|
||
if (body.length < 50) { toast('正文至少 50 个字,再多写一点吧'); return; }
|
||
if (ups > 0) { toast('图片还在上传,稍等一下'); return; }
|
||
btn.disabled = true; btn.textContent = '提交中';
|
||
getJ(API + '/post?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ topic: cpTopic, title: title, body: body, images: pics.map(function (x) { return x.url; }).filter(Boolean) }) })
|
||
.then(function (j) {
|
||
if (!j || j.code !== 200 || !j.result) { toast((j && j.message) || '提交失败,请稍后再试'); return; }
|
||
MINE.unshift(j.result);
|
||
draft(null); pics.forEach(function (x) { x.el.remove(); }); pics = []; syncAdd();
|
||
$('#cpTitle').value = ''; $('#cpBody').value = '';
|
||
closeCompose(); haptic();
|
||
showRs('wait', '已提交,正在审核中', '《<b>' + esc(title) + '</b>》已经交给编辑审核,<br>有结果会在这里提醒你。', '', '好的');
|
||
})
|
||
.catch(function () { toast('网络不太好,请稍后再试(草稿已保存)'); })
|
||
.then(function () { btn.disabled = false; btn.textContent = '提交'; });
|
||
});
|
||
|
||
/* ---------- 返回 ---------- */
|
||
function homeURL() {
|
||
var q = new URLSearchParams(location.search); q.delete('t'); q.delete('n'); q.delete('c');
|
||
var s = q.toString();
|
||
return '../' + (s ? '?' + s : '') + location.hash;
|
||
}
|
||
$('#back').addEventListener('click', function () {
|
||
var fromHome = false;
|
||
try { fromHome = !!document.referrer && new URL(document.referrer).origin === location.origin; } catch (e) {}
|
||
if (fromHome && history.length > 1) {
|
||
history.back();
|
||
/* 后退没生效(宿主新开的 web-view 没有站内历史)→ 直接回首页 */
|
||
setTimeout(function () { location.href = homeURL(); }, 500);
|
||
} else location.href = homeURL();
|
||
});
|
||
|
||
/* ---------- 吸顶阴影 ---------- */
|
||
var sc = $('#sc');
|
||
sc.addEventListener('scroll', function () { $('#top').classList.toggle('on', sc.scrollTop > 4); }, { passive: true });
|
||
|
||
/* ---------- 禁止下拉回弹(同首页那段):竖向拖动时从手指下往上找还能朝该方向滚的容器,找不到才拦 ---------- */
|
||
var sx = 0, sy = 0;
|
||
document.addEventListener('touchstart', function (e) {
|
||
if (e.touches.length !== 1) return;
|
||
sx = e.touches[0].clientX; sy = e.touches[0].clientY;
|
||
}, { passive: true });
|
||
document.addEventListener('touchmove', function (e) {
|
||
if (e.touches.length !== 1) { if (e.cancelable) e.preventDefault(); return; }
|
||
var dx = e.touches[0].clientX - sx, dy = e.touches[0].clientY - sy;
|
||
if (Math.abs(dy) <= Math.abs(dx)) return;
|
||
var el = e.target;
|
||
while (el && el !== document.body && el !== document.documentElement) {
|
||
if (el.nodeType === 1) {
|
||
var oy = getComputedStyle(el).overflowY;
|
||
if ((oy === 'auto' || oy === 'scroll') && el.scrollHeight > el.clientHeight + 1) {
|
||
if (dy > 0 && el.scrollTop > 0) return;
|
||
if (dy < 0 && el.scrollTop + el.clientHeight < el.scrollHeight - 1) return;
|
||
}
|
||
}
|
||
el = el.parentNode;
|
||
}
|
||
if (e.cancelable) e.preventDefault();
|
||
}, { passive: false });
|
||
|
||
/* ---------- 启动 ---------- */
|
||
var deep = new URLSearchParams(location.search).get('n'); /* 先读:selectTopic 会 replaceState 把 n 去掉 */
|
||
var c0 = new URLSearchParams(location.search).get('c');
|
||
if (CAT_ORDER.indexOf(c0) >= 0) catF = c0;
|
||
selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false);
|
||
if (deep && NBY[deep]) openNote(deep, false);
|
||
loadApproved();
|
||
if (new URLSearchParams(location.search).get('mine') === '1') {
|
||
loadMine(function () {
|
||
var un = MINE.filter(function (p) { return !p.seen && p.status !== 'pending'; });
|
||
if (un.length) showResults(un); else openMine();
|
||
});
|
||
} else loadMine();
|
||
var rt; window.addEventListener('resize', function () { clearTimeout(rt); rt = setTimeout(renderFeed, 150); });
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|