Files
mama-box/guangchang/index.html

681 lines
46 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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:8px;padding:4px 12px 10px}
.cats button{flex:1;min-width:0;height:42px;display:flex;align-items:center;justify-content:center;gap:6px;border-radius:14px;background:#fff;border:1.5px solid #F1E2DA;
font-size:15px;font-weight:800;color:#6E5A55;letter-spacing:.3px;box-shadow:0 2px 8px rgba(170,110,90,.06);transition:background .18s,color .18s,border-color .18s,box-shadow .18s}
.cats button .ci2{width:22px;height:22px;flex:none;display:grid;place-items:center;border-radius:8px;background:var(--cb);color:var(--cf)}
.cats button .ci2 .ic{width:14px;height:14px}
.cats button small{font-size:11px;font-weight:700;color:#B09A94;margin-left:-2px}
.cats button.on{background:var(--cf);border-color:var(--cf);color:#fff;box-shadow:0 6px 14px -6px var(--cf)}
.cats button.on .ci2{background:rgba(255,255,255,.22);color:#fff}
.cats button.on small{color:rgba(255,255,255,.8)}
.cats button:active{transform:scale(.97)}
.cats .c-all{--cf:#F4593C;--cb:#FFEDE6}
.cats .c-family{--cf:#E0566F;--cb:#FFE6EB}
.cats .c-exp{--cf:#2E8A7C;--cb:#DDF2EE}
.tabs{display:flex;gap:6px;padding:0 12px 10px;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.tabs::-webkit-scrollbar{display:none}
.tabs::after{content:"";flex:none;width:6px}
.tabs button{flex:none;height:30px;padding:0 13px;border-radius:99px;background:rgba(255,255,255,.75);border:1px solid #F0E2DA;font-size:13px;font-weight:600;color:#7A6663;white-space:nowrap;transition:background .15s,color .15s}
.tabs button.on{background:#2F2424;border-color:#2F2424;color:#fff;font-weight:800}
.tabs.k-family button.on{background:#FFE6EB;border-color:#F3A9B7;color:#C23A55}
.tabs.k-exp button.on{background:#DDF2EE;border-color:#93CFC4;color:#21705F}
.tabs.k-family button.on .hb,.tabs.k-exp button.on .hb{background:#FF5A3C}
.tabs button .hb{display:inline-block;margin-left:3px;padding:0 4px;border-radius:5px;background:#FF5A3C;color:#fff;font-size:9.5px;font-weight:800;line-height:15px;vertical-align:1px}
.tabs button.on .hb{background:#FF7A5C}
/* ---------- 话题头卡 ---------- */
.th{position:relative;margin:4px 12px 2px;padding:16px 16px 14px;border-radius:22px;overflow:hidden;
background:linear-gradient(150deg,var(--c1),var(--c2));color:var(--tk);box-shadow:0 12px 26px -16px var(--tk)}
.th .tg{position:absolute;right:-6px;top:-10px;font-size:110px;font-weight:900;line-height:1;color:#fff;opacity:.5;font-family:"STKaiti","KaiTi","Kaiti SC",serif;pointer-events:none}
.th .tc{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:7px;background:rgba(255,255,255,.65);font-size:11px;font-weight:800;letter-spacing:.5px}
.th .tc.k-family{background:#E0566F;color:#fff}
.th .tc.k-exp{background:#2E8A7C;color:#fff}
.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(--tk);margin-right:2px}
.th p{position:relative;margin:0;max-width:270px;font-size:12.5px;line-height:1.6;color:#5E4E4A}
.th .tf{position:relative;display:flex;align-items:center;gap:10px;margin-top:12px}
.th .ts{flex:1;display:flex;align-items:center;gap:7px;font-size:12px;color:#6E5C57}
.th .ts b{color:var(--tk);font-weight:900;font-variant-numeric:tabular-nums}
.th .avs{display:flex}
.th .avs img{width:20px;height:20px;border-radius:50%;object-fit:cover;border:1.5px solid rgba(255,255,255,.9);margin-left:-6px;background:#FFE3D3}
.th .avs img:first-child{margin-left:0}
.th .join{flex:none;height:32px;padding:0 14px;border-radius:99px;background:#fff;color:var(--tk);font-size:13px;font-weight:800;box-shadow:0 4px 10px rgba(0,0,0,.08);display:inline-flex;align-items:center;gap:4px}
.th .join .ic{width:14px;height:14px}
/* 未选具体话题时的一句引导 */
.intro{display:flex;align-items:center;gap:8px;margin:2px 14px 0;font-size:12px;color:var(--muted)}
.intro b{color:var(--ink);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 .ttag{position:absolute;left:7px;top:7px;z-index:2;height:18px;padding:0 6px;border-radius:6px;background:rgba(40,28,26,.38);color:#fff;font-size:10px;font-weight:700;line-height:18px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);max-width:82%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nc .ttag.k-family{background:rgba(214,74,100,.82)}
.nc .ttag.k-exp{background:rgba(38,128,114,.82)}
.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,详情放大) ---------- */
.cv{position:relative;width:100%;overflow:hidden;font-size:13px;color:var(--tk);isolation:isolate}
.cv .t1{position:relative;z-index:1;font-weight:900;line-height:1.25;letter-spacing:.04em;word-break:break-all}
.cv .t2{position:relative;z-index:1;font-weight:700;opacity:.82;line-height:1.4}
.cv i{font-style:normal}
/* s0 渐变 + 荧光笔 */
.cv.s0{background:linear-gradient(160deg,var(--c1),var(--c2));display:flex;flex-direction:column;justify-content:center;padding:0 1.2em}
.cv.s0 .t1{font-size:1.75em;color:#2A1E1E}
.cv.s0 .t1 span{background:linear-gradient(transparent 58%,rgba(255,255,255,.85) 58%,rgba(255,255,255,.85) 90%,transparent 90%)}
.cv.s0 .t2{margin-top:.7em;font-size:.95em}
.cv.s0 .dc{position:absolute;right:-1.6em;top:-1.6em;width:6em;height:6em;border-radius:50%;background:rgba(255,255,255,.35)}
.cv.s0 .dc2{position:absolute;left:1.2em;bottom:1.1em;width:2.4em;height:.32em;border-radius:1em;background:var(--tk);opacity:.5}
/* s1 便签纸 + 胶带 */
.cv.s1{background:radial-gradient(circle,rgba(255,255,255,.55) 1.2px,transparent 1.6px) 0 0/14px 14px,var(--c2);display:grid;place-items:center;padding:1.3em 1em}
.cv.s1 .pp{position:relative;width:100%;padding:1.3em .9em 1em;background:#FFFDF8;border-radius:.3em;box-shadow:0 .5em 1em -.4em rgba(80,40,30,.35);transform:rotate(-2.5deg)}
.cv.s1 .pp::before{content:"";position:absolute;left:50%;top:-.6em;width:4em;height:1.2em;margin-left:-2em;background:rgba(255,255,255,.65);border:1px solid rgba(0,0,0,.04);transform:rotate(3deg)}
.cv.s1 .t1{font-size:1.45em;color:#3A2C28}
.cv.s1 .t2{margin-top:.5em;font-size:.88em;color:var(--tk)}
/* s2 深色大引号 */
.cv.s2{background:radial-gradient(9em 7em at 100% 0,rgba(255,255,255,.18),transparent 70%),linear-gradient(160deg,var(--tk),#2E2230);color:#FFF4EA;display:flex;flex-direction:column;justify-content:flex-end;padding:1.1em 1.1em 1.2em}
.cv.s2 .q{position:absolute;right:.45em;top:-.15em;font-size:5.5em;font-weight:900;line-height:1;color:var(--c2);opacity:.75;font-family:Georgia,serif}
.cv.s2 .t1{font-size:1.6em}
.cv.s2 .t2{margin-top:.55em;font-size:.9em;color:var(--c2);opacity:1}
/* s3 横线本 */
.cv.s3{background:repeating-linear-gradient(180deg,transparent 0,transparent 1.75em,rgba(170,140,120,.22) 1.75em,rgba(170,140,120,.22) calc(1.75em + 1px)),#FFFCF6;padding:1.2em 1em 1em 1.9em;display:flex;flex-direction:column;justify-content:center}
.cv.s3::before{content:"";position:absolute;left:1.15em;top:0;bottom:0;width:1.5px;background:rgba(240,110,100,.45)}
.cv.s3 .t1{font-size:1.5em;color:#2F2424}
.cv.s3 .t1 span{background:linear-gradient(transparent 55%,var(--c2) 55%,var(--c2) 92%,transparent 92%)}
.cv.s3 .t2{margin-top:.7em;font-size:.9em;color:var(--tk)}
.cv.s3 .ck{display:flex;gap:.35em;margin-top:.8em}
.cv.s3 .ck i{width:.95em;height:.95em;border-radius:.25em;border:1.5px solid var(--tk);opacity:.6}
.cv.s3 .ck i:first-child{background:var(--tk)}
/* s4 大圆 + 水印字 */
.cv.s4{background:var(--c1);display:flex;flex-direction:column;justify-content:flex-end;padding:1em 1.1em 1.1em}
.cv.s4 .bc{position:absolute;right:-1.4em;top:-1.2em;width:8.4em;height:8.4em;border-radius:50%;background:linear-gradient(150deg,var(--c2),rgba(255,255,255,.4));display:grid;place-items:center}
.cv.s4 .bc b{font-size:4em;font-weight:900;color:#fff;opacity:.8;font-family:"STKaiti","KaiTi","Kaiti SC",serif;transform:translate(-.08em,.06em)}
.cv.s4 .t1{font-size:1.6em;color:#2A1E1E}
.cv.s4 .t2{margin-top:.45em;font-size:.9em}
/* s5 方格纸 + 印章 */
.cv.s5{background:linear-gradient(rgba(170,140,120,.13) 1px,transparent 1px) 0 0/1.2em 1.2em,linear-gradient(90deg,rgba(170,140,120,.13) 1px,transparent 1px) 0 0/1.2em 1.2em,#FFF9F3;display:flex;flex-direction:column;justify-content:center;padding:1em 1.1em}
.cv.s5 .st{align-self:flex-start;margin-bottom:.7em;padding:.2em .6em;border-radius:.4em;background:var(--tk);color:#fff;font-size:.8em;font-weight:800;letter-spacing:.08em;transform:rotate(-3deg)}
.cv.s5 .t1{font-size:1.55em;color:#2F2424}
.cv.s5 .t2{margin-top:.55em;font-size:.88em}
.cv.s5 .sm{position:absolute;right:.8em;bottom:.8em;width:3.2em;height:3.2em;border-radius:50%;border:2px solid var(--tk);color:var(--tk);display:grid;place-items:center;font-size:.8em;font-weight:900;opacity:.55;transform:rotate(-14deg)}
/* ---------- 详情层 ---------- */
#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:26px}
.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 .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}
.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}
.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-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>
<span class="sp"></span>
</div>
<div class="cats" id="cats" role="tablist" aria-label="分类"></div>
<div class="tabs" id="tabs" role="tablist"></div>
</div>
<div id="head"></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 class="toast" id="toast"></div>
<script src="topics.js?v=26110112"></script>
<script src="data.js?v=26110112"></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 { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[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'; };
/* ---------- 笔记:data.js 的原始内容 + 确定性补字段(id / 封面样式 / 比例 / 评论) ---------- */
var NOTES = [], NBY = {};
var RATIO = [1.25, 0.96, 1.16, 0.84, 1.32, 1.06, 0.92];
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 || '',
style: (ti * 2 + i * 5) % 6, ratio: RATIO[(ti + i * 3) % RATIO.length],
/* 封面配色:三条里一条用本话题色,另两条借别的话题色,同一话题页里不至于一片同色 */
pal: i % 3 === 0 ? t : T[(ti + 3 + i * 4) % T.length]
};
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) {
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); }
/* ---------- 封面 ---------- */
function coverHTML(n, h) {
var t = TBY[n.t], pl = n.pal || t, st = 'style="--c1:' + pl.c[0] + ';--c2:' + pl.c[1] + ';--tk:' + pl.ink + ';' + (h ? 'height:' + h : '') + '"';
var t1 = esc(n.cover), t2 = esc(n.coverSub), inner;
switch (n.style) {
case 0: inner = '<i class="dc"></i><i class="dc2"></i><div class="t1"><span>' + t1 + '</span></div><div class="t2">' + t2 + '</div>'; break;
case 1: inner = '<div class="pp"><div class="t1">' + t1 + '</div><div class="t2">' + t2 + '</div></div>'; break;
case 2: inner = '<i class="q">“</i><div class="t1">' + t1 + '</div><div class="t2">' + t2 + '</div>'; break;
case 3: inner = '<div class="t1"><span>' + t1 + '</span></div><div class="t2">' + t2 + '</div><div class="ck"><i></i><i></i><i></i></div>'; break;
case 4: inner = '<i class="bc"><b>' + esc(t.g) + '</b></i><div class="t1">' + t1 + '</div><div class="t2">' + t2 + '</div>'; break;
default: inner = '<span class="st">' + (t.cat === 'family' ? '家有暖事' : '过来人经验') + '</span><div class="t1">' + t1 + '</div><div class="t2">' + t2 + '</div><i class="sm">' + esc(t.g) + '</i>';
}
return '<div class="cv s' + n.style + '" ' + st + '>' + inner + '</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) {
return '<button type="button" class="nc" data-id="' + n.id + '"><div class="cvw">' +
(showTopic ? '<span class="ttag k-' + TBY[n.t].cat + '"># ' + esc(TBY[n.t].name) + '</span>' : '') +
coverHTML(n, 'calc(var(--cw) * ' + n.ratio + ')') + '</div>' +
'<div class="nb"><h3>' + esc(n.title) + '</h3><div class="nf"><img src="' + avSrc(n.author) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>';
}
/* ---------- 列表 ---------- */
/* cur 当前话题('' = 不限话题);catF 一级分类('' 全部 / family 家庭关系 / exp 宝妈经验)。选了话题时 catF 恒等于该话题的 cat */
var cur = '', catF = '';
var CATS = [['', '全部', 'i-grid'], ['family', '家庭关系', 'i-home'], ['exp', '宝妈经验', 'i-bulb']];
var CAT_NAME = { family: '家庭关系', exp: '宝妈经验' };
var inCat = function (t) { return !catF || t.cat === catF; };
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]) + '">' +
'<span class="ci2"><svg class="ic"><use href="#' + x[2] + '"/></svg></span>' + x[1] + '</button>';
}).join('');
}
function renderTabs() {
$('#tabs').className = 'tabs' + (catF ? ' k-' + catF : '');
var h = '<button type="button" data-t="" class="' + (cur ? '' : 'on') + '">' + (catF ? '全部' + CAT_NAME[catF] : '全部话题') + '</button>' + T.filter(inCat).map(function (t) {
return '<button type="button" data-t="' + t.id + '" class="' + (cur === t.id ? 'on' : '') + '">' + esc(t.name) + (t.hot ? '<i class="hb">热</i>' : '') + '</button>';
}).join('');
$('#tabs').innerHTML = h;
}
function renderHead() {
var t = TBY[cur], el = $('#head');
if (!t) {
var tip = catF === 'family' ? '老公、婆婆、爸妈,家里那些暖事和糟心事' : catF === 'exp' ? '过来人的干货,少走弯路' : '都是孕妈们的真心话';
el.innerHTML = '<div class="intro"><span><b>' + T.filter(inCat).length + '</b> 个话题 · ' + tip + '</span></div>';
return;
}
var d = D[t.id] || {};
var avs = [0, 1, 2, 3].map(function (k) { return '<img src="' + avSrc(t.id + k) + '" alt="">'; }).join('');
el.innerHTML = '<div class="th" style="--c1:' + t.c[0] + ';--c2:' + t.c[1] + ';--tk:' + t.ink + '"><span class="tg" aria-hidden="true">' + esc(t.g) + '</span>' +
'<span class="tc k-' + t.cat + '">' + (t.cat === 'family' ? '家庭关系' : '宝妈经验') + (t.hot ? ' · 热门' : '') + '</span>' +
'<h2><em>#</em>' + esc(t.name) + '</h2><p>' + esc(d.desc || '') + '</p>' +
'<div class="tf"><span class="ts"><span class="avs">' + avs + '</span><span><b>' + kfmt(t.n) + '</b> 篇笔记 · <b>' + kfmt(t.talk) + '</b> 人在聊</span></span>' +
'<button type="button" class="join" id="join"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button></div></div>';
}
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');
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(); renderTabs(); renderHead(); renderFeed();
history.replaceState(history.state, '', setQuery(cur, ''));
var on = $('#tabs .on');
if (on) { var tb = $('#tabs'); tb.scrollLeft = Math.max(0, on.offsetLeft - tb.clientWidth / 2 + on.offsetWidth / 2); }
var sc = $('#sc'); if (smooth !== false) sc.scrollTop = 0;
}
$('#tabs').addEventListener('click', function (e) {
var b = e.target.closest('button[data-t]');
if (b && b.dataset.t !== cur) { haptic(); selectTopic(b.dataset.t); }
});
$('#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) {
if (e.target.closest('#join')) toast('发布笔记马上开放,先去看看大家怎么说吧');
});
/* 卡片:点心形就地点赞,点别处进详情 */
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 = avSrc(n.author);
$('#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 * Math.min(n.ratio, 1.05));
var day = 26 + (seed(n.id) % 6), mon = day > 31 ? 11 : 10;
$('#dsc').innerHTML = '<div class="dcv">' + coverHTML(n, h + 'px') + '</div>' +
'<div class="dbody"><h2>' + esc(n.title) + '</h2><div class="tx">' + bodyHTML(n.body) + '</div>' +
'<div class="tgs"><button type="button" data-go="' + t.id + '"># ' + esc(t.name) + '</button><button type="button" data-go="">#孕妈广场</button></div>' +
'<div class="tm">' + mon + '-' + (day > 31 ? day - 31 : day) + ' · ' + esc(n.stage || '') + '</div></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 () {
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 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('评论已发出');
}
/* ---------- 返回 ---------- */
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 (c0 === 'family' || c0 === 'exp') catF = c0;
selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false);
if (deep && NBY[deep]) openNote(deep, false);
var rt; window.addEventListener('resize', function () { clearTimeout(rt); rt = setTimeout(renderFeed, 150); });
})();
</script>
</body>
</html>