1712 lines
139 KiB
HTML
1712 lines
139 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-02 第四版:用户「去掉图标、滑块缺设计感」→ 小红书式文字标签:选中字放大加粗 + 底下一条会滑动的分类色胶囊;左右滑页面也能切) ---------- */
|
||
.cats{position:relative;display:flex;gap:8px;margin:0 6px;padding:2px 0 10px}
|
||
.cats button{position:relative;z-index:1;flex:none;padding:6px 12px 4px;font-size:15.5px;font-weight:700;color:#A08B85;letter-spacing:.3px;line-height:24px;transition:color .25s}
|
||
.cats button .ic{display:none}
|
||
.cats button.on{font-size:18px;font-weight:900;color:#2A1E1E}
|
||
.cats button i{position:absolute;left:calc(100% - 12px);top:2px;font-style:normal;font-size:10px;font-weight:800;line-height:12px;color:var(--cf);opacity:0;transition:opacity .25s}
|
||
.cats button.on i{opacity:1}
|
||
.cats .bar{display:block;padding:0;border:0;gap:0;/* 11-03:别吃到详情底栏通用 .bar 的内边距(色块被撑到 17px) */position:absolute;z-index:0;left:0;bottom:12px;height:7px;width:28px;border-radius:7px;background:var(--cbar,#F4593C);opacity:.32;
|
||
transition:transform .32s cubic-bezier(.3,1.3,.5,1),width .32s cubic-bezier(.3,1.3,.5,1),background .25s;pointer-events:none}
|
||
.cats::after{content:"";position:absolute;left:6px;right:6px;bottom:0;height:1px;background:linear-gradient(90deg,transparent,#EADAD3 20%,#EADAD3 80%,transparent)}
|
||
.cats button:active{transform:scale(.96)}
|
||
.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)}
|
||
|
||
/* ---------- 祈福树 banner(11-02):夜空 + 摇摆的树 + 飘福牌 ---------- */
|
||
.qf{position:relative;display:block;width:calc(100% - 24px);height:148px;margin:2px 12px 0;border-radius:20px;overflow:hidden;text-align:left;
|
||
background:radial-gradient(120% 140% at 82% 100%,#3B3A86 0%,#252A63 38%,#161B3F 75%);box-shadow:0 12px 26px -14px rgba(30,30,90,.7)}
|
||
.qf:active{transform:scale(.985)}
|
||
.qf-st{position:absolute;inset:0;pointer-events:none;opacity:.9;
|
||
background-image:radial-gradient(1.4px 1.4px at 12% 20%,#fff,transparent),radial-gradient(1px 1px at 28% 70%,#fff,transparent),radial-gradient(1.2px 1.2px at 46% 14%,#FFE9B0,transparent),
|
||
radial-gradient(1px 1px at 54% 82%,#fff,transparent),radial-gradient(1.5px 1.5px at 62% 30%,#fff,transparent),radial-gradient(1px 1px at 8% 88%,#FFE9B0,transparent),radial-gradient(1.2px 1.2px at 40% 46%,#fff,transparent);
|
||
animation:qfTw 3.2s ease-in-out infinite alternate}
|
||
.qf-st::after{content:"";position:absolute;inset:0;background-image:radial-gradient(1.3px 1.3px at 20% 40%,#fff,transparent),radial-gradient(1px 1px at 35% 26%,#FFE9B0,transparent),radial-gradient(1.4px 1.4px at 50% 60%,#fff,transparent),radial-gradient(1px 1px at 16% 62%,#fff,transparent);
|
||
animation:qfTw 2.4s ease-in-out infinite alternate-reverse}
|
||
@keyframes qfTw{from{opacity:.35}to{opacity:1}}
|
||
.qf-glow{position:absolute;right:-6px;bottom:-30px;width:190px;height:190px;border-radius:50%;pointer-events:none;
|
||
background:radial-gradient(circle,rgba(255,206,110,.55) 0%,rgba(255,170,80,.22) 40%,transparent 70%);animation:qfGl 3.6s ease-in-out infinite}
|
||
@keyframes qfGl{0%,100%{opacity:.7;transform:scale(.94)}50%{opacity:1;transform:scale(1.06)}}
|
||
.qf-tree{position:absolute;right:-4px;bottom:-4px;height:150px;width:auto;transform-origin:52% 100%;animation:qfSw 5.5s ease-in-out infinite;filter:drop-shadow(0 6px 12px rgba(0,0,0,.35))}
|
||
@keyframes qfSw{0%,100%{transform:rotate(-1.6deg)}50%{transform:rotate(1.6deg)}}
|
||
.qf-fly{position:absolute;right:22px;bottom:60px;width:110px;height:100px;pointer-events:none}
|
||
.qf-fly i{position:absolute;bottom:0;width:15px;height:20px;border-radius:3px;background:linear-gradient(#E8343F,#B8141F);color:#FFD98A;font-style:normal;font-size:10px;font-weight:900;line-height:20px;text-align:center;
|
||
font-family:"STKaiti","KaiTi","Kaiti SC",serif;box-shadow:0 0 8px rgba(255,190,90,.6);opacity:0;animation:qfUp 4.8s ease-in infinite}
|
||
.qf-fly i::before{content:"";position:absolute;left:50%;top:-5px;width:1px;height:5px;background:#FFD98A}
|
||
.qf-fly i:nth-child(1){left:6px;animation-delay:0s}.qf-fly i:nth-child(2){left:44px;animation-delay:1.2s}
|
||
.qf-fly i:nth-child(3){left:82px;animation-delay:2.4s}.qf-fly i:nth-child(4){left:26px;animation-delay:3.6s}
|
||
@keyframes qfUp{0%{opacity:0;transform:translateY(10px) rotate(-8deg) scale(.7)}15%{opacity:1}70%{opacity:.9}100%{opacity:0;transform:translateY(-88px) rotate(10deg) scale(1)}}
|
||
.qf-tx{position:relative;z-index:2;display:flex;flex-direction:column;align-items:flex-start;height:100%;padding:16px 0 14px 16px;color:#fff}
|
||
.qf-tx small{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 9px 0 7px;border-radius:99px;background:rgba(255,255,255,.12);font-size:11px;font-weight:700;color:#FFE3A6;letter-spacing:.5px}
|
||
.qf-tx small i{width:6px;height:6px;border-radius:50%;background:#FFC85C;box-shadow:0 0 6px #FFC85C;animation:qfGl 1.8s ease-in-out infinite}
|
||
.qf-tx b{margin-top:9px;font-size:19px;font-weight:900;letter-spacing:.5px;line-height:1.2;font-family:"STKaiti","KaiTi","Kaiti SC","STSong",serif;
|
||
background:linear-gradient(180deg,#FFF3D2,#FFC86A);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 0 18px rgba(255,200,110,.25)}
|
||
.qf-tx b i{font-style:normal;margin:0 1px;font-family:-apple-system,"PingFang SC",sans-serif;font-weight:900}
|
||
.qf-tx em{margin-top:5px;font-style:normal;font-size:11px;color:rgba(255,236,200,.75);letter-spacing:.5px}
|
||
.qf-go{position:relative;overflow:hidden;margin-top:auto;display:inline-flex;align-items:center;gap:2px;height:30px;padding:0 10px 0 14px;border-radius:99px;
|
||
background:linear-gradient(135deg,#FFE29A,#F6B544);color:#7A3A0C;font-size:13px;font-weight:900;box-shadow:0 6px 14px -6px rgba(255,190,80,.9)}
|
||
.qf-go .ic{width:13px;height:13px}
|
||
.qf-go::after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:40%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.7),transparent);transform:skewX(-18deg);animation:qfSh 2.8s ease-in-out infinite}
|
||
@keyframes qfSh{0%,55%{left:-60%}100%{left:130%}}
|
||
@media (prefers-reduced-motion:reduce){.qf *,.qf *::before,.qf *::after{animation:none!important}.qf-fly{display:none}}
|
||
/* 投稿奖励:热门话题列表头一行 */
|
||
.htl .rwl{display:flex;align-items:center;gap:6px;width:100%;margin:6px 0 2px;padding:8px 10px;border-radius:12px;background:linear-gradient(100deg,#FFF1E8,#FFE6E6);text-align:left;font-size:12px;font-weight:700;color:#8A4B36}
|
||
.htl .rwl .ic{flex:none;width:16px;height:16px;color:#F2553A}
|
||
.htl .rwl span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.htl .rwl em{font-style:normal;color:#F2394A;font-weight:900}
|
||
.htl .rwl b{flex:none;font-size:11.5px;color:#F2553A}
|
||
|
||
/* ---------- 投稿有奖横幅 ---------- */
|
||
.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}
|
||
/* 11-02 v2 测一测:广场第 5 个分类「测一测」(经验后面)+「大家在聊」信息流里穿插测试卡。卡片插画 ceshi/img/<id>_s.webp */
|
||
.cats .c-ceshi{--cf:#7C5CFC;align-self:center;display:inline-flex;align-items:center;gap:3px;margin-left:9px;height:30px;padding:0 12px 0 9px;border-radius:99px;font-size:14px;font-weight:800;color:#7C5CFC;
|
||
background:linear-gradient(120deg,#F1ECFF,#FFE8F1);box-shadow:inset 0 0 0 1px rgba(124,92,252,.18);line-height:30px}
|
||
.cats .c-ceshi::before{content:"";position:absolute;left:-9px;top:7px;bottom:7px;width:1px;background:#E6D7D0}
|
||
.cats .c-ceshi .ic{display:block;width:13px;height:13px;flex:none}
|
||
.cats .c-ceshi i{display:none}
|
||
.cats .c-ceshi.on{font-size:14px;font-weight:900;color:#fff;background:linear-gradient(120deg,#8E6BFF,#EE6A9C);box-shadow:0 6px 14px -6px rgba(200,90,180,.7)}
|
||
/* 测一测列表(11-02 v3 用户:「列表别跟帖子一个样,换个形式」)→ 分组专栏:组头 + 推荐横卡 + 条目行 */
|
||
.csl{padding:0 12px}
|
||
.csg{margin-top:18px}
|
||
.csg-h{display:flex;align-items:baseline;gap:8px;padding:0 4px}
|
||
.csg-h b{position:relative;font-size:17px;font-weight:900;color:#2A1E1E}
|
||
.csg-h b::after{content:"";position:absolute;left:-2px;right:-2px;bottom:1px;height:7px;border-radius:4px;background:var(--tg);opacity:.22;z-index:-1}
|
||
.csg-h b{z-index:0}
|
||
.csg-h small{font-size:12px;color:#A08B85}
|
||
.csg-h em{margin-left:auto;font-style:normal;font-size:12px;font-weight:800;color:var(--tg)}
|
||
/* 11-02 v4 用户:「测一测页面太乱,整洁一些,多少人测过要明显」→ 所有分组统一一种列表行:缩略图 + 标题/说明 + 右侧大号人数 */
|
||
.cpl{margin-top:8px;border-radius:20px;background:#fff;box-shadow:0 3px 12px rgba(170,110,90,.07);overflow:hidden}
|
||
.cr{display:flex;align-items:center;gap:12px;width:100%;padding:12px;text-align:left;border-top:1px solid #F7EFEB}
|
||
.cr:first-child{border-top:0}
|
||
.cr:active{background:#FCF8F6}
|
||
.cr .cth{position:relative;flex:none;width:58px;height:58px}
|
||
.cr .cth img{display:block;width:100%;height:100%;border-radius:14px;object-fit:cover;object-position:center 28%;background:var(--tl)}
|
||
.cr .crk{position:absolute;left:-5px;top:-5px;min-width:20px;height:20px;padding:0 5px;border-radius:7px;background:#B9A7A1;color:#fff;font-size:11.5px;font-weight:900;line-height:20px;text-align:center;border:2px solid #fff;font-style:normal}
|
||
.cr .crk.r1{background:#F0453A}.cr .crk.r2{background:#F28A1E}.cr .crk.r3{background:#F2B21E}
|
||
.cr .tx{flex:1;min-width:0}
|
||
.cr b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:14.5px;font-weight:800;line-height:1.4;color:#2A1E1E}
|
||
.cr small{display:block;margin-top:3px;font-size:12px;color:#A99590;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
|
||
.cr small em{font-style:normal;font-weight:800;color:var(--tg)}
|
||
.cr .cn{flex:none;min-width:66px;padding:7px 8px 6px;border-radius:14px;background:linear-gradient(160deg,#FFF3EE,#FFE4DA);text-align:center} /* 11-02 用户:「N万人测过」要更明显 */
|
||
.cr .cn b{display:flex;align-items:baseline;justify-content:center;font-size:22px;font-weight:900;line-height:1.05;color:#EE4B2B;font-family:-apple-system,"DIN Alternate","Helvetica Neue",sans-serif;letter-spacing:-.5px}
|
||
.cr .cn b i{font-size:12.5px;font-style:normal;font-weight:900;margin-left:1px}
|
||
.cr .cn small{display:flex;align-items:center;justify-content:center;gap:2px;margin-top:3px;font-size:11px;font-weight:800;color:#F0704F}
|
||
.cr .cn small svg{width:11px;height:11px}
|
||
.cr .cn.dn b{font-size:13px;color:var(--tg)}
|
||
.ckm{display:block;width:100%;height:42px;border-top:1px solid #F7EFEB;color:#8A7470;font-size:12.5px;font-weight:800;background:#fff}
|
||
.k-ceshi{--kf:#7C5CFC;--kt:#6346B0;--kl:#F1EDFF;--kl2:#E4DDFD}
|
||
.g-quiz{--tg:#F0714F;--tl:#FFEFE9}.g-psy{--tg:#7C5CFC;--tl:#F1EDFF}.g-game{--tg:#13A08A;--tl:#E4F6F1}.g-shop{--tg:#E9557F;--tl:#FFEEF3}
|
||
.nc.tst .cvw{background:var(--tl)}
|
||
.nc.tst .cvw img{display:block;width:100%;height:calc(var(--cw) * 1.08);object-fit:cover;object-position:center 30%}
|
||
.nc.tst .tb{position:absolute;left:7px;top:7px;display:inline-flex;align-items:center;gap:3px;height:21px;padding:0 8px 0 6px;border-radius:7px;background:var(--tg);color:#fff;font-size:11px;font-weight:800;letter-spacing:.5px;box-shadow:0 3px 8px -3px var(--tg)}
|
||
.nc.tst .tb .ic{width:12px;height:12px;stroke-width:2.2}
|
||
.nc.tst .tq{position:absolute;left:0;right:0;bottom:0;padding:22px 9px 7px;background:linear-gradient(transparent,rgba(30,20,40,.42));color:#fff;font-size:11.5px;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.25)}
|
||
.nc.tst .nf{justify-content:space-between}
|
||
.nc.tst .gs{font-size:11px;font-weight:700;color:var(--tg)}
|
||
.nc.tst .gs.dn{max-width:96px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nc.tst .gt{flex:none;height:22px;padding:0 9px;border-radius:99px;background:var(--tl);color:var(--tg);font-size:11.5px;font-weight:800;line-height:22px}
|
||
.csh{display:flex;align-items:center;gap:6px;margin:2px 12px 0;padding:11px 14px;border-radius:16px;background:linear-gradient(120deg,#F1EDFF,#FFEFF4 70%,#FFF3EA)}
|
||
.csh .ic{width:16px;height:16px;color:#8E6BFF;stroke-width:2.2}
|
||
.csh b{font-size:15px;font-weight:900;color:#2A1E1E}
|
||
.csh span{margin-left:auto;font-size:12px;font-weight:700;color:#C0507A}
|
||
.htl{margin:0 12px;padding:4px 12px 2px;border-radius:18px;background:#fff;box-shadow:0 6px 18px -12px rgba(120,60,40,.25)}
|
||
.htl .hr{display:flex;align-items:center;gap:10px;padding:11px 0;border-bottom:1px dashed #F0E2DC;--hk:var(--kf)}
|
||
.htl .hr:last-of-type{border-bottom:0}
|
||
.htl .no{flex:none;width:20px;text-align:center;font-style:italic;font-size:16px;font-weight:900;color:#C9B3AC}
|
||
.htl .no.t0{color:#F2465A}.htl .no.t1{color:#FF6A3D}.htl .no.t2{color:#FF9A2E}
|
||
.htl .hm{flex:1;min-width:0}
|
||
.htl .hm b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:14.5px;font-weight:900;line-height:1.4;color:#2A1E1E}
|
||
.htl .hm em{font-style:normal;color:var(--hk);margin:0 1px}
|
||
.htl .hm small{display:block;margin-top:2px;font-size:11.5px;color:#A8918B;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.htl .hm u{text-decoration:none;color:var(--hk);font-weight:700;margin-right:6px}
|
||
.htl .rk{flex:none;height:17px;padding:0 5px;border-radius:5px;background:#FF5A3C;color:#fff;font-size:10.5px;font-weight:800;line-height:17px}
|
||
.htl .jn{flex:none;height:26px;padding:0 11px;border-radius:99px;border:1px solid var(--hk);color:var(--hk);background:#fff;font-size:12px;font-weight:800}
|
||
.htl .hall{display:block;width:100%;padding:10px 0 9px;border-top:1px solid #F5EAE6;font-size:12.5px;font-weight:700;color:#9A817C}
|
||
.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}
|
||
|
||
/* ---------- 层级:分类 · 话题胶囊(11-02) ---------- */
|
||
.lvw{margin:16px 0 0}
|
||
.lvw .lv{display:flex;align-items:baseline;gap:8px;padding:0 14px}
|
||
.lvw .lv h2{margin:0;font-size:17px;font-weight:900;letter-spacing:.3px;color:var(--kt)}
|
||
.lvw .lv small{font-size:12px;font-weight:600;color:var(--muted);white-space:nowrap}
|
||
.lvw .lv .ba{margin-left:auto;font-size:12.5px;font-weight:800;color:var(--kt)}
|
||
.tcs{display:flex;gap:7px;padding:9px 12px 2px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none}
|
||
.tcs::-webkit-scrollbar{display:none}
|
||
.tcs::after{content:"";flex:none;width:4px}
|
||
.tcs button{flex:none;height:30px;padding:0 11px;border-radius:99px;background:#fff;border:1px solid #EFE1DB;font-size:12.5px;font-weight:700;color:#5E4E4A;white-space:nowrap;display:inline-flex;align-items:center;gap:5px}
|
||
.tcs button i{font-style:normal;font-size:11px;font-weight:800;color:#B59A93;font-variant-numeric:tabular-nums}
|
||
.tcs button.on{background:var(--kf);border-color:var(--kf);color:#fff;box-shadow:0 5px 12px -6px var(--kf)}
|
||
.tcs button.on i{color:rgba(255,255,255,.85)}
|
||
.th .bc{position:relative;display:flex;align-items:center;gap:6px}
|
||
.th .bc button{display:inline-flex}
|
||
.th .bc span:last-child{font-size:12px;font-weight:700;color:var(--ht)}
|
||
.th .bc .kb{height:auto;padding:0;border-radius:0;background:none;box-shadow:none;color:var(--ht);font-size:12.5px;letter-spacing:.3px} /* 11-03 用户:话题卡左上角分类不要底色块 */
|
||
|
||
.mo{display:block;width:calc(100% - 24px);margin:14px 12px 0;padding:13px 14px;border-radius:16px;text-align:center;background:linear-gradient(150deg,var(--kl),var(--kl2))}
|
||
.mo small{display:block;font-size:11.5px;font-weight:600;color:#9A817C}
|
||
.mo b{display:block;margin-top:3px;font-size:14.5px;font-weight:900;color:var(--kt)}
|
||
/* ---------- 瀑布流 ---------- */
|
||
.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)}
|
||
/* 我的投稿入口卡(11-02 从右上角挪到「全部」瀑布流第一位,点进 mine/ 独立页) */
|
||
.nc.fvc{display:flex;align-items:center;gap:8px;padding:11px 12px;border-radius:14px;background:#fff;color:var(--ink);font-size:13.5px;font-weight:900;text-align:left;box-shadow:0 4px 14px rgba(170,110,90,.08)}
|
||
.fvc .fi{width:30px;height:30px;flex:none;border-radius:10px;display:grid;place-items:center;background:#FFF4D6;color:#F2A20C}
|
||
.fvc .fi .ic{width:17px;height:17px;fill:currentColor;stroke:none}
|
||
.fvc span{flex:1;min-width:0}.fvc small{display:block;font-size:11px;font-weight:600;color:var(--muted)}
|
||
.fvc>.ic{width:14px;height:14px;color:#C9B6B0}
|
||
/* 我的收藏(11-02 用户:收藏了要有地方找 → 首页「我的」页入口 → ?fav=1 打开这一层;广场「全部」里我的投稿卡下面也有入口) */
|
||
#fvp{position:fixed;inset:0;z-index:35;background:var(--bg);transform:translateX(100%);transition:transform .32s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column}
|
||
#fvp.show{transform:none}
|
||
#fvp .nav{flex:none;padding-top:env(safe-area-inset-top);height:calc(46px + env(safe-area-inset-top))}
|
||
#fvs{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:none;padding-bottom:calc(30px + env(safe-area-inset-bottom))}
|
||
#fvs .fvh{margin:4px 14px 0;font-size:12.5px;color:var(--muted)}
|
||
#fvs .fve{margin:40px 24px;text-align:center;color:var(--muted);font-size:13px;line-height:1.7}
|
||
#fvs .fve b{display:block;margin-bottom:4px;font-size:16px;color:var(--ink)}
|
||
.nc.myc{position:relative;padding:14px 12px 12px;color:#fff;background:linear-gradient(150deg,#FF8A65,#F0607E 70%,#D8609E);box-shadow:0 10px 20px -14px #E8506E}
|
||
.nc.myc::after{content:"";position:absolute;right:-26px;top:-30px;width:96px;height:96px;border-radius:50%;background:rgba(255,255,255,.15)}
|
||
.myc .mi{position:relative;width:38px;height:38px;border-radius:12px;display:grid;place-items:center;background:rgba(255,255,255,.22)}
|
||
.myc .mi .ic{width:20px;height:20px}
|
||
.myc b{position:relative;display:block;margin-top:10px;font-size:16px;font-weight:900}
|
||
.myc p{position:relative;margin:2px 0 0;font-size:11.5px;line-height:1.5;opacity:.92}
|
||
.myc p em{font-style:normal;font-weight:900;color:#FFF1B8}
|
||
.myc .ms{position:relative;display:flex;gap:4px;flex-wrap:wrap;margin-top:9px}
|
||
.myc .ms span{height:20px;padding:0 7px;border-radius:6px;background:rgba(255,255,255,.95);color:#C0504E;font-size:11px;font-weight:800;line-height:20px}
|
||
.myc .go{position:relative;display:flex;align-items:center;justify-content:space-between;margin-top:10px;padding-top:9px;border-top:1px dashed rgba(255,255,255,.4);font-size:12px;font-weight:800}
|
||
.myc .go .ic{width:14px;height:14px}
|
||
.myc .dot{position:absolute;right:10px;top:10px;z-index:1;height:18px;padding:0 6px;border-radius:99px;background:#fff;color:#E8473A;font-size:10.5px;font-style:normal;font-weight:900;line-height:18px}
|
||
@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(116px + 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}
|
||
|
||
/* 图上压字(11-02 用户:文字放到图片上穿插来,小红书式):ov 底部渐变大字 / tg 贴纸字 */
|
||
.nc .ovt{position:absolute;left:0;right:0;bottom:0;padding:56px 11px 11px;background:linear-gradient(transparent,rgba(30,18,14,.35) 30%,rgba(30,18,14,.72));color:#fff;pointer-events:none}
|
||
.nc .ovt b{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;font-size:17px;font-weight:900;line-height:1.38;letter-spacing:.3px;text-shadow:0 1px 4px rgba(0,0,0,.3)}
|
||
.nc .ovt small{display:inline-block;margin-bottom:5px;padding:0 6px;border-radius:5px;background:rgba(255,255,255,.22);font-size:10.5px;font-weight:700;line-height:18px}
|
||
.nc .tgt{position:absolute;left:9px;right:9px;bottom:12px;pointer-events:none}
|
||
.nc .tgt b{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;font-size:15.5px;font-weight:900;line-height:1.62;color:#2A1E1E}
|
||
.nc .tgt span{background:#FFF2A6;padding:1px 5px;-webkit-box-decoration-break:clone;box-decoration-break:clone;border-radius:3px}
|
||
.nc:nth-child(odd) .tgt span{background:#fff}
|
||
.nc .ovt~*,.nc .tgt~*{display:none}
|
||
.nc .ovt.at-top{bottom:auto;top:0;padding:11px 11px 56px;background:linear-gradient(rgba(30,18,14,.72),rgba(30,18,14,.35) 70%,transparent)}
|
||
.nc .ovt.at-mid{bottom:auto;top:50%;transform:translateY(-50%);padding:16px 11px;background:rgba(30,18,14,.42)}
|
||
.nc .tgt.at-top{bottom:auto;top:12px}
|
||
.nc .tgt.at-mid{bottom:auto;top:50%;transform:translateY(-50%)}
|
||
.cm-ld{padding:22px 0;text-align:center;font-size:12.5px;color:#B8A39D}
|
||
.nc.s-ov .nb .tp,.nc.s-tg .nb .tp{display:none} /* 11-02 用户:图上带字的卡,下方放一行标题、不放话题 */
|
||
.nc.s-ov .nb h3,.nc.s-tg .nb h3{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-line-clamp:unset}
|
||
|
||
/* ---------- 详情层 ---------- */
|
||
#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 span{flex:1}
|
||
.tl button em{font-style:normal;color:var(--hk);font-weight:900;margin:0 1px}
|
||
.tl button small{display:block;margin-top:2px;font-size:11px;font-weight:600;color:#A8918B}
|
||
.tl-h small{margin-left:6px;font-size:12px;font-weight:600;color:#A8918B}
|
||
.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;margin-left:3px;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}
|
||
/* 11-03 用户评论要后台审核:自己的评论挂状态 */
|
||
.ci-st{display:inline-block;margin-top:5px;padding:0 7px;border-radius:4px;font-size:11px;line-height:18px;font-weight:600}
|
||
.ci-st.pending{background:#FFF4E5;color:#E08A00}.ci-st.rejected{background:#F2F3F5;color:#86909C}.ci-st.local{background:#F2F3F5;color:#A0A6AE}
|
||
.ci.mine.rejected .ci-t{color:#A0A6AE}
|
||
.ci-b[data-rk] .ci-t,.rp p[data-rk]{cursor:pointer}.ci-b[data-rk] .ci-t:active,.rp p[data-rk]:active{opacity:.6}
|
||
.rp .au.me{background:#FFE7E0;color:#EC4D33}.rp p.rej{color:#A0A6AE}.rp .ci-st{margin-top:3px}
|
||
/* 11-03 用户:孕周挪到名字右边,样式同专题页的小胶囊 */
|
||
.ci-n .stg{font-style:normal;font-size:11px;line-height:17px;padding:0 6px;border-radius:99px;background:#F5EFEC;color:#A08C86;white-space:nowrap}
|
||
.ci-s .rpy{margin-left:0;color:#8C7B75;font-weight:600;cursor:pointer}
|
||
.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 4px 0 7px;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 .nsp{flex:none;width:36px}
|
||
#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}
|
||
/* 审核结果 / 提交成功弹窗 */
|
||
#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)}
|
||
|
||
/* ---------- 底部胶囊 Tab(11-03 用户:「主页面里加上返回兜爸和记一下那个 tab,就跟数胎动一样」)
|
||
照数胎动 /taidong/ 的最终样式:悬浮药丸 + 中间「记一下」橙色圆钮(玻璃顶部挖缺口坐进去)+ 右边「返回兜爸」(有真头像就显示头像 + 小房子角标)。
|
||
z-index 30:详情 / 收藏 / 投稿 / 弹层都在 35 以上,打开时自然盖住它。 ---------- */
|
||
.tab-fade{position:fixed;left:0;right:0;bottom:0;z-index:29;pointer-events:none;height:calc(96px + var(--safe-b));background:linear-gradient(180deg,rgba(255,246,241,0),rgba(255,246,241,.75))}
|
||
.tabbar{position:fixed;left:16px;right:16px;bottom:calc(22px + var(--safe-b));height:62px;z-index:30;border-radius:31px;padding:0 6px;display:grid;grid-template-columns:repeat(3,1fr)}
|
||
.tabbar::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:#FFF9F5;
|
||
box-shadow:inset 0 0 0 1px rgba(255,255,255,.85),inset 0 1px 0 #fff;
|
||
-webkit-mask:radial-gradient(circle 31px at 50% 6px,transparent 30.5px,#000 31.5px);mask:radial-gradient(circle 31px at 50% 6px,transparent 30.5px,#000 31.5px)}
|
||
.tabbar::after{content:"";position:absolute;inset:0;z-index:-2;border-radius:inherit;pointer-events:none;box-shadow:0 14px 34px rgba(200,100,70,.2),0 2px 6px rgba(200,100,70,.06)}
|
||
.tab{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:0 0 6px;border:0;background:none;font-family:inherit;color:#A3958D;cursor:pointer;transition:color .22s;-webkit-tap-highlight-color:transparent}
|
||
.tab.on{color:#F4593C}
|
||
.t-ico{width:25px;height:25px;display:block;position:relative}
|
||
.t-svg{display:block;width:100%;height:100%;overflow:visible}
|
||
.t-svg .tf,.t-svg .tl{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
|
||
.t-svg .td{fill:currentColor;stroke:none}
|
||
.tab.on .t-svg .tf{fill:currentColor}
|
||
.tab.on .t-svg .tl{stroke:#fff}
|
||
.tab.on .t-svg .td{fill:#fff}
|
||
.tab .t-txt{font-size:12.5px;font-weight:600;line-height:1.1;letter-spacing:.2px;white-space:nowrap}
|
||
.tab.on .t-txt{font-weight:800}
|
||
.tab::after{content:"";position:absolute;left:50%;bottom:6px;width:4px;height:4px;margin-left:-2px;border-radius:50%;background:#F4593C;opacity:0}
|
||
.tab.on::after{opacity:1}
|
||
.tab-fab::after{display:none}
|
||
.tab-fab .fab{position:absolute;left:50%;top:-20px;width:52px;height:52px;margin-left:-26px;border-radius:50%;display:grid;place-items:center;overflow:visible;
|
||
background:linear-gradient(150deg,#FF8A6E,#F4593C);box-shadow:0 6px 14px rgba(244,89,60,.32),inset 0 1px 0 rgba(255,255,255,.3);transition:transform .3s cubic-bezier(.3,1.6,.5,1)}
|
||
.tab-fab .fab::before{content:"";display:block;width:20px;height:20px;opacity:.28;border-radius:2px;
|
||
background:linear-gradient(#fff,#fff) center/100% 3px no-repeat,linear-gradient(#fff,#fff) center/3px 100% no-repeat}
|
||
.tab-fab:active .fab{transform:scale(.9)}
|
||
.fab-w{position:absolute;left:50%;top:50%;transform:translate(calc(-50% - 5px),-54%) rotate(-8deg);display:flex;align-items:center;white-space:nowrap;font-weight:900;font-style:normal;color:#4A1E14;line-height:1;pointer-events:none;
|
||
text-shadow:1.6px 0 #fff,-1.6px 0 #fff,0 1.6px #fff,0 -1.6px #fff,1.2px 1.2px #fff,-1.2px 1.2px #fff,1.2px -1.2px #fff,-1.2px -1.2px #fff,0 3px 4px rgba(120,30,10,.25)}
|
||
.fab-w i{font-style:normal;font-size:31px}
|
||
.fab-w em{font-style:normal;font-size:12.5px;line-height:1;margin:9px 0 0;letter-spacing:-.5px}
|
||
.fab-w s{text-decoration:none;font-size:20px;display:inline-block;transform:skewX(-8deg)}
|
||
.tab-fab .t-txt{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
|
||
#tabHome .t-ico{margin-bottom:6px}
|
||
#tabHome .t-txt{font-size:11.5px;font-weight:600}
|
||
.tab-avimg{position:absolute;inset:-3px;width:calc(100% + 6px);height:calc(100% + 6px);border-radius:50%;object-fit:cover;display:none;box-shadow:0 3px 10px rgba(226,105,74,.38)}
|
||
.tab-hm{position:absolute;right:-8px;bottom:-5px;width:15px;height:15px;z-index:1;border-radius:50%;display:none;background:linear-gradient(150deg,#E2694A,#C24E31);box-shadow:0 0 0 1.5px #FFF6F1}
|
||
.tab-hm svg{display:block;width:10px;height:10px;margin:2.5px}
|
||
.t-ico.has-av .tab-avimg,.t-ico.has-av .tab-hm{display:block}
|
||
.t-ico.has-av .t-svg{visibility:hidden}
|
||
.t-ico.has-av::before{content:"";position:absolute;inset:-6px;border-radius:50%;z-index:-1;pointer-events:none;
|
||
background:conic-gradient(from 0deg,rgba(226,105,74,0) 0deg,#F09A72 90deg,#E2694A 200deg,rgba(226,105,74,0) 300deg);
|
||
-webkit-mask:radial-gradient(circle,transparent 61%,#000 63%,#000 72%,transparent 74%);mask:radial-gradient(circle,transparent 61%,#000 63%,#000 72%,transparent 74%)}
|
||
/* 「记一下」弹层:标题一行 + 4 列工具宫格(同数胎动 / 首页) */
|
||
.rec-h{display:flex;align-items:baseline;gap:10px;padding:10px 2px 14px}
|
||
.rec-h b{font-size:19px;font-weight:800;color:#2A1E1E;flex:none}
|
||
.rec-h span{font-size:12px;color:#9C8F88;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.rec-x{flex:none;align-self:center;width:30px;height:30px;border:0;border-radius:50%;display:grid;place-items:center;background:rgba(120,70,50,.08);color:#9C8F88;cursor:pointer}
|
||
.rec-x .ic{width:12px;height:12px}
|
||
.rec-apps{display:grid;grid-template-columns:repeat(4,1fr);gap:20px 6px;padding:4px 0 8px}
|
||
.rec-app{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0;border:0;background:none;font-family:inherit;color:#2A1E1E;cursor:pointer;transition:transform .16s}
|
||
.rec-app:active{transform:scale(.92)}
|
||
.rec-app img,.rec-app .rl{width:48px;height:48px;display:block;object-fit:contain;border-radius:14px}
|
||
.rec-app .rl{display:grid;place-items:center;background:#F6D9CB;color:#C2553A;font-size:19px;font-weight:800}
|
||
.rec-app span{display:block;max-width:100%;font-size:11.5px;font-weight:600;letter-spacing:-.2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.rec-app.off img,.rec-app.off .rl{opacity:.45;filter:grayscale(.4)}
|
||
.rec-app.off i{position:absolute;top:-8px;left:calc(50% + 4px);font-style:normal;font-size:9px;font-weight:700;line-height:1;padding:3px 5px;border-radius:99px;background:#B9A9A2;color:#fff;white-space:nowrap}
|
||
.rec-empty{padding:30px 0;text-align:center;font-size:13px;color:#9C8F88}
|
||
</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-spark" viewBox="0 0 24 24"><path d="M12 3l2 6.2L20 12l-6 2.8L12 21l-2-6.2L4 12l6-2.8z" 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>
|
||
<i class="nsp"></i>
|
||
</div>
|
||
<div class="cats" id="cats" role="tablist" aria-label="分类"></div>
|
||
</div>
|
||
<div id="pane">
|
||
<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 id="more"></div>
|
||
<div class="end"><b>— 到底啦 —</b><small>内容为示例占位,正式版将替换为妈妈们的真实分享</small></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-fade" aria-hidden="true"></div>
|
||
<nav class="tabbar" id="tabbar">
|
||
<button class="tab on" id="tabPlaza" type="button"><span class="t-ico"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><path class="tf" d="M4 6.6A2.6 2.6 0 0 1 6.6 4h10.8A2.6 2.6 0 0 1 20 6.6v7.8a2.6 2.6 0 0 1-2.6 2.6H11l-4.2 3.2c-.4.3-.9 0-.9-.4V17h0A2.6 2.6 0 0 1 4 14.4z"/><path class="tl" d="M8.5 9.4h7M8.5 12.6h4.4"/></svg></span><span class="t-txt">孕妈广场</span></button>
|
||
<button class="tab tab-fab" id="tabRec" type="button"><span class="fab"><b class="fab-w" aria-hidden="true"><i>记</i><em>一下</em><s>!</s></b></span><span class="t-txt">记一下</span></button>
|
||
<button class="tab" id="tabHome" type="button"><span class="t-ico" id="tabAv"><svg class="t-svg" viewBox="0 0 24 24" aria-hidden="true"><path class="tf" d="M4 10.4 12 4l8 6.4V18a2.4 2.4 0 0 1-2.4 2.4H6.4A2.4 2.4 0 0 1 4 18z"/><path class="tl" d="M9.8 20.2v-4.4a2.2 2.2 0 0 1 4.4 0v4.4"/></svg></span><span class="t-txt">返回兜爸</span></button>
|
||
</nav>
|
||
|
||
<div id="fvp" aria-hidden="true">
|
||
<div class="nav"><button class="bk" id="fvBack" type="button" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button><h1><span>我的收藏</span></h1><i class="nsp"></i></div>
|
||
<div id="fvs"><div class="fvh" id="fvh"></div><div class="wf" id="fvw"><div class="col"></div><div class="col"></div></div></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=26110251"></script>
|
||
<script src="data.js?v=26110251"></script>
|
||
<script src="feed.js?v=26110251"></script>
|
||
<script src="ceshi/meta.js?v=26110251"></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];
|
||
/* 11-02 用户:「要参差不齐的小红书瀑布流,现在都横向对齐」→ 照片封面高度按 id 哈希在 0.95~1.45 之间取,不再统一 1.3 */
|
||
var PR = [1.33, 1.05, 1.25, 1.45, 1.15, 0.95, 1.38, 1.2];
|
||
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 ? PR[seed(t.id + '-' + (i + 1) + 'r') % PR.length] : 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 < 30; 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'];
|
||
/* 评论(11-02 用户:每篇 ≥20 条、紧贴正文、有作者回复;评论人从 1000 个人设里取,一人会在多篇下留言)
|
||
cm.json = { p: [[昵称, 头像(数字=av/NNNN.webp,字符串=assets/img/mom/xxx.jpg), 阶段]], c: { 帖子id: [[人设, 内容, 赞, [[人设|-1=作者, 内容]]]] } }
|
||
模拟内容,见 AGENTS.md 12c;文件较大,进页面后后台拉,详情页先显示「评论加载中」 */
|
||
var CMD = null, CMERR = false;
|
||
/* 头像编码:数字 = av/NNNN.webp(旧代码头像);'av:c012' = av/c012.webp(卡通/可爱卡通);'/…' = 站内绝对路径(内置头像库 /_bridge/avatars/);其余 = assets/img/mom/xxx.jpg */
|
||
var avP = function (a) { return typeof a === 'number' ? 'av/' + ('000' + a).slice(-4) + '.webp' : a.indexOf('av:') === 0 ? 'av/' + a.slice(3) + '.webp' : a.charAt(0) === '/' ? a : '../assets/img/mom/' + a + '.jpg'; };
|
||
fetch('cm.json?v=26110251').then(function (r) { return r.json(); }).then(function (j) {
|
||
CMD = j; if (openId && NBY[openId]) { renderComments(NBY[openId]); syncBar(NBY[openId]); }
|
||
}).catch(function () { CMERR = true; if (openId && NBY[openId]) renderComments(NBY[openId]); });
|
||
function commentsOf(n) {
|
||
if (n.real || !CMD) return []; /* 真实投稿不配模拟评论 */
|
||
var L = CMD.c[n.id] || [], P = CMD.p;
|
||
return L.map(function (c, k) {
|
||
var p = P[c[0]];
|
||
return { key: n.id + '#' + k, n: p[0], av: avP(p[1]), s: p[2], t: c[1], likes: c[2],
|
||
r: c[3].map(function (x) { var q = x[0] < 0 ? null : P[x[0]]; return { n: q ? q[0] : n.author, t: x[1], au: !q }; }) };
|
||
});
|
||
}
|
||
|
||
/* ---------- 本机存储 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); };
|
||
/* 11-03 用户:评论要后台审核通过才对外公开。服务器 /plaza/comments:list = 别人已通过的;mine = 我在这篇下发的(含审核中 / 未通过)。
|
||
ME.cm 里没有 id 的是 11-03 以前只存本机的旧评论,从没公开过,照旧只给自己看(标「仅自己可见」)。 */
|
||
var RC = {};
|
||
var myCm = function (id) {
|
||
var old = (ME.cm[id] || []).filter(function (c) { return !c.id; }).map(function (c) { return { t: c.t, ts: c.ts, s: c.s, st: 'local' }; });
|
||
var srv = RC[id] ? RC[id].mine.map(function (c) { return { id: c.id, t: c.text, ts: c.at, s: c.stage, st: c.status, why: c.reason, parent: c.parent, to: c.parentName }; }) : [];
|
||
return old.concat(srv.reverse());
|
||
};
|
||
var realCm = function (id) { return RC[id] ? RC[id].list : []; };
|
||
/* 11-03 用户:可以回复别人的评论。回复也先审核;楼里只有一层,回复回复也挂在同一楼,写「回复 XX」 */
|
||
var REPLY = null;
|
||
function extraReplies(id, k) {
|
||
var o = realCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: c.nickname || '孕妈', t: c.text, to: c.parentName, ts: c.at }; });
|
||
var m = myCm(id).filter(function (c) { return c.parent === k; }).map(function (c) { return { n: MYNAME, me: 1, t: c.t, to: c.to, st: c.st, why: c.why, ts: c.ts }; });
|
||
return o.concat(m).sort(function (x, y) { return x.ts - y.ts; }); /* 楼里按时间先后 */
|
||
}
|
||
function stTag(c) { return c.st === 'pending' ? '<span class="ci-st pending">审核中 · 通过后大家才能看到</span>' : c.st === 'rejected' ? '<span class="ci-st rejected">未通过' + (c.why ? ':' + esc(c.why) : '') + '</span>' : c.st === 'local' ? '<span class="ci-st local">仅自己可见</span>' : ''; }
|
||
function rpHTML(list, k, owner) {
|
||
return list.length ? '<div class="rp">' + list.map(function (x) {
|
||
return '<p' + (x.me ? ' class="rme' + (x.st === 'rejected' ? ' rej' : '') + '"' : ' data-rk="' + esc(k) + '" data-rn="' + esc(x.n) + '"') + '><b>' + esc(x.n) + '</b>' + (x.au ? '<span class="au">作者</span>' : '') + (x.me ? '<span class="au me">我</span>' : '') +
|
||
(x.to && x.to !== owner ? ' 回复 <b>' + esc(x.to) + '</b>' : '') + ':' + esc(x.t) + (x.me && x.st && x.st !== 'approved' ? '<br>' + stTag(x) : '') + '</p>';
|
||
}).join('') + '</div>' : '';
|
||
}
|
||
var cmN = function (n) { return commentsOf(n).length + realCm(n.id).length + myCm(n.id).filter(function (c) { return c.st !== 'rejected'; }).length; }; /* 含回复 */
|
||
function loadRC(n) {
|
||
var u = '/api/mp/public/mama-box/plaza/comments?kind=post&target=' + encodeURIComponent(n.id) + (OPENID ? '&openid=' + encodeURIComponent(OPENID) : '');
|
||
fetch(u).then(function (r) { return r.json(); }).then(function (j) {
|
||
if (!j || j.code !== 200) return;
|
||
RC[n.id] = j.result;
|
||
if (openId === n.id) { renderComments(n); syncBar(n); }
|
||
}).catch(function () {});
|
||
}
|
||
|
||
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"></div>'; /* 11-03 用户:信息流卡片左上角「职场 / 家庭婚姻」标签删掉 */
|
||
return '<div class="cv" style="--c1:' + c[0] + ';--c2:' + c[1] + ';--tk:' + pl.ink + ';' + (h ? 'height:' + h : '') + '">' + (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>';
|
||
}
|
||
/* 卡片样式 sty(只对照片封面):'' 普通图 / 'ov' 图上压大字(底部渐变)/ 'tg' 图上贴纸字 —— 11-02 用户:「把一些文字放到图片上,穿插着来,类似小红书」 */
|
||
function cardHTML(n, showTopic, sty) {
|
||
var t = TBY[n.t], r = n.ratio, ov = '';
|
||
if (!n.photo) sty = '';
|
||
/* 11-02 用户:图上放的短语「不知所云」→ 图上直接放完整标题;卡片下方再放一行标题(单行省略)、不放话题。
|
||
11-02 二改:普通卡(图上没字)也不放话题;图上文字 70% 在底部,30% 放顶部/中间(按帖子 id 哈希固定,刷新不跳) */
|
||
var ph = 0; for (var q = 0; q < n.id.length; q++) ph = (ph * 31 + n.id.charCodeAt(q)) >>> 0;
|
||
var pos = ph % 10 < 7 ? '' : ph % 10 < 9 ? ' at-mid' : ' at-top';
|
||
if (sty === 'ov') { r = Math.max(r, 1.33); ov = '<div class="ovt' + pos + '">' + (n.stage ? '<small>' + esc(n.stage) + '</small>' : '') + '<b>' + esc(n.title) + '</b></div>'; }
|
||
else if (sty === 'tg') { r = Math.max(r, 1.2); ov = '<div class="tgt' + pos + '"><b><span>' + esc(n.title) + '</span></b></div>'; }
|
||
return '<button type="button" class="nc' + (sty ? ' s-' + sty : '') + '" data-id="' + n.id + '"><div class="cvw">' +
|
||
coverHTML(n, 'calc(var(--cw) * ' + r + ')') + ov + '</div>' +
|
||
'<div class="nb"><h3>' + esc(n.title) + '</h3><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 UBAND = (function () { try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); return !g ? -1 : g.pp ? 'pp' : g.w && window.GC_BAND ? window.GC_BAND('孕' + g.w + '周') : -1; } catch (e) { return -1; } })();
|
||
/* 11-01 用户:家庭+婚姻合成「家庭婚姻」,母婴改「经验」→ 三块(marriage 话题在 topics.js 里已并进 family) */
|
||
var CATS = [['', '全部', 'i-grid'], ['family', '家庭婚姻', 'i-home'], ['work', '职场', 'i-bag'], ['baby', '经验', 'i-baby'], ['ceshi', '测一测', 'i-spark']];
|
||
var CAT_ORDER = ['family', 'work', 'baby'];
|
||
var CAT_NAME = { family: '家庭婚姻', 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() {
|
||
var bs = $('#cats').querySelectorAll('button[data-c]');
|
||
if (bs.length) { /* 已画过:只换选中态,胶囊才能滑过去 */
|
||
[].forEach.call(bs, function (b) { var on = b.dataset.c === catF; b.classList.toggle('on', on); b.setAttribute('aria-selected', on); });
|
||
moveBar(); return;
|
||
}
|
||
$('#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]) + '">' +
|
||
(x[0] === 'ceshi' ? '<svg class="ic"><use href="#i-spark"/></svg>' : '') + x[1] + '<i>' + catCnt(x[0]) + '</i></button>';
|
||
}).join('') + '<span class="bar"></span>';
|
||
moveBar();
|
||
}
|
||
function catCnt(c) { if (c === 'ceshi') return TM.length; return NOTES.filter(function (n) { return !c || TBY[n.t].cat === c; }).length; }
|
||
/* 胶囊挪到选中标签文字下方,宽度跟文字走(取文字宽的一半,偏小红书) */
|
||
function moveBar() {
|
||
var on = $('#cats .on'), bar = $('#cats .bar'); if (!on || !bar) return;
|
||
var w = on.offsetWidth - 20, x = on.offsetLeft + (on.offsetWidth - w) / 2;
|
||
bar.style.width = w + 'px'; bar.style.transform = 'translateX(' + x + 'px)';
|
||
bar.style.background = getComputedStyle(on).getPropertyValue('--cf');
|
||
bar.style.opacity = on.dataset.c === 'ceshi' ? '0' : '';
|
||
}
|
||
window.addEventListener('resize', moveBar);
|
||
/* 11-02 用户:「孕妈广场做一张为宝宝祈福的 banner,点了直接进祈福树;要把祈福树调上来、有动效,像首页 3D 婴儿房,吸引点击;替换掉 30 现金 + 500 兜豆」
|
||
→ 夜空卡 + 右侧祈福树(透明图 assets/img/d71826d10457.png,AI 生成)轻轻摇 + 树后金光呼吸 + 福牌往上飘 + 星星闪;整卡可点 */
|
||
function qifuHTML() {
|
||
return '<button type="button" class="qf" id="qfBanner" aria-label="去宝宝祈福树,为宝宝挂一张福牌">' +
|
||
'<i class="qf-st" aria-hidden="true"></i><i class="qf-glow" aria-hidden="true"></i>' +
|
||
'<img class="qf-tree" src="../assets/img/d71826d10457.png" alt="" decoding="async">' +
|
||
'<span class="qf-fly" aria-hidden="true"><i>福</i><i>安</i><i>福</i><i>康</i></span>' +
|
||
'<span class="qf-tx"><small><i></i>宝宝祈福树</small><b><i>#</i>为宝宝挂一张福牌<i>#</i></b><em>集齐五福,愿宝宝平平安安</em>' +
|
||
'<span class="qf-go">去祈福<svg class="ic"><use href="#i-right"/></svg></span></span></button>';
|
||
}
|
||
/* 跳祈福树:同首页 jumpApp(QIFU_URL) —— 相对路径、身份走 query、上报 last_app 与分享位置(AGENTS 硬约定 3/6/7/13) */
|
||
function goQifu() { goApp('/qifu-shu/'); }
|
||
/* 跳站内其他 H5(祈福树 / 记一下宫格共用):只走相对路径(AGENTS 13),后台给的完整地址也剥成 /slug/… */
|
||
function goApp(url) {
|
||
try { var u = new URL(url, location.href); if (u.origin === location.origin || /(^|\.)yizhezhe\.com$/.test(u.hostname)) url = u.pathname + u.search; } catch (e) {}
|
||
var q = [], oid = param('openid'), uid = param('unionid');
|
||
if (oid) q.push('openid=' + encodeURIComponent(oid));
|
||
if (uid) q.push('unionid=' + encodeURIComponent(uid));
|
||
if (!oid && !uid) q.push('__no_identity=1');
|
||
var target = url + (url.indexOf('?') >= 0 ? '&' : '?') + q.join('&');
|
||
try {
|
||
if (oid) {
|
||
var api = '/api/mp/public/last-app?openid=' + encodeURIComponent(oid) + '&url=' + encodeURIComponent(location.origin + url);
|
||
if (!(navigator.sendBeacon && navigator.sendBeacon(api)) && window.fetch) fetch(api, { method: 'POST', keepalive: true }).catch(function () {});
|
||
}
|
||
if (window.wxAuth && wxAuth.reportLocation) wxAuth.reportLocation({ href: target });
|
||
} catch (e) {}
|
||
haptic(); location.href = target;
|
||
}
|
||
/* 11-02 v2 用户:「测一测放到『经验』后边;孕妈广场上现在那个测一测删掉;『大家在聊』里穿插几个测一测,点了进对应的测试」
|
||
→ CATS 加第 5 个分类 ceshi;选中时 #head 放说明卡、#fh 放分组胶囊、#wf 瀑布流放 25 张测试卡;「全部」信息流每 8 张帖子穿插 1 张测试卡(先 CS_MIX 再按热度)。
|
||
测试目录只引轻量 ceshi/meta.js;题库在 ceshi/tests.js,只在测试页加载。 */
|
||
var TM = window.GC_TESTS_META || [], TMBY = {};
|
||
TM.forEach(function (x) { TMBY[x.id] = x; });
|
||
var TG = { quiz: '常识小测', psy: '趣味心理', game: '趣味闯关', shop: '好物配置' }, tGrp = '';
|
||
var CS_MIX = ['t11', 't29', 't01', 't24', 't26', 't16', 't03', 't27', 't14', 't21', 't30', 't18'];
|
||
function csDone() { try { return (JSON.parse(localStorage.getItem('mmbox.gcts.v1') || '{}')[param('openid') || '_guest']) || {}; } catch (e) { return {}; } }
|
||
function ceshiURL(id, fromTab) {
|
||
var q = new URLSearchParams(location.search); ['t', 'n', 'c', 'id', 'mine', 'write', 'fav'].forEach(function (k) { q.delete(k); });
|
||
if (fromTab) q.set('c', 'ceshi');
|
||
q.set('id', id);
|
||
return 'ceshi/?' + q.toString() + location.hash;
|
||
}
|
||
function testCardHTML(x, done) {
|
||
var d = done && done[x.id];
|
||
return '<button type="button" class="nc tst g-' + x.group + '" data-test="' + x.id + '"><div class="cvw"><img src="ceshi/img/' + x.id + '_s.webp" alt="" loading="lazy">' +
|
||
'<span class="tb"><svg class="ic"><use href="#i-spark"/></svg>测一测</span><span class="tq">' + gcTestedText(x.id) + ' · ' + x.n + ' 题</span></div>' +
|
||
'<div class="nb"><h3>' + esc(x.title) + '</h3><div class="nf">' + (d ? '<span class="gs dn">已测 · ' + esc(d.title) + '</span>' : '<span class="gs">' + TG[x.group] + '</span>') +
|
||
'<span class="gt">' + (d ? '再测' : '去测') + ' ›</span></div></div></button>';
|
||
}
|
||
/* 热度排序:按「N人测过」(ceshi/meta.js gcTested,模拟数,见 AGENTS.md 12b)从高到低 */
|
||
var byHot = function (l) { return l.slice().sort(function (a, b) { return gcTested(b.id) - gcTested(a.id); }); }, hotOpen = false;
|
||
var TGD = { quiz: '有标准答案,答完看解析', psy: '没有对错,测测你是哪一型', game: '挑战一下,看能拿什么称号', shop: '看看你是哪一类育儿采购玩家' };
|
||
/* 统一列表行:缩略图(热度榜带名次)+ 标题 / 说明 + 右侧大号人数;测过的右侧换成「已测」 */
|
||
function rowHTML(x, done, rank) {
|
||
var d = done[x.id], num = gcTestedText(x.id).replace('人测过', '').replace('万', '<i>万</i>');
|
||
return '<button type="button" class="cr g-' + x.group + '" data-test="' + x.id + '"><span class="cth"><img src="ceshi/img/' + x.id + '_s.webp" alt="" loading="lazy">' +
|
||
(rank ? '<i class="crk' + (rank <= 3 ? ' r' + rank : '') + '">' + rank + '</i>' : '') + '</span>' +
|
||
'<span class="tx"><b>' + esc(x.title) + '</b><small>' + (d ? '<em>' + (x.group === 'quiz' || x.group === 'game' ? '已拿「' : '我是「') + esc(d.title) + '」</em>' : (rank ? '<em>' + TG[x.group] + '</em> · ' : '') + esc(x.sub)) + '</small></span>' +
|
||
'<span class="cn"><b>' + num + '</b><small><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12.6 2.5c.4 3-1.6 4.6-3 6.2C8 10.4 7 12 7 14.3A5 5 0 0012 19.5a5 5 0 005-5.2c0-2-1-3.6-1.9-4.6-.2 1.3-.9 2.2-1.9 2.6.6-3.4-.2-7-.6-9.8z" fill="currentColor"/></svg>人测过</small></span></button>';
|
||
}
|
||
function hotHTML(done) {
|
||
var l = byHot(TM);
|
||
return '<section class="csg csk"><div class="csg-h"><b>热度榜</b><small>按测过的人数排名</small></div><div class="cpl">' +
|
||
l.slice(0, hotOpen ? l.length : 5).map(function (x, i) { return rowHTML(x, done, i + 1); }).join('') +
|
||
'<button type="button" class="ckm" data-hot="1">' + (hotOpen ? '收起' : '查看完整榜单(' + l.length + ' 个)') + '</button></div></section>';
|
||
}
|
||
function ceshiListHTML() {
|
||
var done = csDone();
|
||
return '<div class="csl">' + (tGrp ? '' : hotHTML(done)) + ['quiz', 'psy', 'game', 'shop'].filter(function (g) { return !tGrp || tGrp === g; }).map(function (g) {
|
||
var l = byHot(TM.filter(function (x) { return x.group === g; })); if (!l.length) return '';
|
||
var nd = l.filter(function (x) { return done[x.id]; }).length;
|
||
return '<section class="csg g-' + g + '"><div class="csg-h"><b>' + TG[g] + '</b><small>' + l.length + ' 套 · ' + TGD[g] + '</small>' + (nd ? '<em>已测 ' + nd + '</em>' : '') + '</div>' +
|
||
'<div class="cpl">' + l.map(function (x) { return rowHTML(x, done); }).join('') + '</div></section>';
|
||
}).join('') + '</div>';
|
||
}
|
||
function ceshiHead() { /* 11-02 用户同意:介绍卡压成一行,让热度榜进第一屏 */
|
||
return '<div class="csh"><svg class="ic"><use href="#i-spark"/></svg><b>孕育测一测</b><span>累计 ' + Math.round(TM.reduce(function (a, x) { return a + gcTested(x.id); }, 0) / 1e4) + ' 万人次参与</span></div>';
|
||
}
|
||
function ceshiFh(fh) {
|
||
fh.className = 'lvw k-ceshi';
|
||
var all = [['', '全部', TM.length]].concat(['quiz', 'psy', 'game', 'shop'].map(function (g) { return [g, TG[g], TM.filter(function (x) { return x.group === g; }).length]; }));
|
||
fh.innerHTML = '<div class="lv"><h2>测一测</h2><small>' + TM.length + ' 个测试 · 每个 12 题以上</small></div>' +
|
||
'<div class="tcs">' + all.map(function (x) { return '<button type="button" data-tg="' + x[0] + '"' + (tGrp === x[0] ? ' class="on"' : '') + '>' + x[1] + '<i>' + x[2] + '</i></button>'; }).join('') + '</div>';
|
||
}
|
||
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 < 10; 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 (catF === 'ceshi') { el.innerHTML = ceshiHead(); ceshiFh(fh); return; }
|
||
if (!t) {
|
||
var hl = hotList();
|
||
el.innerHTML = qifuHTML() +
|
||
'<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>' +
|
||
/* 11-02 用户:「热门话题不要一块一块的,改成井号、偏列表的形式」→ 排行列表:名次 + #话题# + 一行简介 + 篇数/热,右侧「参与」
|
||
投稿奖励从顶部大横幅挪到这里当列表头一行(用户:「30 现金 + 500 兜豆看放哪」→ 跟「参与」放一起,点了看规则) */
|
||
'<div class="htl"><button type="button" class="rwl" data-rule="1"><svg class="ic"><use href="#i-gift"/></svg><span>投稿被选中得 ' + REWARD + '</span><b>怎么参与 ›</b></button>' + hl.slice(0, 4).map(function (x, i) { /* 11-02 用户:热门话题 6 → 4 个,去掉下面浅色小字 */
|
||
return '<div class="hr k-' + x.cat + '" data-t="' + x.id + '" role="button"><i class="no' + (i < 3 ? ' t' + i : '') + '">' + (i + 1) + '</i>' +
|
||
'<span class="hm"><b><em>#</em>' + esc(x.name) + '<em>#</em></b></span>' +
|
||
'<button type="button" class="jn" data-join="' + x.id + '">参与</button></div>';
|
||
}).join('') + '<button type="button" class="hall" data-all="1">查看全部 ' + hl.length + ' 个话题 ›</button></div>';
|
||
if (catF) { fhLevels(fh); return; }
|
||
fh.className = 'sh';
|
||
fh.innerHTML = '<h2>大家在聊</h2><small>' + T.filter(function (x) { return cntT(x.id); }).length + ' 个话题 · 共 ' + NOTES.length + ' 篇</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>' +
|
||
'<div class="bc"><button type="button" data-t="">' + kbHTML(t.cat).replace('</span>', ' ›</span>') + '</button><span>话题 · ' + cntT(t.id) + ' 篇</span></div>' +
|
||
'<h2><em>#</em>' + esc(t.name) + '<em>#</em></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>';
|
||
/* 11-02 用户:「话题页比较乱」→ 去掉投稿奖励横幅和同分类话题胶囊,只留一行标题 */
|
||
fh.className = 'sh';
|
||
fh.innerHTML = '<h2>这个话题下的分享</h2><small>共 ' + cntT(t.id) + ' 篇</small>';
|
||
}
|
||
/* 11-02 用户:「选了家庭婚姻下一个话题,看着像这块就这几篇,层次感没出来」→ 选了分类 / 话题时,列表上方固定一行「分类 · N 个话题 · 共 M 篇」+ 该分类全部话题胶囊(带篇数),当前话题高亮,「全部」回分类 */
|
||
var cntT = function (id) { return NOTES.filter(function (n) { return n.t === id; }).length; };
|
||
function fhLevels(fh) {
|
||
var tl = hotList().filter(function (x) { return cntT(x.id); }), all = 0;
|
||
tl.forEach(function (x) { all += cntT(x.id); });
|
||
fh.className = 'lvw k-' + catF;
|
||
fh.innerHTML = '<div class="lv"><h2>' + CATS.filter(function (c) { return c[0] === catF; })[0][1] + '</h2><small>' + tl.length + ' 个话题 · 共 ' + all + ' 篇</small>' +
|
||
(cur ? '<button type="button" class="ba" data-t="">看这块全部 ›</button>' : '') + '</div>' +
|
||
'<div class="tcs"><button type="button" data-t=""' + (cur ? '' : ' class="on"') + '>全部<i>' + all + '</i></button>' +
|
||
tl.map(function (x) { return '<button type="button" data-t="' + x.id + '"' + (cur === x.id ? ' class="on"' : '') + '>#' + esc(x.name) + '#<i>' + cntT(x.id) + '</i></button>'; }).join('') + '</div>';
|
||
var on = fh.querySelector('.tcs .on'); if (on && cur) fh.querySelector('.tcs').scrollLeft = Math.max(0, on.offsetLeft - 60);
|
||
}
|
||
function renderFeed() {
|
||
var list = cur ? NOTES.filter(function (n) { return n.t === cur; }) : MIXED.filter(function (n) { return inCat(TBY[n.t]); });
|
||
/* 11-02 按孕周段排:同阶段孕妈的帖子为主、穿插过来人(GC_ORDER 在 feed.js);真实投稿仍排最前;孕周由首页写进 mmbox.gcwk.v1 */
|
||
if (window.GC_ORDER) list = list.filter(function (n) { return n.real; }).concat(window.GC_ORDER(list.filter(function (n) { return !n.real; }), UBAND));
|
||
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'), lastTx = [false, true], txN = [0, 1]; /* 11-02 用户:图上带字的卡至少占 40% → 每列「带字 / 不带字」交替(测试卡算不带字),两列错开一格,带字的在压大字 ov / 贴纸字 tg 间轮换;整体约 45% */
|
||
if (catF === 'ceshi') {
|
||
$('#more').innerHTML = ceshiListHTML(); return;
|
||
}
|
||
/* 「全部」信息流:穿插测试卡 */
|
||
if (!cur && !catF && TM.length) {
|
||
var dn = csDone(), mixed = [], ci = 0;
|
||
/* 测试卡:第 3 位起每 8 张帖子插 1 张(约占 1/9),先出 CS_MIX 精选,再按热度轮完其余测试 */
|
||
var csq = CS_MIX.concat(byHot(TM).map(function (x) { return x.id; }).filter(function (id) { return CS_MIX.indexOf(id) < 0; }));
|
||
list.forEach(function (n, k) { if (k >= 3 && (k - 3) % 8 === 0) { var tid = csq[ci++ % csq.length]; if (TMBY[tid]) mixed.push({ test: TMBY[tid] }); } mixed.push(n); });
|
||
list = [{ mine: 1 }].concat(mixed);
|
||
}
|
||
/* 11-03 用户:切分类有点卡。原来每张卡塞进列里再 offsetHeight 量高,每量一次整页重排;85 张卡在中端机上卡 0.5 秒以上,正好卡在滑入动画中间。
|
||
现在:帖子卡高度直接算(封面 = 列宽 × 比例,底部 = 标题 1/2 行 + 作者行,和 .nc 样式对应),只有「我的投稿 / 收藏 / 测试卡」这几种
|
||
一次性批量量高;整列拼成字符串一次挂上,每列先出前 14 张,其余等滑入动画走完再补;入场动画只给前 12 张。 */
|
||
var tw = cw - 18;
|
||
function txtW(t) { var w = 0; for (var i = 0; i < t.length; i++) w += t.charCodeAt(i) > 255 ? 13.6 : 7.4; return w; }
|
||
function estH(n, r) { return cw * r + 8 + 9 + (txtW(n.title) > tw ? 2 : 1) * 19.6 + 7 + 18; }
|
||
var specials = [];
|
||
list.forEach(function (n) {
|
||
if (n.mine) specials.push(myCardHTML(), favCardHTML());
|
||
else if (n.test) specials.push(testCardHTML(n.test, dn));
|
||
});
|
||
var spH = [];
|
||
if (specials.length) {
|
||
var meas = document.createElement('div');
|
||
meas.className = 'col'; meas.style.cssText = 'position:absolute;left:0;top:0;width:' + cw + 'px;visibility:hidden;pointer-events:none';
|
||
meas.innerHTML = specials.join(''); wf.appendChild(meas);
|
||
[].forEach.call(meas.children, function (el) { spH.push(el.offsetHeight); }); /* 一次重排量完 */
|
||
wf.removeChild(meas);
|
||
}
|
||
var out = [[], []], si = 0, nk = 0, k2 = 0;
|
||
function anim(h, k) { return k >= 12 ? h.replace('class="nc', 'style="animation:none" class="nc') : h.replace('class="nc', 'style="animation-delay:' + Math.min(k, 10) * 30 + 'ms" class="nc'); }
|
||
function add(html, c, h) { out[c].push(anim(html, k2++)); hs[c] += h + 8; }
|
||
list.forEach(function (n) {
|
||
if (n.mine) { add(specials[si], 0, spH[si++]); add(specials[si], 0, spH[si++]); return; }
|
||
if (n.test) { var tc0 = hs[0] <= hs[1] ? 0 : 1; add(specials[si], tc0, spH[si++]); lastTx[tc0] = false; return; }
|
||
nk++;
|
||
var c = hs[0] <= hs[1] ? 0 : 1, sty = !lastTx[c] && n.photo ? (txN[c]++ % 2 ? 'tg' : 'ov') : '';
|
||
lastTx[c] = !!sty;
|
||
var r = n.ratio; if (n.photo && sty === 'ov') r = Math.max(r, 1.33); else if (n.photo && sty === 'tg') r = Math.max(r, 1.2);
|
||
add(cardHTML(n, !cur, sty), c, estH(n, r));
|
||
});
|
||
var FIRST = 14, gen = renderFeed.gen = (renderFeed.gen || 0) + 1;
|
||
cols[0].innerHTML = out[0].slice(0, FIRST).join(''); cols[1].innerHTML = out[1].slice(0, FIRST).join('');
|
||
if (out[0].length > FIRST || out[1].length > FIRST) setTimeout(function () {
|
||
if (gen !== renderFeed.gen) return; /* 期间又切了分类,作废 */
|
||
cols[0].insertAdjacentHTML('beforeend', out[0].slice(FIRST).join('')); cols[1].insertAdjacentHTML('beforeend', out[1].slice(FIRST).join(''));
|
||
}, 450);
|
||
/* 话题下帖子看完,接着引到同分类其他话题,避免以为这块只有这几篇 */
|
||
var mo = $('#more'), tc = cur && TBY[cur];
|
||
if (tc) {
|
||
var rest = NOTES.filter(function (n) { return n.t !== cur && TBY[n.t].cat === tc.cat; }).length;
|
||
mo.innerHTML = '<button type="button" class="mo k-' + tc.cat + '" data-t=""><small>这个话题就这些啦</small><b>「' + CATS.filter(function (c) { return c[0] === tc.cat; })[0][1] + '」还有 ' + rest + ' 篇,去看看 ›</b></button>';
|
||
} else mo.innerHTML = '';
|
||
}
|
||
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'); q.delete('write'); q.delete('fav');
|
||
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;
|
||
if (paneBusy) return;
|
||
var o = catOrder(), d = o.indexOf(b.dataset.c) - o.indexOf(catF);
|
||
if (!d) { catF = b.dataset.c; haptic(); selectTopic(''); return; }
|
||
slideTo(b.dataset.c, d > 0 ? 1 : -1); /* 点标签也滑入,和手势一致 */
|
||
});
|
||
/* 11-02 用户:「广场首页左右滑动,可以切到家庭婚姻、职场、经验」+「突然就滑过去了,要有动效、让人感觉是被划过去的」
|
||
→ 手指横拖时整块内容(#pane)跟手走、顶部胶囊同步往目标分类挪;松手过 22% 屏宽(或甩得快)就整块滑出、换内容、从另一侧滑入;
|
||
不够就弹回。第一个 / 最后一个分类往外拖有阻尼。点分类标签也走同一套滑入。横滑列表、弹层里不触发。 */
|
||
var paneBusy = false;
|
||
function catOrder() { return CATS.map(function (c) { return c[0]; }); }
|
||
function barBetween(a, b, p) { /* 胶囊在 a、b 两个标签间按进度 p 插值 */
|
||
var bar = $('#cats .bar'); if (!bar || !a) return;
|
||
var wa = a.offsetWidth - 20, xa = a.offsetLeft + 10, wb = b ? b.offsetWidth - 20 : wa, xb = b ? b.offsetLeft + 10 : xa;
|
||
bar.style.transition = 'none';
|
||
bar.style.width = (wa + (wb - wa) * p) + 'px'; bar.style.transform = 'translateX(' + (xa + (xb - xa) * p) + 'px)';
|
||
}
|
||
function slideTo(c, dir) { /* dir 1 = 往左滑(去下一个),-1 = 往右滑 */
|
||
var pane = $('#pane'), W = $('#sc').clientWidth;
|
||
paneBusy = true; haptic();
|
||
pane.style.transition = 'transform .2s cubic-bezier(.4,0,1,1),opacity .2s';
|
||
pane.style.transform = 'translateX(' + (-dir * W * .6) + 'px)'; pane.style.opacity = '.15';
|
||
var bar = $('#cats .bar'); if (bar) bar.style.transition = '';
|
||
catF = c; renderCats();
|
||
setTimeout(function () {
|
||
selectTopic('');
|
||
pane.style.transition = 'none'; pane.style.transform = 'translateX(' + (dir * W * .35) + 'px)';
|
||
void pane.offsetWidth;
|
||
pane.style.transition = 'transform .38s cubic-bezier(.2,1.25,.4,1),opacity .25s ease-out';
|
||
pane.style.transform = 'translateX(0)'; pane.style.opacity = '1';
|
||
setTimeout(function () { pane.style.transition = ''; pane.style.transform = ''; pane.style.opacity = ''; paneBusy = false; }, 400);
|
||
}, 200);
|
||
}
|
||
(function () {
|
||
var sx = 0, sy = 0, t0 = 0, mode = '', ok = false, dx = 0, sc = $('#sc'), pane = $('#pane');
|
||
sc.addEventListener('touchstart', function (e) {
|
||
var t = e.touches[0]; sx = t.clientX; sy = t.clientY; t0 = Date.now(); mode = ''; dx = 0;
|
||
ok = !paneBusy && e.touches.length === 1 && !e.target.closest('.tcs,.hot,.cats,.cs-l,#sheet,#note,.nd') && !document.body.classList.contains('lock');
|
||
}, { passive: true });
|
||
sc.addEventListener('touchmove', function (e) {
|
||
if (!ok) return;
|
||
var t = e.touches[0], mx = t.clientX - sx, my = t.clientY - sy;
|
||
if (!mode) {
|
||
if (Math.abs(mx) < 8 && Math.abs(my) < 8) return;
|
||
mode = Math.abs(mx) > Math.abs(my) * 1.2 ? 'h' : 'v';
|
||
if (mode === 'h') pane.style.transition = 'none';
|
||
}
|
||
if (mode !== 'h') return;
|
||
if (e.cancelable) e.preventDefault();
|
||
var order = catOrder(), i = order.indexOf(catF), j = i + (mx < 0 ? 1 : -1), W = sc.clientWidth;
|
||
var has = j >= 0 && j < order.length;
|
||
dx = has ? mx : mx * .28; /* 两头没有下一页:阻尼 */
|
||
pane.style.transform = 'translateX(' + dx + 'px)';
|
||
pane.style.opacity = String(1 - Math.min(.45, Math.abs(dx) / W * .6));
|
||
var bs = $('#cats').querySelectorAll('button[data-c]');
|
||
barBetween(bs[i], has ? bs[j] : null, Math.min(1, Math.abs(dx) / W));
|
||
}, { passive: false });
|
||
sc.addEventListener('touchend', function () {
|
||
if (!ok || mode !== 'h') { ok = false; return; }
|
||
ok = false;
|
||
var order = catOrder(), i = order.indexOf(catF), dir = dx < 0 ? 1 : -1, j = i + dir, W = sc.clientWidth;
|
||
var v = Math.abs(dx) / Math.max(1, Date.now() - t0);
|
||
if (j >= 0 && j < order.length && (Math.abs(dx) > W * .22 || (v > .5 && Math.abs(dx) > 30))) { slideTo(order[j], dir); return; }
|
||
/* 不够:弹回 */
|
||
pane.style.transition = 'transform .35s cubic-bezier(.2,1.3,.4,1),opacity .25s';
|
||
pane.style.transform = 'translateX(0)'; pane.style.opacity = '1';
|
||
var bar = $('#cats .bar'); if (bar) bar.style.transition = ''; moveBar();
|
||
setTimeout(function () { if (!paneBusy) { pane.style.transition = ''; pane.style.transform = ''; pane.style.opacity = ''; } }, 360);
|
||
}, { passive: true });
|
||
sc.addEventListener('touchcancel', function () { if (mode === 'h') { pane.style.transform = ''; pane.style.opacity = ''; moveBar(); } ok = false; }, { passive: true });
|
||
})();
|
||
$('#fh').addEventListener('click', function (e) {
|
||
var tg = e.target.closest('[data-tg]');
|
||
if (tg) { tGrp = tg.dataset.tg; haptic(); ceshiFh($('#fh')); renderFeed(); return; }
|
||
var b = e.target.closest('[data-t]'); if (!b || b.dataset.t === cur) return;
|
||
haptic(); var sl = $('#fh .tcs') ? $('#fh .tcs').scrollLeft : 0;
|
||
selectTopic(b.dataset.t, false);
|
||
var tc = $('#fh .tcs'); if (tc && !b.dataset.t) tc.scrollLeft = sl;
|
||
});
|
||
$('#more').addEventListener('click', function (e) { if (e.target.closest('[data-t]')) { haptic(); selectTopic(''); } });
|
||
$('#head').addEventListener('click', function (e) {
|
||
if (e.target.closest('#qfBanner')) { goQifu(); return; }
|
||
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) {
|
||
var tl = T.filter(function (t) { return t.cat === cat; });
|
||
return '<div class="tl-h">' + kbHTML(cat) + '<small>' + tl.length + ' 个话题</small></div><div class="tl k-' + cat + '">' + tl.map(function (t) {
|
||
return '<button type="button" data-pick="' + t.id + '" class="' + (cur === t.id ? 'on' : '') + '"><span><em>#</em>' + esc(t.name) + '<em>#</em><small>' + cntT(t.id) + ' 篇分享</small></span>' + (t.hot ? '<i>热</i>' : '') + '</button>';
|
||
}).join('') + '</div>';
|
||
};
|
||
openSheet('topics', '<h3>全部 ' + T.length + ' 个话题</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'); }
|
||
});
|
||
}
|
||
$('#more').addEventListener('click', function (e) {
|
||
if (e.target.closest('[data-hot]')) { e.stopPropagation(); haptic(); hotOpen = !hotOpen; var k = $('#more .csk'); if (k) k.outerHTML = hotHTML(csDone()); return; }
|
||
var ts = e.target.closest('[data-test]');
|
||
if (ts) { e.stopPropagation(); haptic(); location.href = ceshiURL(ts.dataset.test, true); }
|
||
}, true);
|
||
$('#wf').addEventListener('click', function (e) {
|
||
if (e.target.closest('[data-mine]')) { haptic(); location.href = mineURL(); return; }
|
||
if (e.target.closest('[data-fav]')) { haptic(); openFav(false); return; }
|
||
var ts = e.target.closest('[data-test]');
|
||
if (ts) { haptic(); location.href = ceshiURL(ts.dataset.test, catF === 'ceshi'); return; }
|
||
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('');
|
||
}
|
||
/* 11-02 用户:自己发的评论也带上孕周(首页写进 mmbox.gcwk.v1;产后显示「宝妈」) */
|
||
function myStage() {
|
||
try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); return !g ? '' : g.pp ? '宝妈' : g.w ? '孕 ' + g.w + ' 周' : ''; } catch (e) { return ''; }
|
||
}
|
||
function commentHTML(c, mine) {
|
||
if (mine) {
|
||
var st = c.s || myStage();
|
||
var mk = c.id && c.st === 'approved' ? 'r:' + c.id : ''; /* 通过了的自己的评论,别人能回复,回复挂在这里 */
|
||
return '<div class="ci mine' + (c.st === 'rejected' ? ' rejected' : '') + '"><span class="me">我</span><div class="ci-b"' + (mk ? ' data-rk="' + mk + '" data-rn="' + esc(MYNAME) + '"' : '') + '><div class="ci-n"><b>' + esc(MYNAME) + '</b><span class="mt">我</span>' + (st ? '<i class="stg">' + esc(st) + '</i>' : '') + '</div>' +
|
||
'<p class="ci-t">' + esc(c.t) + '</p>' + (mk ? '<div class="ci-s"><span class="rpy">回复</span></div>' : '') + stTag(c) + (mk ? rpHTML(extraReplies(openId, mk), mk, MYNAME) : '') + '</div></div>'; /* 11-02 自己的评论也不显示时间 */
|
||
}
|
||
var on = !!ME.cl[c.key], n = c.likes + (on ? 1 : 0);
|
||
var rp = rpHTML(c.r.concat(extraReplies(openId, c.key)), c.key, c.n);
|
||
return '<div class="ci"><img src="' + (c.av || avSrc(c.n)) + '" alt="" loading="lazy"><div class="ci-b" data-rk="' + esc(c.key) + '" data-rn="' + esc(c.n) + '"><div class="ci-n"><b>' + esc(c.n) + '</b>' + (c.s ? '<i class="stg">' + esc(c.s) + '</i>' : '') +
|
||
'<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"><span class="rpy">回复</span></div>' /* 11-02 用户:评论时间先不显示 */ + 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).filter(function (c) { return !c.parent; }).reverse(), cs = commentsOf(n);
|
||
$('#cmh').innerHTML = '评论 <small>共 ' + cmN(n) + ' 条</small>';
|
||
if (!CMD && !n.real && !CMERR) { $('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + '<div class="cm-ld">评论加载中…</div>'; return; }
|
||
/* 别人发的、已审核通过的真实评论排在模拟评论前面 */
|
||
var rl = realCm(n.id).filter(function (c) { return !c.parent; }).map(function (c) { return { key: 'r:' + c.id, n: c.nickname || '孕妈', av: c.avatar || '', s: c.stage, t: c.text, likes: 0, r: [] }; });
|
||
$('#cml').innerHTML = mine.map(function (c) { return commentHTML(c, true); }).join('') + rl.concat(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">' + '<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">' + [n.stage ? esc(n.stage) : '', n.real ? '妈妈投稿' : ''].filter(Boolean).join(' · ') + '</div></div>' /* 11-02 用户:帖子发布日期先隐藏(when 留着,以后恢复直接拼回去) */ +
|
||
'<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); loadRC(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);
|
||
if (fvOn) renderFav(); /* 详情里取消了收藏,回到收藏页要立刻消失 */
|
||
}
|
||
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;
|
||
}
|
||
var rr = e.target.closest('[data-rk]');
|
||
if (rr) { REPLY = { k: rr.dataset.rk, n: rr.dataset.rn }; cin.placeholder = '回复 ' + REPLY.n + ':'; cin.focus(); return; }
|
||
if (e.target.closest('#cmgo')) { REPLY = null; cin.placeholder = '说点什么…'; $('#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] = Date.now(); /* 存收藏时间,「我的收藏」按它倒序 */
|
||
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'); REPLY = null; cin.placeholder = '说点什么…'; } }, 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 || send.busy) return;
|
||
if (!OPENID) { toast('请在小程序里打开后再评论'); return; }
|
||
/* 11-03:评论先交后台审核,通过后才公开;审核中只有自己看得到 */
|
||
send.busy = true; $('#csend').disabled = true;
|
||
fetch(API + '/comment?' + idq(), { method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ kind: 'post', target: n.id, title: n.title, text: v.slice(0, 200), stage: myStage(), parent: REPLY ? REPLY.k : '', parentName: REPLY ? REPLY.n : '' }) })
|
||
.then(function (r) { return r.json(); }).then(function (j) {
|
||
send.busy = false;
|
||
if (!j || j.code !== 200) { $('#csend').disabled = !cin.value.trim(); toast((j && j.message) || '没发出去,稍后再试'); return; }
|
||
var rc = RC[n.id] || (RC[n.id] = { list: [], mine: [] }); rc.mine.unshift(j.result);
|
||
var wasReply = !!REPLY; REPLY = null; cin.placeholder = '说点什么…';
|
||
haptic();
|
||
cin.value = ''; $('#csend').disabled = true; cin.blur(); $('#bar').classList.remove('typing');
|
||
if (openId === n.id) { renderComments(n); syncBar(n); }
|
||
if (!wasReply) { var w = $('#cmw'); if (w) $('#dsc').scrollTo({ top: w.offsetTop - 50, behavior: 'smooth' }); }
|
||
toast(wasReply ? '回复已提交,审核通过后大家就能看到' : '已提交,审核通过后大家就能看到');
|
||
}).catch(function () { send.busy = false; $('#csend').disabled = !cin.value.trim(); 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 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 () {});
|
||
}
|
||
|
||
/* 我的投稿:入口卡在「全部」瀑布流第一位,详情是独立页 mine/ */
|
||
var UNREAD = 0;
|
||
var mineURL = function () { return 'mine/' + location.hash; };
|
||
function myCardHTML() {
|
||
var n = { pending: 0, approved: 0 };
|
||
MINE.forEach(function (p) { if (n[p.status] != null) n[p.status]++; });
|
||
return '<button type="button" class="nc myc" id="myc" data-mine="1">' + (UNREAD ? '<i class="dot">' + UNREAD + ' 条新结果</i>' : '') +
|
||
'<span class="mi"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/></svg></span>' +
|
||
'<b>我的投稿</b>' + (MINE.length ? '<p>已投 ' + MINE.length + ' 篇,看看审核进度</p><div class="ms">' + (n.pending ? '<span>审核中 ' + n.pending + '</span>' : '') + (n.approved ? '<span>已通过 ' + n.approved + '</span>' : '') + '</div>'
|
||
: '<p>写下你的故事,被选中得 <em>¥30</em> + <em>500</em> 兜豆</p>') +
|
||
'<span class="go">' + (MINE.length ? '查看全部' : '去看看') + '<svg class="ic"><use href="#i-right"/></svg></span></button>';
|
||
}
|
||
function favIds() {
|
||
return Object.keys(ME.fav).filter(function (id) { return NBY[id]; }).sort(function (a, b) { return (+ME.fav[b] || 0) - (+ME.fav[a] || 0); });
|
||
}
|
||
function favCardHTML() {
|
||
var k = favIds().length;
|
||
return '<button type="button" class="nc fvc" id="fvc" data-fav="1"><i class="fi"><svg class="ic"><use href="#i-star-f"/></svg></i><span>我的收藏<small>' + (k ? '已收藏 ' + k + ' 篇' : '看到喜欢的点 ☆ 收藏') + '</small></span><svg class="ic"><use href="#i-right"/></svg></button>';
|
||
}
|
||
var fvOn = false, fvDeep = false;
|
||
function renderFav() {
|
||
var ids = favIds(), cols = $('#fvw').children, hs = [0, 0], tmp = document.createElement('div');
|
||
cols[0].innerHTML = ''; cols[1].innerHTML = '';
|
||
$('#fvh').textContent = ids.length ? '共 ' + ids.length + ' 篇 · 只保存在这台手机上' : '';
|
||
var em = $('#fvs .fve'); if (em) em.remove();
|
||
if (!ids.length) { $('#fvw').insertAdjacentHTML('beforebegin', '<div class="fve"><b>还没有收藏</b>看到有用的帖子,点底部的 ☆ 就能收藏到这里</div>'); return; }
|
||
$('#fvw').style.setProperty('--cw', (cols[0].clientWidth || 175) + 'px');
|
||
ids.forEach(function (id, k) {
|
||
tmp.innerHTML = cardHTML(NBY[id], false, ''); 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 openFav(deep) {
|
||
fvOn = true; fvDeep = !!deep;
|
||
var p = $('#fvp'); p.classList.add('show'); p.setAttribute('aria-hidden', 'false'); $('#fvs').scrollTop = 0;
|
||
renderFav();
|
||
}
|
||
function closeFav() {
|
||
/* 从首页「我的 → 我的收藏」直接进来的,返回就回首页 */
|
||
if (fvDeep && history.length > 1 && document.referrer && document.referrer.indexOf('/guangchang/') < 0) { history.back(); return; }
|
||
fvOn = false; var p = $('#fvp'); p.classList.remove('show'); p.setAttribute('aria-hidden', 'true');
|
||
var c = $('#fvc'); if (c) c.outerHTML = favCardHTML();
|
||
history.replaceState(history.state, '', setQuery(cur, ''));
|
||
}
|
||
$('#fvBack').addEventListener('click', closeFav);
|
||
$('#fvw').addEventListener('click', function (e) {
|
||
var lk = e.target.closest('[data-like]'); if (lk) { toggleLike(lk.dataset.like); syncCardLike(lk.dataset.like); return; }
|
||
var c = e.target.closest('[data-id]'); if (c) { haptic(); openNote(c.dataset.id, true); }
|
||
});
|
||
function syncMyCard() { var c = $('#myc'); if (c) { c.outerHTML = myCardHTML(); } }
|
||
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 || [];
|
||
UNREAD = un.length; syncMyCard();
|
||
if (cb) cb(); else if (un.length) showResults(un);
|
||
}).catch(function () {});
|
||
}
|
||
|
||
/* 审核结果弹窗:逐条弹,全部看完一次性 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 () {});
|
||
UNREAD = 0; syncMyCard();
|
||
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 () {
|
||
/* 11-02 用户:「从首页点热门话题进来,左上角返回要回孕妈广场,不是首页」→ 在话题里先退回广场「全部」,再按一次才回首页 */
|
||
if (cur) { haptic(); catF = ''; selectTopic(''); return; }
|
||
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();
|
||
});
|
||
|
||
/* ---------- 底部 Tab:孕妈广场 / 记一下 / 返回兜爸(11-03 用户:「就跟数胎动一样」) ---------- */
|
||
$('#tabPlaza').addEventListener('click', function () { /* 再点一次:回到顶部;在话题里就退回「全部」 */
|
||
haptic();
|
||
if (cur || catF) { catF = ''; selectTopic(''); }
|
||
$('#sc').scrollTo({ top: 0, behavior: 'smooth' });
|
||
});
|
||
$('#tabHome').addEventListener('click', function () { haptic(); location.href = homeURL(); }); /* 广场就在首页仓里,直接回 ../ 带身份,不走 goHome */
|
||
/* 记一下:和首页「记一下」同一份数据 —— 后台 App 表已上架、category=孕期工具(首页 loadPublishedApps 同规则);
|
||
数胎动 16 / 数宫缩 20 / 胎儿估重 15 周前灰掉、点了提示(同首页 STAGE_GATE,孕周取首页写的 mmbox.gcwk.v1,拿不准不拦) */
|
||
var REC_GATE = { taidong: [16, '数胎动'], gongsuopinlv: [20, '数宫缩'], taierguzhong: [15, '胎儿估重'] }, recApps = null;
|
||
var myWeek = (function () { try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); return g && !g.pp && g.w ? +g.w : 0; } catch (e) { return 0; } })();
|
||
function recLocked(a) { var g = REC_GATE[a.identifier]; return g && myWeek && myWeek < g[0] ? g : null; }
|
||
function recHTML() {
|
||
if (!recApps) return '<div class="rec-empty">加载中…</div>';
|
||
if (!recApps.length) return '<div class="rec-empty">暂时没取到工具,稍后再试</div>';
|
||
var ok = recApps.filter(function (a) { return !recLocked(a); }), lk = recApps.filter(recLocked); /* 没开放的排到后面(同首页) */
|
||
return ok.concat(lk).map(function (a) {
|
||
var g = recLocked(a), nm = a.name || a.identifier || '工具', ic = a.logo || a.icon;
|
||
return '<button type="button" class="rec-app' + (g ? ' off' : '') + '" data-rid="' + esc(a.identifier || '') + '">' +
|
||
(ic ? '<img src="' + esc(ic) + '" alt="">' : '<b class="rl">' + esc(nm.slice(0, 1)) + '</b>') +
|
||
'<span>' + esc(nm) + '</span>' + (g ? '<i>孕' + g[0] + '周开放</i>' : '') + '</button>';
|
||
}).join('');
|
||
}
|
||
function loadRec() {
|
||
if (recApps || loadRec.busy) return; loadRec.busy = true;
|
||
fetch('/api/mp/apps?isPublished=1&pageSize=200').then(function (r) { return r.ok ? r.json() : null; }).then(function (d) {
|
||
recApps = ((d && d.result && d.result.items) || []).filter(function (a) { return a.url && a.category === '孕期工具'; })
|
||
.sort(function (x, y) { return (y.seq || 0) - (x.seq || 0) || (y.no || 0) - (x.no || 0); });
|
||
}).catch(function () { recApps = []; }).then(function () {
|
||
loadRec.busy = false;
|
||
var g = $('#recApps'); if (g && sheetOn === 'rec') g.innerHTML = recHTML();
|
||
});
|
||
}
|
||
$('#tabRec').addEventListener('click', function () {
|
||
haptic(); loadRec();
|
||
openSheet('rec', '<div class="rec-h"><b>记一下</b><span>兜爸心选的孕期工具</span><button type="button" class="rec-x" data-recx aria-label="关闭"><svg class="ic"><use href="#i-x"/></svg></button></div>' +
|
||
'<div class="rec-apps" id="recApps">' + recHTML() + '</div>');
|
||
});
|
||
$('#sbd').addEventListener('click', function (e) {
|
||
if (sheetOn !== 'rec') return;
|
||
if (e.target.closest('[data-recx]')) { closeSheet(); return; }
|
||
var b = e.target.closest('[data-rid]'); if (!b || !recApps) return;
|
||
var a = recApps.filter(function (x) { return (x.identifier || '') === b.dataset.rid; })[0]; if (!a) return;
|
||
var g = recLocked(a);
|
||
if (g) { haptic(); toast(g[1] + '孕 ' + g[0] + ' 周以后开放,你现在孕 ' + myWeek + ' 周,还用不到哦'); return; }
|
||
goApp(a.url);
|
||
});
|
||
/* 返回兜爸的头像:同数胎动 —— 跨应用 user-center/info 有真头像才换上(商城默认头像 /uploads/system/ 当没有),没有就留小房子 */
|
||
if (OPENID && window.fetch) fetch('/api/mp/public/user-center/info?openid=' + encodeURIComponent(OPENID)).then(function (r) { return r.ok ? r.json() : null; }).then(function (d) {
|
||
var av = d && d.result && d.result.data && d.result.data.avatar;
|
||
if (!av || /\/uploads\/system\//.test(av)) return;
|
||
var ico = $('#tabAv'), im = new Image(); im.className = 'tab-avimg'; im.alt = '';
|
||
im.onload = function () { ico.appendChild(im); ico.insertAdjacentHTML('beforeend', '<i class="tab-hm" aria-hidden="true"><svg viewBox="0 0 24 24" fill="#fff"><path d="M12 4 3.5 11H6v8.5h4.5v-5h3v5H18V11h2.5z"/></svg></i>'); ico.classList.add('has-av'); };
|
||
im.src = av;
|
||
}).catch(function () {});
|
||
|
||
/* ---------- 吸顶阴影 ---------- */
|
||
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'), q0 = new URLSearchParams(location.search); /* 先读:selectTopic 会 replaceState 把 n 去掉 */
|
||
var c0 = new URLSearchParams(location.search).get('c');
|
||
if (CAT_ORDER.indexOf(c0) >= 0 || c0 === 'ceshi') catF = c0;
|
||
selectTopic(param('t') && TBY[param('t')] ? param('t') : '', false);
|
||
if (deep && NBY[deep]) openNote(deep, false);
|
||
loadApproved();
|
||
if (q0.get('fav') === '1') openFav(true); /* 首页「我的 → 我的收藏」 */
|
||
if (q0.get('mine') === '1') location.href = mineURL(); /* 首页审核提醒 ?mine=1 → 我的投稿页(selectTopic 已把 mine 从地址里去掉,返回不会再跳) */
|
||
else if (q0.get('write') === '1') { loadMine(function () {}); openCompose(q0.get('t') || ''); } /* 我的投稿页「写新的故事 / 修改后重投」:结果在那页已看过,不再弹 */
|
||
else loadMine(); /* 我的投稿页「写新的故事 / 修改后重投」 */
|
||
var rt; window.addEventListener('resize', function () { clearTimeout(rt); rt = setTimeout(renderFeed, 150); });
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|