2566 lines
225 KiB
HTML
2566 lines
225 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
|
||
<script src="../js/login-gate.js?v=26110610"></script>
|
||
<script src="../js/ugc.js?v=26110464" data-guard></script>
|
||
<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;touch-action:pan-y;-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)}
|
||
/* 11-07 置顶笔记「孕妈悄悄话」(用户:首页不放,在广场内容里发一条置顶笔记,点了进星空页):
|
||
右列第一张,样子是一张笔记卡 —— 封面换成夜空(星星一闪一闪 + 偶尔一道流星)+ 本周话题大字 + 一句轮播的悄悄话 */
|
||
.nc.pin .pcv,.dcv .pcv{position:relative;height:calc(var(--cw, 175px) * 1.25);overflow:hidden;color:#fff;
|
||
background:radial-gradient(120% 70% at 85% 0%,#5A3B72 0%,transparent 60%),radial-gradient(90% 60% at 0% 100%,#4A2C55 0%,transparent 70%),linear-gradient(180deg,#191634 0%,#241D44 55%,#2F2148 100%)}
|
||
.pcv .psk{position:absolute;inset:0;pointer-events:none}
|
||
.pcv .psk i{position:absolute;width:6px;height:6px;margin:-3px 0 0 -3px;opacity:.85;filter:drop-shadow(0 0 2px rgba(255,255,255,.7));
|
||
background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 .5C10.9 7.4 12.6 9.1 19.5 10 12.6 10.9 10.9 12.6 10 19.5 9.1 12.6 7.4 10.9.5 10 7.4 9.1 9.1 7.4 10 .5Z' fill='%23FFFFFF'/%3E%3C/svg%3E") center/contain no-repeat;animation:pTw 2.6s ease-in-out infinite}
|
||
.pcv .psk i.b{width:11px;height:11px;margin:-5.5px 0 0 -5.5px;opacity:1;filter:drop-shadow(0 0 4px rgba(255,255,255,.9))}
|
||
@keyframes pTw{0%,100%{opacity:.9;transform:scale(1)}50%{opacity:.2;transform:scale(.55)}}
|
||
.pcv .pmt{position:absolute;top:8%;left:78%;width:80px;height:2px;border-radius:2px;opacity:0;transform-origin:0 50%;
|
||
background:linear-gradient(90deg,#fff,rgba(255,255,255,.7) 30%,rgba(255,255,255,0));box-shadow:0 0 8px 1px rgba(255,255,255,.8);animation:pMt 6s linear infinite 1.2s}
|
||
.pcv .pmt::before{content:"";position:absolute;left:-2px;top:-1.5px;width:5px;height:5px;border-radius:50%;background:#fff;box-shadow:0 0 6px 2px #fff}
|
||
.pcv .pmt.m2{top:30%;left:96%;width:60px;animation-duration:9s;animation-delay:4.2s}
|
||
@keyframes pMt{0%{opacity:0;transform:translate(0,0) rotate(-28deg)}2%{opacity:1}12%{opacity:0;transform:translate(-130px,70px) rotate(-28deg)}100%{opacity:0;transform:translate(-130px,70px) rotate(-28deg)}}
|
||
@media (prefers-reduced-motion:reduce){.pcv .psk i,.pcv .pmt{animation:none}}
|
||
.pcv .ptop{position:absolute;left:8px;top:8px;z-index:1;height:19px;padding:0 7px;border-radius:6px;background:linear-gradient(120deg,#FFE2B8,#FFB98F);color:#4A2E1E;font-size:10.5px;font-style:normal;font-weight:900;line-height:19px;letter-spacing:.5px}
|
||
.pcv .pbig{position:absolute;left:12px;right:12px;bottom:40px;z-index:1}
|
||
.pcv .pbig small{display:block;font-size:10.5px;font-weight:700;letter-spacing:1px;color:rgba(255,231,199,.75)}
|
||
.pcv .pbig b{display:block;margin-top:4px;font-size:20px;font-weight:900;line-height:1.3;letter-spacing:.5px;color:#FFE7C7;text-shadow:0 2px 10px rgba(20,10,40,.6)}
|
||
.pcv .pq{position:absolute;left:12px;right:12px;bottom:12px;z-index:1;margin:0;font-size:11.5px;color:rgba(255,244,232,.8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:opacity .26s,transform .26s}
|
||
.pcv .pq.out{opacity:0;transform:translateY(5px)}
|
||
.nb .ntg.k-whs{background:#F0EBFA;color:#7A5BB8}
|
||
.nc.pin .nf .pav{flex:none;display:grid;place-items:center;width:18px;height:18px;border-radius:50%;background:linear-gradient(135deg,#3E2F5E,#6B4AA8);color:#FFE2B8;font-size:10px;font-style:normal}
|
||
/* 置顶笔记详情页:夜空封面 + 「去星空看看」;不要点赞/收藏/关注(这篇是官方置顶,不是某个妈妈的帖子) */
|
||
.dcv .pcv{height:min(78vw,340px)}
|
||
.dcv .pcv .pbig{bottom:auto;top:30%}
|
||
.dcv .pcv .pbig small{font-size:12px}
|
||
.dcv .pcv .pbig b{font-size:28px}
|
||
.dcv .pcv .pq{bottom:64px;font-size:13px}
|
||
.dcv .pcv .ptop{left:14px;top:14px}
|
||
.pstar{position:absolute;left:14px;bottom:16px;z-index:2;display:inline-flex;align-items:center;gap:4px;height:36px;padding:0 16px;border:0;border-radius:99px;font:inherit;font-size:14px;font-weight:800;color:#4A2E1E;background:linear-gradient(120deg,#FFE2B8,#FFB98F);box-shadow:0 6px 16px -6px rgba(255,185,143,.8)}
|
||
.pstar:active{transform:scale(.97)}
|
||
#dt.is-pin #blk,#dt.is-pin #bfv,#dt.is-pin #dfo{display:none}
|
||
.nc.pin .nf .pgo{margin-left:auto;flex:none;font-size:11px;font-weight:800;color:#7A5BB8}
|
||
.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,.rww .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,.rww .rwl .ic{flex:none;width:16px;height:16px;color:#F2553A}
|
||
.htl .rwl span,.rww .rwl span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.htl .rwl em,.rww .rwl em{font-style:normal;color:#F2394A;font-weight:900}
|
||
.htl .rwl b,.rww .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 14px}
|
||
/* 11-03 测试列表 · 参考图排版(分组标题 + 宫格卡) */
|
||
.cst{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;padding:12px 14px 0}
|
||
.cst button{height:34px;border-radius:10px;background:#fff;border:1px solid #F0E6EE;box-shadow:0 2px 6px rgba(150,110,140,.06);font-size:13px;font-weight:700;color:#5A4C58;white-space:nowrap}
|
||
.cst button.on{background:linear-gradient(135deg,#EFEAFF,#E6F0FF);border-color:#D9D0FA;color:#4F45B5;font-weight:900}
|
||
.csg{margin-top:22px}
|
||
/* 11-04 测试列表「热闹」:实时在测 + 战报 + 手气测 + 卡片在测 / TOP / 弹入 / 扫光 */
|
||
.luck-fl{position:fixed;left:50%;top:64px;z-index:60;display:flex;align-items:center;gap:8px;height:44px;padding:0 6px 0 8px;border-radius:99px;color:#fff;
|
||
background:linear-gradient(120deg,#7B5CF5,#A17BFF 60%,#FF8FB1);box-shadow:0 10px 22px -8px rgba(123,92,245,.75);transform:translate(-50%,-14px) scale(.9);opacity:0;pointer-events:none;transition:transform .3s cubic-bezier(.3,1.4,.5,1),opacity .2s;white-space:nowrap}
|
||
.luck-fl.on{transform:translate(-50%,0);opacity:1;pointer-events:auto}
|
||
.luck-fl-d{width:30px;height:30px;animation:lkIdle 3.2s ease-in-out infinite}.luck-fl-d svg{width:100%;height:100%;display:block}
|
||
.luck-fl b{font-size:14px;font-weight:800}
|
||
.luck-fl em{height:32px;padding:0 14px;border-radius:99px;background:#fff;color:#6A4BE0;font-size:13.5px;font-style:normal;font-weight:900;line-height:32px;animation:lkPulse 1.8s ease-in-out infinite}
|
||
.luck{position:relative;display:flex;align-items:center;gap:10px;width:calc(100% - 24px);margin:12px 12px 0;padding:14px 12px 14px 14px;border-radius:20px;text-align:left;color:#fff;
|
||
background:radial-gradient(circle at 88% 0,rgba(255,255,255,.28) 0 38px,transparent 39px),radial-gradient(circle at 6% 120%,rgba(255,201,77,.45) 0 46px,transparent 47px),linear-gradient(120deg,#7B5CF5,#A17BFF 55%,#FF8FB1);box-shadow:0 10px 22px -10px rgba(123,92,245,.7);overflow:visible}
|
||
.luck-dc{flex:none;width:46px;height:46px;filter:drop-shadow(0 4px 6px rgba(60,30,140,.35));animation:lkIdle 3.2s ease-in-out infinite;transform-origin:50% 60%}
|
||
.luck-dc svg{width:100%;height:100%;display:block}
|
||
.luck-dc.d2{position:absolute;left:44px;top:6px;width:24px;height:24px;animation-delay:.4s}
|
||
@keyframes lkIdle{0%,72%,100%{transform:rotate(0)}78%{transform:rotate(-14deg) translateY(-3px)}86%{transform:rotate(10deg) translateY(-1px)}93%{transform:rotate(-4deg)}}
|
||
.luck.roll .luck-dc{animation:lkTumble .35s linear infinite}
|
||
.luck.roll .luck-dc.d2{animation-duration:.28s}
|
||
@keyframes lkTumble{0%{transform:rotate(0) translateY(0)}25%{transform:rotate(90deg) translateY(-6px)}50%{transform:rotate(180deg) translateY(0)}75%{transform:rotate(270deg) translateY(-4px)}100%{transform:rotate(360deg)}}
|
||
.luck.hit .luck-dc{animation:lkLand .5s cubic-bezier(.3,1.6,.5,1)}
|
||
@keyframes lkLand{from{transform:scale(1.3) rotate(-20deg)}to{transform:none}}
|
||
.luck-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px;padding-left:4px}
|
||
.luck-t>b{font-size:16.5px;font-weight:900;letter-spacing:.3px;text-shadow:0 1px 2px rgba(60,30,140,.25)}
|
||
.luck-w{display:block;height:22px;line-height:22px;padding:0 9px;border-radius:8px;background:rgba(255,255,255,.22);font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.luck-w .sp{display:inline-block;animation:lkSp .09s linear}
|
||
@keyframes lkSp{from{transform:translateY(-70%);opacity:.3}}
|
||
.luck-w .hit{display:inline-block;color:#FFE27A;font-weight:900;animation:lkLand .45s cubic-bezier(.3,1.6,.5,1)}
|
||
.luck-b{flex:none;height:34px;padding:0 14px;border-radius:99px;background:#fff;color:#6A4BE0;font-size:14px;font-style:normal;font-weight:900;line-height:34px;box-shadow:0 4px 10px -4px rgba(60,30,140,.5);animation:lkPulse 1.8s ease-in-out infinite}
|
||
@keyframes lkPulse{50%{transform:scale(1.07)}}
|
||
.luck.roll .luck-b,.luck.hit .luck-b{animation:none;opacity:.6}
|
||
.luck:active{transform:scale(.985)}
|
||
.luck-fx{position:absolute;left:50%;top:50%;pointer-events:none}
|
||
.luck-fx i{position:absolute;width:7px;height:7px;border-radius:2px;animation:lkBoom .9s ease-out forwards}
|
||
@keyframes lkBoom{from{transform:translate(0,0) scale(1);opacity:1}to{transform:translate(var(--x),var(--y)) rotate(200deg) scale(.4);opacity:0}}
|
||
.csv{display:grid;grid-template-columns:1fr;gap:6px;margin:10px 12px 0;padding:10px 12px;border-radius:16px;background:linear-gradient(135deg,#FFF1EA,#FFF7F0 60%,#F6F0FF);box-shadow:0 4px 14px -8px rgba(240,112,79,.35)}
|
||
.csv-n{font-size:13px;font-weight:700;color:#6E5A55;display:flex;align-items:center;gap:6px}
|
||
.csv-n b{font-size:17px;font-weight:900;color:#F0453A;display:inline-block}
|
||
.csv-n b.bp{animation:csvBp .5s ease}
|
||
@keyframes csvBp{40%{transform:translateY(-2px) scale(1.08)}}
|
||
.csv-dot{width:8px;height:8px;border-radius:50%;background:#F0453A;box-shadow:0 0 0 0 rgba(240,69,58,.5);animation:csvDot 1.4s ease-out infinite}
|
||
@keyframes csvDot{70%{box-shadow:0 0 0 7px rgba(240,69,58,0)}100%{box-shadow:0 0 0 0 rgba(240,69,58,0)}}
|
||
.csv-r{grid-column:1/-1;position:relative;height:24px;overflow:hidden}
|
||
.csv-i{position:absolute;inset:0;display:flex;align-items:center;gap:6px;width:100%;font-size:12.5px;color:#7A6863;text-align:left;opacity:0;transform:translateY(100%);transition:transform .45s ease,opacity .45s ease}
|
||
.csv-i.on{opacity:1;transform:none}.csv-i.up{opacity:0;transform:translateY(-100%)}
|
||
.csv-i img{flex:none;width:20px;height:20px;border-radius:50%;object-fit:cover;border:1.5px solid #fff;background:#FFE3D3}
|
||
.csv-i span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.csv-i em{font-style:normal;font-weight:800;color:#3A2A26;margin-right:4px}
|
||
.csv-i b{font-weight:800;color:#8D6BFF}
|
||
.csv-i small{flex:none;font-size:11px;color:#B5A39C}
|
||
.ck .cv .ck-top{position:absolute;right:0;top:0;z-index:1;height:20px;padding:0 8px 0 9px;border-radius:0 0 0 12px;color:#fff;font-size:10.5px;font-style:italic;font-weight:900;line-height:20px;letter-spacing:.3px}
|
||
.ck-top.t1{background:linear-gradient(135deg,#F0453A,#FF8A3D)}.ck-top.t2{background:linear-gradient(135deg,#FF8A2E,#FFC06E)}.ck-top.t3{background:linear-gradient(135deg,#8D6BFF,#B9A3FF)}
|
||
.ck .cv em{position:relative;overflow:hidden}
|
||
.ck .cv em::after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:40%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.55),transparent);transform:skewX(-18deg);animation:ckShine 3.6s ease-in-out infinite}
|
||
@keyframes ckShine{0%,62%{left:-60%}88%,100%{left:130%}}
|
||
.pre{opacity:0}
|
||
.pre.pop-in{animation:ckPop .5s cubic-bezier(.3,1.35,.5,1) both}
|
||
@keyframes ckPop{from{opacity:0;transform:translateY(14px) scale(.96)}to{opacity:1;transform:none}}
|
||
@media (prefers-reduced-motion:reduce){.luck-dc,.luck-b{animation:none}.pre{opacity:1}.pre.pop-in,.ck .cv em::after,.csv-dot{animation:none}}
|
||
.csg-h{display:flex;flex-direction:column;gap:5px;padding:0 2px}
|
||
.csg-h b{display:flex;align-items:center;gap:6px;padding-left:10px;border-left:3px solid #B9B3D6;font-size:19px;font-weight:900;line-height:1.1;color:#2B2433}
|
||
.csg-h b i{font-style:normal;font-size:18px}
|
||
.csg-h b{border-left:0;padding-left:0}
|
||
.csg-h small{padding-left:32px}
|
||
.csg-ic{display:grid;place-items:center;width:26px;height:26px;border-radius:8px;background:var(--gi)}
|
||
.csg-ic svg{width:16px;height:16px}
|
||
.csg.g-quiz{--gi:#FF8A65}.csg.g-psy{--gi:#9A7FE0}.csg.g-game{--gi:#3FAE7A}.csg.g-shop{--gi:#4E8DE6}
|
||
.csr.gq,.ck.gq{--c1:#FFF4EA;--c2:#FFE3D3;--c3:#FFC9AE;--c4:#FFB08F;--cb:#FF8A65}
|
||
.csr.gp,.ck.gp{--c1:#F6F1FF;--c2:#EAE2FB;--c3:#CDBEF5;--c4:#DCCFF7;--cb:#9A7FE0}
|
||
.csr.gg,.ck.gg{--c1:#F0FAF4;--c2:#DDF3E7;--c3:#B5E5CB;--c4:#C6EBD6;--cb:#3FAE7A}
|
||
.csr.gs,.ck.gs{--c1:#F0F6FF;--c2:#DFEBFD;--c3:#BCD5FA;--c4:#CCDFFB;--cb:#4E8DE6}
|
||
.csg-h b{border-left:0}
|
||
.csrl{display:flex;flex-direction:column;gap:9px;margin-top:12px}
|
||
.csr{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;border-radius:14px;background:#fff;box-shadow:0 3px 10px -4px rgba(120,90,130,.14);text-align:left}
|
||
.csr:active{transform:scale(.98)}
|
||
.csr-i{flex:none;display:grid;place-items:center;width:40px;height:40px;border-radius:11px;background:var(--cb)}
|
||
.csr-i svg{width:20px;height:20px}
|
||
.csr-m{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
|
||
.csr-m b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:14px;font-weight:800;line-height:1.4;color:#2B2433}
|
||
.csr-m small{font-size:11px;color:#8D8091}
|
||
.csr-m small i{margin-left:8px;font-style:normal;font-weight:800;color:#F0704F}
|
||
.csr em{flex:none;height:26px;padding:0 12px;border-radius:99px;background:var(--cb);color:#fff;font-size:12px;font-style:normal;font-weight:800;line-height:26px}
|
||
.csg-h small{padding-left:13px;font-size:13px;color:#8F8494}
|
||
.ckg{display:grid;gap:12px 10px;margin-top:12px}
|
||
.ckg.c3{grid-template-columns:repeat(3,1fr)}
|
||
.ckg.c2{grid-template-columns:repeat(2,1fr)}
|
||
.ck{display:flex;flex-direction:column;min-width:0;border-radius:16px;background:#fff;box-shadow:0 4px 14px -4px rgba(120,90,130,.16);overflow:hidden;text-align:center}
|
||
.ck:active{transform:scale(.97)}
|
||
.ck .cv{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;height:128px;padding:0 6px;background:linear-gradient(160deg,var(--c1),var(--c2));overflow:hidden}
|
||
.c2 .ck .cv{height:150px;gap:7px}
|
||
.ck .cbl{position:absolute;inset:0;width:100%;height:100%}
|
||
.ck .cbl .b1{fill:var(--c3);opacity:.75}.ck .cbl .b2{fill:var(--c4);opacity:.6}.ck .cbl .b3{fill:#fff;opacity:.35}
|
||
.ck .cv b,.ck .cv small,.ck .cv em{position:relative}
|
||
.ck .cv b{font-size:16.5px;font-weight:900;line-height:1.2;color:#2B2433;letter-spacing:.5px}
|
||
.c2 .ck .cv b{font-size:20px;padding:0 8px}
|
||
.ck .cv b{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;padding:0 2px;font-size:13.5px;line-height:1.35;letter-spacing:0}
|
||
.c2 .ck .cv b{font-size:15.5px;padding:0 6px}
|
||
.ck .cv{height:146px}
|
||
.c2 .ck .cv{height:160px}
|
||
#more .ck .cv{padding-top:14px;height:160px}#more .c2 .ck .cv{height:172px}
|
||
#more .ck .cv b{font-size:15.5px;line-height:1.32}
|
||
#more .c2 .ck .cv{height:206px}
|
||
/* 11-04 二改(用户:「下面的呈现太大了,跟首页孕期百宝箱下面往外滚的一样:一个头像、一个人名和一小行字」)→ 两行白条改成一行 20px 小滚动条 */
|
||
#more .c2 .ck .cv:has(.ck-hl){padding-bottom:22px}
|
||
.ck .cv .ck-hl{position:absolute;left:7px;right:7px;bottom:7px;height:22px;padding:0 8px 0 3px;border-radius:99px;background:rgba(255,255,255,.78);overflow:hidden;text-align:left}
|
||
.ck-hl .hl-i{left:3px!important;right:8px!important;top:1px!important}
|
||
.ck-hl .hl-i{position:absolute;left:0;right:0;top:0;display:flex;align-items:center;gap:4px;height:20px;font-size:11px;color:var(--cb);white-space:nowrap;opacity:0;transform:translateY(100%);transition:transform .45s ease,opacity .45s ease}
|
||
.ck-hl .hl-i.on{opacity:1;transform:none}.ck-hl .hl-i.up{opacity:0;transform:translateY(-100%)}
|
||
.ck-hl .hl-i img{flex:none;width:16px;height:16px;border-radius:50%;object-fit:cover;background:#fff}
|
||
.ck-hl .hl-i u{flex:none;text-decoration:none;font-weight:800;color:#4A3E50}
|
||
.ck-hl .hl-i span{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
||
@media (prefers-reduced-motion:reduce){.ck-hl .hl-i{transition:none}}
|
||
#more .c2 .ck .cv b{font-size:17px;padding:0 4px}
|
||
.ck .cnn{margin-top:8px}
|
||
.ck .cv small{font-size:10.5px;color:#8D8091;white-space:nowrap}
|
||
.ck .cv em{margin-top:2px;height:22px;padding:0 10px;border-radius:6px;background:var(--cb);color:#fff;font-size:11px;font-style:normal;font-weight:800;line-height:22px;box-shadow:0 3px 8px -3px var(--cb)}
|
||
.c2 .ck .cv em{height:25px;line-height:25px;padding:0 13px;font-size:12px}
|
||
.ck .cv .dn{position:absolute;right:6px;top:6px;height:17px;padding:0 6px;border-radius:99px;background:rgba(255,255,255,.88);color:var(--cb);font-size:10px;font-style:normal;font-weight:800;line-height:17px}
|
||
.ck .ct{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin:8px 8px 0;min-height:2.8em;font-size:12.5px;font-weight:700;line-height:1.4;color:#3A3040}
|
||
.c2 .ck .ct{font-size:13.5px}
|
||
.ck .cnn{display:inline-flex;align-items:center;justify-content:center;gap:2px;margin:4px 0 9px;font-size:11px;font-weight:800;color:#F0704F}
|
||
/* 11-04 用户:「背景太单一、行图标都一样、加头像、整体 UI 太单一」→ 每组一块分组色底板(带淡图案 + 大号分组水印),行图标按测试各不相同、底色三档深浅,卡片 / 行 / 组标题都挂头像堆 */
|
||
.csg{position:relative;margin:22px -4px 0;padding:16px 10px 14px;border-radius:22px;background:var(--gb);overflow:hidden}
|
||
.csg::before{content:"";position:absolute;inset:0;background-image:radial-gradient(var(--gd) 1.2px,transparent 1.4px);background-size:16px 16px;opacity:.55;pointer-events:none}
|
||
.csg>*{position:relative}
|
||
.csg.g-quiz{--gb:linear-gradient(170deg,#FFEDE2,#FFF6F0 40%,#FFF1E8);--gd:#FFD2BC}
|
||
.csg.g-psy{--gb:linear-gradient(170deg,#EFE8FF,#F8F5FF 40%,#F1EBFF);--gd:#DCCFF7}
|
||
.csg.g-game{--gb:linear-gradient(170deg,#E2F6EA,#F3FBF6 40%,#E6F7EE);--gd:#BFE7D0}
|
||
.csg.g-shop{--gb:linear-gradient(170deg,#E3EEFF,#F4F8FF 40%,#E8F1FF);--gd:#C7DBFA}
|
||
.csg>.csg-deco{position:absolute;right:-14px;top:-18px;width:96px;height:96px;border-radius:30px;background:var(--gi);opacity:.13;transform:rotate(14deg);display:grid;place-items:center}
|
||
.csg>.csg-deco svg{width:64px;height:64px}
|
||
.csg-h b{flex-wrap:wrap}
|
||
.csg-n{display:inline-flex;align-items:center;gap:4px;margin-left:auto;height:24px;padding:0 9px 0 4px;border-radius:99px;background:rgba(255,255,255,.75);font-size:11px;font-weight:800;color:var(--gi)}
|
||
.csg-n .cav img{width:18px;height:18px}
|
||
.cav{display:inline-flex;align-items:center;vertical-align:middle}
|
||
.cav img{width:16px;height:16px;border-radius:50%;object-fit:cover;border:1.5px solid #fff;background:#FFE3D3;margin-left:-5px}
|
||
.cav img:first-child{margin-left:0}
|
||
.ck .cnn .cav{margin-right:5px}
|
||
.csr-m small .cav{margin-left:8px}.csr-m small .cav+i{margin-left:4px}
|
||
.csr-i.s1{background:linear-gradient(135deg,var(--cb),var(--c4))}
|
||
.csr-i.s2{background:var(--c1);box-shadow:inset 0 0 0 1.5px var(--c3)}
|
||
.csr-i.s2 svg{fill:var(--cb)}.csr-i.s2 svg [fill="#fff"]{fill:var(--cb)}.csr-i.s2 svg [stroke="#fff"]{stroke:var(--cb)}
|
||
.csr-i svg{width:22px;height:22px}
|
||
.csr-i{border-radius:13px;transform:rotate(-4deg)}
|
||
.csr:nth-child(even) .csr-i{transform:rotate(4deg)}
|
||
.ck.has-bg .cv>.cbl,.ck.has-bg .cv>.ck-wm{display:none}
|
||
.ck .cv .ck-wash{position:absolute;inset:0;pointer-events:none}
|
||
.ck.gq .ck-wash{background:linear-gradient(180deg,rgba(255,244,234,.86),rgba(255,236,222,.74) 62%,rgba(255,228,211,.35))}
|
||
.ck.gp .ck-wash{background:linear-gradient(180deg,rgba(246,241,255,.86),rgba(238,230,252,.74) 62%,rgba(234,226,251,.35))}
|
||
.ck.gg .ck-wash{background:linear-gradient(180deg,rgba(240,250,244,.86),rgba(228,246,236,.74) 62%,rgba(221,243,231,.35))}
|
||
.ck.gs .ck-wash{background:linear-gradient(180deg,rgba(240,246,255,.86),rgba(230,240,254,.74) 62%,rgba(223,235,253,.35))}
|
||
.ck .cv .ck-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 50%}
|
||
.csr-i.has-bg{background-size:cover!important;background-position:70% 85%!important;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.7)}
|
||
/* 11-04 二改(用户:照片压在字后面抢字)→ 图文分开:照片只占卡片上方一条、往下渐隐成本组纯色,标题/题数/按钮全在纯色区,不再叠在照片上 */
|
||
.ck.has-bg .cv{justify-content:flex-start;background:linear-gradient(180deg,var(--c1),var(--c2))}
|
||
.ck.has-bg .cv .ck-wash{display:none}
|
||
.ck.has-bg .cv .ck-bg{inset:0 0 auto 0;height:var(--ph,62px);-webkit-mask-image:linear-gradient(180deg,#000 55%,transparent);mask-image:linear-gradient(180deg,#000 55%,transparent)}
|
||
.ck.has-bg .cv>b{margin-top:calc(var(--ph,62px) - 8px)}
|
||
#more .ck.has-bg .cv{--ph:64px;height:auto;min-height:168px;padding:0 6px 12px}
|
||
#more .c2 .ck.has-bg .cv{--ph:84px;min-height:212px}
|
||
#more .c2 .ck.has-bg .cv:has(.ck-hl){padding-bottom:36px}
|
||
.ck.has-bg .cv .ck-top,.ck.has-bg .cv .dn{z-index:2}
|
||
/* 11-04 三改(用户:风景照还是太抢镜,视觉都被抢走、标题不突出)→ 照片退成淡淡的氛围:降饱和 + 半透明 + 高度缩小、更早渐隐;标题加大加粗加深,题数 / 按钮弱一点 */
|
||
.ck.has-bg .cv .ck-bg{opacity:.5;filter:saturate(.55) brightness(1.06);-webkit-mask-image:linear-gradient(180deg,#000 30%,transparent);mask-image:linear-gradient(180deg,#000 30%,transparent)}
|
||
#more .ck.has-bg .cv{--ph:48px;min-height:150px}
|
||
#more .c2 .ck.has-bg .cv{--ph:60px;min-height:190px}
|
||
#more .ck.has-bg .cv>b{margin-top:calc(var(--ph) - 12px);font-weight:900;color:#1F1717}
|
||
#more .ck .cv b{font-size:16px;line-height:1.36}
|
||
#more .c2 .ck .cv b{font-size:18px}
|
||
.ck.has-bg .cv small{color:#A89A96}
|
||
.ck.has-bg .cv em{box-shadow:none;opacity:.92}
|
||
.csr-i.has-bg{filter:saturate(.6) brightness(1.05)}
|
||
.ck .cv .ck-wm{position:absolute;right:-8px;bottom:-6px;width:62px;height:62px;opacity:.22;transform:rotate(-12deg);pointer-events:none}
|
||
.ck .cv .ck-wm svg{width:100%;height:100%}
|
||
.ck .cv .ck-wm svg,.ck .cv .ck-wm svg [fill="#fff"]{fill:var(--cb)}.ck .cv .ck-wm svg [stroke="#fff"]{stroke:var(--cb)}
|
||
.csv-n{flex-wrap:nowrap}
|
||
.csv-av{margin-left:auto}
|
||
.csv-av .cav img{width:22px;height:22px;margin-left:-7px;transition:transform .22s,opacity .22s}
|
||
.csv-av .cav img:first-child{margin-left:0}
|
||
.csv-av .cav img.sw{transform:scale(.3);opacity:0}
|
||
.csv-r{height:90px !important}
|
||
.csv-i{opacity:0;transform:translateY(90px);transition:transform .5s cubic-bezier(.3,1.2,.5,1),opacity .45s ease !important;height:30px}
|
||
.csv-i img{width:22px !important;height:22px !important}
|
||
.csv-i:nth-child(odd) b{color:#F0704F}
|
||
/* 摇一摇全屏浮层 */
|
||
.lko{position:fixed;inset:0;z-index:9999;display:grid;place-items:center;pointer-events:auto}
|
||
.lko-bg{position:absolute;inset:0;background:radial-gradient(circle at 50% 42%,rgba(141,107,255,.55),rgba(40,20,80,.78));opacity:0;transition:opacity .25s;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
|
||
.lko.on .lko-bg{opacity:1}
|
||
.lko-in{position:relative;display:flex;flex-direction:column;align-items:center;gap:14px;width:300px;transform:scale(.6);opacity:0;transition:transform .35s cubic-bezier(.3,1.5,.5,1),opacity .25s}
|
||
.lko.on .lko-in{transform:none;opacity:1}
|
||
.lko-dc{position:relative;width:170px;height:110px}
|
||
.lko-dc span{position:absolute;width:84px;height:84px;filter:drop-shadow(0 10px 14px rgba(20,0,60,.45));animation:lkoT .42s linear infinite}
|
||
.lko-dc span svg{width:100%;height:100%;display:block}
|
||
.lko-dc .a{left:6px;top:14px}.lko-dc .b{right:6px;top:0;width:66px;height:66px;animation-duration:.34s;animation-direction:reverse}
|
||
@keyframes lkoT{0%{transform:rotate(0) translateY(0)}25%{transform:rotate(90deg) translateY(-16px)}50%{transform:rotate(180deg)}75%{transform:rotate(270deg) translateY(-10px)}100%{transform:rotate(360deg)}}
|
||
.lko.hit .lko-dc span{animation:lkoLand .5s cubic-bezier(.3,1.7,.5,1)}
|
||
@keyframes lkoLand{from{transform:scale(1.35) rotate(-25deg)}to{transform:none}}
|
||
.lko-tip{margin:0;color:#fff;font-size:15px;font-weight:800;letter-spacing:2px;opacity:.9}
|
||
.lko.hit .lko-tip{font-size:24px;letter-spacing:3px;color:#FFE27A;opacity:1;animation:lkoLand .5s cubic-bezier(.3,1.7,.5,1)}
|
||
.lko-reel{width:100%;height:58px;border-radius:18px;background:rgba(255,255,255,.16);box-shadow:inset 0 0 0 2px rgba(255,255,255,.35);overflow:hidden;display:grid;place-items:center}
|
||
.lko-reel span{display:block;color:#fff;font-size:24px;font-weight:900;letter-spacing:1px;white-space:nowrap}
|
||
.lko-reel span.sp{animation:lkoSp .1s linear}
|
||
@keyframes lkoSp{from{transform:translateY(-90%);opacity:.2;filter:blur(2px)}}
|
||
.lko.hit .lko-reel{display:none}
|
||
.lko-card{width:100%}
|
||
.lko-card .ck{transform:scale(.5) rotate(-8deg);opacity:0;animation:lkoCard .55s .05s cubic-bezier(.3,1.5,.5,1) forwards;box-shadow:0 18px 40px -10px rgba(20,0,60,.6)}
|
||
@keyframes lkoCard{to{transform:none;opacity:1}}
|
||
.lko-card .ck .cv{height:auto;padding:26px 16px 20px;gap:8px}
|
||
.lko-card .ck .cv b{font-size:20px;-webkit-line-clamp:3}
|
||
.lko-card .ck .cv small{font-size:12.5px}
|
||
.lko-card .ck .cv em{height:32px;line-height:32px;padding:0 20px;font-size:14px}
|
||
.lko-card .lko-ic{display:grid;place-items:center;width:52px;height:52px;border-radius:16px;background:var(--cb);box-shadow:0 6px 14px -6px var(--cb);position:relative}
|
||
.lko-card .lko-ic svg{width:30px;height:30px}
|
||
.lko-fx{position:absolute;left:50%;top:50%;pointer-events:none}
|
||
.lko-act{display:flex;flex-direction:column;align-items:stretch;gap:10px;width:100%;opacity:0;transform:translateY(10px);pointer-events:none;transition:opacity .25s,transform .3s cubic-bezier(.3,1.4,.5,1)}
|
||
.lko.done .lko-act{opacity:1;transform:none;pointer-events:auto}
|
||
.lko:not(.hit) .lko-act{display:none}
|
||
.lko-go{height:50px;border-radius:99px;background:linear-gradient(120deg,#FFD25A,#FF9A4D);color:#5A2A00;font-size:17px;font-weight:900;letter-spacing:1px;box-shadow:0 10px 22px -10px rgba(255,150,60,.9);animation:lkPulse 1.8s ease-in-out infinite}
|
||
.lko-re{display:flex;align-items:center;justify-content:center;gap:6px;height:44px;border-radius:99px;background:rgba(255,255,255,.16);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.55);color:#fff;font-size:15px;font-weight:800}
|
||
.lko-re svg{width:22px;height:22px}
|
||
.lko-x,.lko-snd{position:absolute;top:calc(14px + env(safe-area-inset-top));z-index:2;width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;font-size:24px;line-height:36px;text-align:center}
|
||
.lko-x{right:14px}.lko-snd{left:14px}
|
||
.lko-snd::before{content:"";position:absolute;inset:0;background:center/20px no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9.5h3.5L12 5.5v13l-4.5-4H4z' fill='white'/%3E%3Cpath d='M15.5 9a4.2 4.2 0 010 6M18 6.5a7.8 7.8 0 010 11'/%3E%3C/svg%3E")}
|
||
.lko-snd.off::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9.5h3.5L12 5.5v13l-4.5-4H4z' fill='white'/%3E%3Cpath d='M16 9.5l5 5M21 9.5l-5 5'/%3E%3C/svg%3E")}
|
||
.lko-fx i{position:absolute;width:9px;height:12px;border-radius:2px;animation:lkoBoom 1.3s cubic-bezier(.2,.7,.4,1) forwards}
|
||
@keyframes lkoBoom{from{transform:translate(0,0) rotate(0) scale(1);opacity:1}to{transform:translate(var(--x),calc(var(--y) + 180px)) rotate(var(--r)) scale(.6);opacity:0}}
|
||
@media (prefers-reduced-motion:reduce){.lko-dc span{animation:none}}
|
||
.ck .cnn svg{width:11px;height:11px}
|
||
.csr.pa,.ck.pa{--c1:#FFF4EA;--c2:#FFE4D6;--c3:#FFC9AE;--c4:#FFB08F;--cb:#FF8A65}
|
||
.csr.pb,.ck.pb{--c1:#F4F0FA;--c2:#E9E4F4;--c3:#B9AEDB;--c4:#E8D9EE;--cb:#8D84BE}
|
||
.csr.pc,.ck.pc{--c1:#FFF9EC;--c2:#F0F2F6;--c3:#C9DCF0;--c4:#DDE6D2;--cb:#7F8EC9}
|
||
.csr.pd,.ck.pd{--c1:#F6EEFA;--c2:#FBEFE6;--c3:#D9C6EE;--c4:#FBD9BF;--cb:#9A86C4}
|
||
.csr.pe,.ck.pe{--c1:#F1FAEF;--c2:#EEF6F5;--c3:#CDE9D5;--c4:#BFDDEB;--cb:#7C8FCB}
|
||
.csr.pf,.ck.pf{--c1:#FFF1E6;--c2:#FDE6DD;--c3:#FFC5A6;--c4:#F8D7C4;--cb:#E58A64}
|
||
.csd{display:flex;align-items:center;gap:10px;margin:20px 0 -4px;color:#A69CA8;font-size:12.5px}
|
||
.csd::before,.csd::after{content:"";flex:1;height:1px;background:#E6DEE6}
|
||
.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:inherit;margin:0 1px} /* 11-05 用户:# 号不要有颜色 */
|
||
.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:inherit;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)}
|
||
.shtg .sh{margin-bottom:2px}
|
||
/* 11-05 用户:广场页面不要左右滑,要固定 → 标签不再横滑,自动换行 */
|
||
.gtg{display:flex;flex-wrap:wrap;gap:7px;padding:4px 14px 6px}
|
||
.gtg::-webkit-scrollbar{display:none}
|
||
.gtg button{flex:none;height:30px;padding:0 13px;border-radius:99px;background:#fff;border:1px solid #EFE1DB;font-size:13px;font-weight:700;color:#5E4E4A;white-space:nowrap}
|
||
.gtg .gall{border-style:dashed;color:#B0948D;font-weight:600}
|
||
/* 11-05 整合:投稿奖励一行(原在热门话题列表头)+ 选中标签后的热门话题 */
|
||
.rww{margin:14px 12px 0}
|
||
.rww .rwl{margin:0}
|
||
/* 11-07 用户:祈福树下面「投稿被选中得 ¥30…」一条 → 改成轮播「哪些妈妈的笔记上了广场」:真实投稿(审核通过)排前,
|
||
不够时用广场里点赞高的笔记补;只说「上了广场 / 入选精选」,不写某人领了多少钱。右边「我也投稿」= 原来的规则弹层 */
|
||
.rwc{display:flex;align-items:center;gap:8px;height:40px;padding:0 6px 0 10px;border-radius:12px;background:linear-gradient(100deg,#FFF1E8,#FFE6E6)}
|
||
.rwc>.ic{flex:none;width:16px;height:16px;color:#F2553A}
|
||
.rwv{position:relative;flex:1;min-width:0;height:40px;overflow:hidden}
|
||
.rwi{position:absolute;left:0;right:0;top:0;display:flex;align-items:center;gap:6px;height:40px;border:0;background:none;padding:0;font:inherit;text-align:left;color:#8A4B36;font-size:12px;
|
||
transition:transform .4s ease,opacity .4s ease}
|
||
.rwi.in{transform:translateY(100%);opacity:0}.rwi.out{transform:translateY(-100%);opacity:0}
|
||
.rwi img{flex:none;width:20px;height:20px;border-radius:50%;object-fit:cover;background:#FFE3D3}
|
||
.rwi span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.rwi span b{font-weight:800;color:#5A3226}
|
||
.rwi span em{font-style:normal;font-weight:800;color:#F2394A}
|
||
.rwb{flex:none;height:26px;padding:0 10px;border:0;border-radius:99px;background:linear-gradient(135deg,#FF8A65,#F2553A);color:#fff;font:inherit;font-size:11.5px;font-weight:800}
|
||
.gtp{display:flex;flex-direction:column;align-items:flex-start;gap:6px;margin:2px 14px 4px;padding:10px 12px;border-radius:14px;background:#fff;box-shadow:0 6px 16px -14px rgba(120,60,40,.35)}
|
||
.gtp[hidden]{display:none}
|
||
.gtp-h{font-size:11.5px;font-weight:800;color:#F2553A}
|
||
.gtp button{max-width:100%;padding:0;background:none;border:0;text-align:left;font-size:13.5px;font-weight:700;line-height:1.45;color:#3A2C28;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.gtp button::after{content:' ›';color:#C9B3AC}
|
||
html.night .gtp{background:rgba(255,255,255,.06)}
|
||
html.night .gtp button{color:#EFE3EA}
|
||
.gtg button.on{background:#F2725B;border-color:#F2725B;color:#fff;box-shadow:0 5px 12px -6px #F2725B}
|
||
/* 11-05 用户:「护肤经验」标签加颜色重点突出 */
|
||
.gtg button[data-tag="护肤经验"]{background:linear-gradient(135deg,#FFE3EC,#FFD1E0);border-color:#FFB3CB;color:#D6336C}
|
||
.gtg button[data-tag="护肤经验"]::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:#FF5C8D;margin-right:5px;vertical-align:2px}
|
||
.gtg button[data-tag="护肤经验"].on{background:linear-gradient(135deg,#FF7AA2,#F0507F);border-color:#F0507F;color:#fff;box-shadow:0 5px 12px -6px #F0507F}
|
||
.gtg button[data-tag="护肤经验"].on::before{background:#fff}
|
||
html.night .gtg button[data-tag="护肤经验"]{background:rgba(255,92,141,.18);border-color:rgba(255,92,141,.45);color:#FF9DBB}
|
||
html.night .gtg button[data-tag="护肤经验"].on{background:linear-gradient(135deg,#FF7AA2,#F0507F);border-color:#F0507F;color:#fff}
|
||
html.night .gtg button{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.12);color:#E8DFE8}
|
||
html.night .gtg button.on{background:#F2725B;border-color:#F2725B;color:#fff}
|
||
.tcs{display:flex;flex-wrap:wrap;gap:7px;padding:9px 12px 2px}
|
||
.tcs::-webkit-scrollbar{display:none}
|
||
.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:0 1 auto;min-width:0;font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nc .nf{gap:4px}
|
||
.nc .nf .stg{flex:none;font-style:normal;font-size:10px;line-height:16px;padding:0 4px;border-radius:99px;background:#F5EFEC;color:#A08C86;white-space:nowrap}
|
||
.nc .nf .lk{margin-left:auto;min-width:0;gap:1px}
|
||
.nc .nf .lk .ic{width:13px;height:13px}
|
||
.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}
|
||
.mb-brand{text-align:center;color:#C29A8F;font-size:11.5px;line-height:1.7}.mb-brand img{display:block;width:86px;height:auto;margin:0 auto 6px;opacity:.6}.mb-brand p{display:flex;align-items:center;justify-content:center;gap:8px;margin:0;letter-spacing:.06em}.mb-brand p::before,.mb-brand p::after{content:'';width:28px;height:1px;background:#EAD3CC}
|
||
.end{padding-top:28px}
|
||
|
||
/* ---------- 封面(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}
|
||
/* 11-05 用户:全部话题里「家庭婚姻 / 职场 / 经验」几个字要明显 → 分类标签放大成 30px 高的色块,图标同步放大,后面拉一条同色淡线隔开各组 */
|
||
.tl-h .kb{height:30px;padding:0 13px 0 10px;border-radius:10px;font-size:16px;letter-spacing:1px;gap:5px;box-shadow:0 4px 10px -4px var(--kf)}
|
||
.tl-h .kb .ic{width:17px;height:17px}
|
||
.tl-h::after{content:'';flex:1;height:1.5px;margin-left:6px;border-radius:1px;background:linear-gradient(90deg,#EADBD6,transparent)}
|
||
.tl-h{margin:20px 0 10px}
|
||
.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:inherit;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-05 评论 / 回复带图(js/cm-pics.js):输入框里加图片按钮,选了图在底栏上方排一行缩略图 */
|
||
.bar{position:relative}
|
||
/* 11-05 表情包:缩略图条 + 表情面板一起浮在底栏上方 */
|
||
#cmUp{position:absolute;left:0;right:0;bottom:100%;background:#fff}
|
||
#cmPics{padding:8px 14px 6px;border-top:1px solid var(--line)}
|
||
#cpic,#cemo{width:28px;height:28px}
|
||
#cemo.on{color:#F4593C}
|
||
/* 11-05 用户:广场评论框里把表情去掉 → 表情按钮和面板都不出(cm-pics.js 留着,已发的表情评论照常显示) */
|
||
#cemo,#cmEmo{display:none!important}
|
||
|
||
/* ---------- 投稿(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;background:#fff;box-shadow:0 0 0 1.5px #fff,0 3px 10px rgba(226,105,74,.3)}
|
||
.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:-7px;border-radius:50%;z-index:-1;pointer-events:none; /* 渐变圈:整圈 粉→橙→深橙,比数胎动那条半圈更明显(11-03 用户要「渐变圈的效果」) */
|
||
background:conic-gradient(from 200deg,#FFB38A,#F4593C,#E2694A,#FF8FA3,#FFB38A);
|
||
-webkit-mask:radial-gradient(circle closest-side,transparent 82%,#000 85%);mask:radial-gradient(circle closest-side,transparent 82%,#000 85%)}
|
||
/* 「记一下」弹层:标题一行 + 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}
|
||
|
||
/* ---------- 分类小 banner(11-03 用户:家庭婚姻 / 职场 / 经验 / 测一测各做一张小 banner 替换祈福树,祈福树只留在「全部」)
|
||
图 guangchang/bn/*.webp(AI 生成 3D 黏土风,纯色底),卡片底色取图的底色,图贴右边、左侧文字 ---------- */
|
||
.cbn{position:relative;display:flex;align-items:stretch;width:calc(100% - 24px);height:112px;margin:2px 12px 0;border:0;padding:0;border-radius:18px;overflow:hidden;text-align:left;font-family:inherit;cursor:pointer;background:var(--bb);box-shadow:0 6px 16px rgba(160,90,70,.1);transition:transform .16s;-webkit-tap-highlight-color:transparent}
|
||
.cbn:active{transform:scale(.985)}
|
||
.cbn img{position:absolute;right:-6px;top:50%;height:132px;width:auto;transform:translateY(-50%);pointer-events:none;animation:cbnF 5s ease-in-out infinite}
|
||
@keyframes cbnF{0%,100%{transform:translateY(-50%)}50%{transform:translateY(calc(-50% - 3px))}}
|
||
.cbn::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,var(--bb) 38%,transparent 66%)}
|
||
.cbn-tx{position:relative;z-index:1;display:flex;flex-direction:column;align-items:flex-start;padding:14px 0 12px 16px;max-width:64%}
|
||
.cbn-tx small{font-size:11px;font-weight:700;color:var(--bc);opacity:.85;letter-spacing:.3px}
|
||
.cbn-tx b{margin-top:4px;font-size:17.5px;font-weight:900;color:#2A1E1E;line-height:1.25;white-space:nowrap}
|
||
.cbn-tx em{margin-top:3px;font-style:normal;font-size:11.5px;color:#7C6E68;white-space:nowrap}
|
||
.cbn-go{margin-top:auto;display:inline-flex;align-items:center;gap:1px;height:26px;padding:0 9px 0 12px;border-radius:99px;background:var(--bc);color:#fff;font-size:12px;font-weight:800;box-shadow:0 3px 8px rgba(0,0,0,.12)}
|
||
.cbn-go .ic{width:12px;height:12px}
|
||
.cbn.b-family{--bb:#FCDEE3;--bc:#E25C7A}
|
||
.cbn.b-work{--bb:#D2E0F7;--bc:#4A7BD0}
|
||
.cbn.b-baby{--bb:#D6EFE7;--bc:#2E9B78}
|
||
.cbn.b-ceshi{--bb:#E8E0FC;--bc:#7A5BD6}
|
||
|
||
/* 11-03 卡片话题标签:标题下一行「#职场」「#经验分享」「#家庭婚姻」,像发布时带的话题 */
|
||
.nb .ntg{display:inline-block;margin:4px 0 0;padding:1px 7px;border-radius:6px;font-size:11px;font-weight:700;line-height:18px;background:#FFF0EC;color:#E2694A}
|
||
.nb .ntg.k-work{background:#EDF3FD;color:#4A7BD0}
|
||
.nb .ntg.k-baby{background:#E9F6F1;color:#2E9B78}
|
||
.nb .ntg.k-family{background:#FFEEF2;color:#E25C7A}
|
||
</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"><div class="mb-brand"><img src="../assets/img/brand-logo-c.png" alt="兜爸心选"><p>陪你从孕期到育儿的每一天</p></div></div> <!-- 11-04 用户:底部「到底啦 / 示例占位」文字去掉,换品牌 logo + slogan -->
|
||
</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="cmp-btn" id="cemo" type="button" aria-label="表情"></button><button class="cmp-btn" id="cpic" type="button" aria-label="加图片"></button><button class="send" id="csend" type="button" disabled>发送</button></label>
|
||
<div id="cmUp"><div class="cmp-strip" id="cmPics"></div><div id="cmEmo"></div></div>
|
||
<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="../js/wh-themes.js?v=26110609"></script> <!-- 11-07 悄悄话每周话题(与首页共用) -->
|
||
<script src="topics.js?v=26110487"></script>
|
||
<script src="data.js?v=26110487"></script>
|
||
<script src="feed.js?v=26110487"></script>
|
||
<script src="../js/ava-pool.js?v=26110487"></script> <!-- 11-05 装饰头像分配表(各模块互不重复) -->
|
||
<script src="ceshi/meta.js?v=26110464"></script>
|
||
<script src="../js/share-card.js?v=26110464"></script>
|
||
<script src="../js/cm-pics.js?v=26110464"></script> <!-- 11-05 评论 / 回复带图 -->
|
||
<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 = (window.mbGate && window.mbGate.out) ? '' : param('openid'); /* 11-07 退出登录后按访客(不拉「我的评论」、不认头像) */
|
||
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'; };
|
||
/* 11-05 用户:各模块头像不要重复 → 占位笔记作者头像改用分配表 author(每篇一个,179 个互不相同,首页卡堆 / 大家都在关注同一张);分配表没有的才回落 AV 池 */
|
||
var avOf = function (n) { var a = window.MB_AVA && MB_AVA.S.author[n.id]; return n.avatar || (a ? MB_AVA.src(a, '../') : 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) {
|
||
if (n.del) return; /* 11-05 用户删帖:保留位置不挪,后面几篇 id(评论 / 头像 / 转发图)不错位 */
|
||
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: window.GC_LIKES ? GC_LIKES(t.id + '-' + (i + 1), n.likes) : (+n.likes || 0), body: n.body || '', /* 11-05 每天 +20~30(feed.js) */
|
||
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=26110612').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, img: c.images }; }) : [];
|
||
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, img: c.images }; });
|
||
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, img: c.img }; });
|
||
return o.concat(m).sort(function (x, y) { return x.ts - y.ts; }); /* 楼里按时间先后 */
|
||
}
|
||
var cpH = function (a) { return window.MBCmPics ? MBCmPics.html(a) : ''; }; /* 11-05 评论里的图 */
|
||
var cpT = function (t) { return window.MBCmPics ? MBCmPics.txt(t) : esc(t); }; /* 11-05 评论文字里的 [兜表情:xx] 换成表情图 */
|
||
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>' : '') + ':' + cpT(x.t) + cpH(x.img) + (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 + '"><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>'; }
|
||
/* 11-04 用户:卡片底部昵称旁边带上孕周,样式同评论区 .stg;图上压字卡原来顶部那行孕周去掉,免得一张卡出现两次 */
|
||
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>' + (t && TAG_NAME[t.cat] ? '<span class="ntg k-' + t.cat + '">#' + TAG_NAME[t.cat] + '</span>' : '') +
|
||
'<div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + (n.stage ? '<i class="stg">' + esc(n.stage.replace(/\s+/g, '')) + '</i>' : '') + likeHTML(n) + '</div></div></button>';
|
||
}
|
||
|
||
/* ---------- 列表 ---------- */
|
||
/* cur 当前话题('' = 不限话题);catF 一级分类('' 全部 / family 家庭 / marriage 婚姻 / work 职场 / baby 母婴)。选了话题时 catF 恒等于该话题的 cat */
|
||
var cur = '', catF = '', tagF = '';
|
||
/* 「大家在聊」标签 → 话题 id(11-05)。护肤经验 = b11(同日新开的话题);一个话题可以在多个标签里 */
|
||
var GTAGS = [
|
||
['职场', ['w01', 'w02', 'w03', 'w04', 'w05', 'w06', 'w07', 'w08', 'w09', 'w10']],
|
||
['护肤经验', ['b11']],
|
||
['夫妻日常', ['m01', 'm02', 'm03', 'm04', 'm05', 'm06', 'm07', 'm08', 'm09', 'm10']],
|
||
['婆家娘家', ['f01', 'f02', 'f03', 'f04', 'f05', 'f06', 'f07', 'f09', 'f10']],
|
||
['身体变化', ['b01', 'b05', 'b10', 'b11']],
|
||
['吃喝', ['b09', 'f10']],
|
||
['胎动', ['b06', 'w04']],
|
||
['待产生娃', ['b07', 'b08', 'b04']],
|
||
['花钱囤货', ['b02', 'b04']],
|
||
['宅家日常', ['f08', 'b03']]
|
||
];
|
||
var GTBY = {}; GTAGS.forEach(function (g) { GTBY[g[0]] = g[1]; });
|
||
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) */
|
||
/* 11-03 用户:「家庭婚姻 / 职场 / 经验标签全部删除,只展示全部,所有内容放到全部里;每篇带一个话题标签(职场 / 经验分享…)」
|
||
→ 顶部只留「全部」+「测一测」(首页孕期百宝箱「趣味小测试」进的就是测一测);话题标签见 cardHTML 的 .ntg */
|
||
/* 11-03 三改:顶部「测一测」也删了,只剩「全部」;测试列表只从首页孕期百宝箱「趣味小测试」进(?c=ceshi),这时顶部换成「趣味小测试」标题、不出分类条 */
|
||
var CATS = [['', '全部', 'i-grid']];
|
||
var TAG_NAME = { family: '家庭婚姻', work: '职场', baby: '经验分享' };
|
||
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 cs = catF === 'ceshi';
|
||
/* 11-04 用户:「列表页把『全部』去掉,只留顶上的头和『孕妈广场』」→ 分类条一律不出 */
|
||
$('#cats').style.display = 'none';
|
||
$('#top .nav h1 span').textContent = cs ? '趣味小测试' : '孕妈广场';
|
||
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>';
|
||
} /* 11-07 用户:「首页就不放了,在内容页里放,发一个笔记置顶,点击就进到这个页面」→ 「全部」信息流右列第一张置顶笔记卡。
|
||
有孕周(首页写的 mmbox.gcwk.v1,≥4 周、没生)且没退出登录才出;数据同首页 GET /whisper?openid=&week=,回来后卡里轮播真实的悄悄话,
|
||
拉不到就只显示话题,不造内容。星空全屏页在首页 → 点了跳首页带 ?wh=1,首页直接打开星空页,关掉回到这里。 */
|
||
var PIN_WK = (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; } })();
|
||
var PIN_ON = PIN_WK >= 4 && !(window.mbGate && window.mbGate.out);
|
||
var WHD = null, whRi = 0, whT = null;
|
||
/* 置顶笔记本身:按每周话题一篇(id = wh-话题起始日),留言走广场评论那套(先审后发,后台「评论审核」页签);
|
||
模拟祝福评论在 cm.json 的 c['wh-20260928'](100 条,tools/whcm/,AGENTS.md 12c 扩展) */
|
||
var PIN_TH = window.MB_WH_THEME ? window.MB_WH_THEME() : null;
|
||
var PIN_ID = 'wh-' + (PIN_TH ? PIN_TH.from.replace(/-/g, '') : '0');
|
||
var PIN = NBY[PIN_ID] = { id: PIN_ID, pin: 1, title: '孕妈悄悄话 · ' + (PIN_TH ? PIN_TH.name : ''), author: '孕妈悄悄话', stage: '', likes: 0 };
|
||
function pinCoverHTML(th, l, sky, big) {
|
||
return '<div class="pcv"><span class="psk" aria-hidden="true">' + sky + '<b class="pmt"></b><b class="pmt m2"></b></span><i class="ptop">置顶</i>' +
|
||
'<div class="pbig"><small>' + (th ? '本周话题' : '孕妈悄悄话') + '</small><b>' + (th ? (th.lines || [th.name]).map(esc).join('<br>') : '说给宝宝听的悄悄话') + '</b></div>' +
|
||
'<p class="pq" id="' + (big ? 'pinRl2' : 'pinRl') + '">' + (l.length ? '“' + esc(l[0].text) + '”' : '点一颗星星,听听她们说了什么') + '</p>' +
|
||
(big ? '<button type="button" class="pstar" data-star="1">去星空看看<svg class="ic" style="width:14px;height:14px"><use href="#i-right"/></svg></button>' : '') + '</div>';
|
||
}
|
||
function pinHTML() {
|
||
var th = (WHD && WHD.theme && WHD.theme.name) ? WHD.theme : (window.MB_WH_THEME ? window.MB_WH_THEME() : null);
|
||
var l = WHD ? (WHD.list || []).filter(function (x) { return !x.mine; }) : [];
|
||
var sky = pinSky();
|
||
return '<button type="button" class="nc pin" id="whPin" data-id="' + PIN_ID + '" aria-label="置顶:孕妈悄悄话' + (th ? ',本周话题' + esc(th.name) : '') + '"><div class="cvw">' + pinCoverHTML(th, l, sky) + '</div>' +
|
||
'<div class="nb"><h3>每一颗星星,都是一位孕妈的一句话</h3><span class="ntg k-whs">#孕妈悄悄话</span>' +
|
||
'<div class="nf"><i class="pav" aria-hidden="true"><svg viewBox="0 0 20 20" width="10" height="10"><path d="M10 .5C10.9 7.4 12.6 9.1 19.5 10 12.6 10.9 10.9 12.6 10 19.5 9.1 12.6 7.4 10.9.5 10 7.4 9.1 9.1 7.4 10 .5Z" fill="currentColor"/></svg></i><span class="nm">' + PIN_WK + '周孕妈悄悄话</span><span class="pgo">去看看 ›</span></div></div></button>';
|
||
}
|
||
var PIN_SKY = [[14,14,0,-1.2,2.4],[38,8,0,-.3,2],[62,20,1,-2.4,2.8],[86,12,0,-3.1,2.2],[24,34,1,-3.7,2.6],[50,40,0,-1.6,3.2],[80,32,0,-2.2,2.6],[10,52,0,-.8,3],[70,50,1,-1.9,2.4],[90,58,0,-2.8,3]];
|
||
function pinSky() { return PIN_SKY.map(function (k) { return '<i' + (k[2] ? ' class="b"' : '') + ' style="left:' + k[0] + '%;top:' + k[1] + '%;animation-delay:' + k[3] + 's;animation-duration:' + k[4] + 's"></i>'; }).join(''); }
|
||
function whRoll() {
|
||
clearInterval(whT); whRi = 0;
|
||
var els = ['pinRl', 'pinRl2'].map(function (x) { return document.getElementById(x); }).filter(Boolean), l = WHD ? (WHD.list || []).filter(function (x) { return !x.mine; }) : [];
|
||
if (!els.length || !l.length) return;
|
||
els.forEach(function (el) { el.textContent = '“' + l[0].text + '”'; });
|
||
if (l.length < 2) return;
|
||
whT = setInterval(function () {
|
||
var es = ['pinRl', 'pinRl2'].map(function (x) { return document.getElementById(x); }).filter(Boolean);
|
||
if (!es.length) { clearInterval(whT); return; } if (document.hidden) return;
|
||
whRi = (whRi + 1) % l.length; es.forEach(function (e2) { e2.classList.add('out'); });
|
||
setTimeout(function () { es.forEach(function (e2) { e2.textContent = '“' + l[whRi].text + '”'; e2.classList.remove('out'); }); }, 260);
|
||
}, 4000);
|
||
}
|
||
if (PIN_ON) fetch('/api/mp/public/mama-box/whisper?openid=' + encodeURIComponent(OPENID || '') + '&week=' + PIN_WK)
|
||
.then(function (r) { return r.ok ? r.json() : null; })
|
||
.then(function (j) { var r = j && j.code === 200 && j.result; if (r && r.show && (r.list || []).length) { WHD = r; whRoll(); } })
|
||
.catch(function () {});
|
||
|
||
/* 分类小 banner:家庭婚姻 / 职场 / 经验 点了 = 参与本类最热话题(投稿规则弹层);测一测 点了 = 进最热的那个测试 */
|
||
var CBN = {
|
||
family: ['家庭婚姻', '孕期的家,也需要用心经营', '和老公、婆婆、爸妈的那些事', '我也来聊聊'],
|
||
work: ['职场', '怀孕了,工作也要安心', '产检请假、孕期上班、休产假', '我也来聊聊'],
|
||
baby: ['经验', '过来人的孕育笔记', '踩过的坑、买对的好物都在这', '分享我的经验'],
|
||
ceshi: ['孕育测一测', '', '', '测最热的一个']
|
||
};
|
||
function cbnHTML(c) {
|
||
var x = CBN[c]; if (!x) return '';
|
||
var tgt;
|
||
if (c === 'ceshi') {
|
||
var top = byHot(TM)[0];
|
||
x = x.slice(); x[1] = '测测你是哪种孕妈'; x[2] = '累计 ' + Math.round(TM.reduce(function (a, y) { return a + gcTested(y.id); }, 0) / 1e4) + ' 万人次参与 · ' + TM.length + ' 个测试';
|
||
tgt = top ? ' data-test="' + top.id + '"' : '';
|
||
} else { var h = hotList()[0]; tgt = ' data-join="' + (h ? h.id : '') + '"'; }
|
||
return '<button type="button" class="cbn b-' + c + '"' + tgt + '><img src="bn/' + c + '.webp" alt="" decoding="async">' +
|
||
'<span class="cbn-tx"><small>' + x[0] + '</small><b>' + x[1] + '</b><em>' + x[2] + '</em><span class="cbn-go">' + x[3] + '<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); }); };
|
||
var TGD = { quiz: '有标准答案,答完看解析', psy: '没有对错,测测你是哪一型', game: '挑战一下,看能拿什么称号', shop: '测测你给娃买东西、挑东西是哪种风格' };
|
||
/* 11-03 用户发参考图:「测试列表按图里的排版」→ 分组标题(色条 + 图标 + 名称 + 一句话)+ 宫格卡:
|
||
彩色渐变封面(两团柔和色块)上写大字短名 + 小字「谁来测 · N 题」+「开始测试」胶囊,封面下一行完整标题 + 人数;
|
||
常识小测 / 趣味闯关 3 列,趣味心理 / 花钱风格 2 列(大卡)。原热度榜不再单列,组内仍按人数从高到低排。 */
|
||
var CS_SHORT = window.GC_SHORT || {}; /* 短名表在 ceshi/meta.js(测试开始页顶部小胶囊也用) */
|
||
/* 11-04 用户:「列表页小图标都用扁平化」→ 分组 emoji 换成纯色圆角块 + 白色实心图标(CS_ICO);
|
||
「一排 3 个字看不清」→ 每组统一一排 2 个,最多 3 排(6 张),多出来的改一行一条的列表(csRowHTML);5 个的组出 4 张卡 + 1 行,不留单张。 */
|
||
var CS_ICO = {
|
||
quiz: '<svg viewBox="0 0 24 24"><path d="M3.5 5.6c2.6-.9 5.4-.6 7.6 1V19c-2.2-1.4-5-1.7-7.6-.9zM20.5 5.6c-2.6-.9-5.4-.6-7.6 1V19c2.2-1.4 5-1.7 7.6-.9z" fill="#fff"/></svg>',
|
||
psy: '<svg viewBox="0 0 24 24"><path d="M12 20s-7.5-4.5-8.8-9.2C2.3 7.6 4.4 4.8 7.4 4.8c1.9 0 3.5 1 4.6 2.6 1.1-1.6 2.7-2.6 4.6-2.6 3 0 5.1 2.8 4.2 6C19.5 15.5 12 20 12 20z" fill="#fff"/></svg>',
|
||
game: '<svg viewBox="0 0 24 24"><path d="M7 4h10v5a5 5 0 01-10 0zM7 6H4v1.5A3.5 3.5 0 007.3 11M17 6h3v1.5a3.5 3.5 0 01-3.3 3.5" fill="#fff"/><path d="M7 6H4v1.5A3.5 3.5 0 007.3 11M17 6h3v1.5a3.5 3.5 0 01-3.3 3.5" fill="none" stroke="#fff" stroke-width="1.6"/><path d="M10.5 14h3v3h-3zM8 17.5h8V20H8z" fill="#fff"/></svg>',
|
||
shop: '<svg viewBox="0 0 24 24"><path d="M5 8.5h14l-1 11.5H6z" fill="#fff"/><path d="M9 10V7a3 3 0 016 0v3" fill="none" stroke="#fff" stroke-width="1.8" stroke-linecap="round"/></svg>'
|
||
};
|
||
|
||
/* 11-04 用户:「一行一条前面的图标都是一样的小书」→ 每个测试一枚自己的扁平图标(白色实心,底色按分组再分深浅三档),宫格卡封面右下角也放一枚大号淡水印 */
|
||
var CS_TI = {
|
||
t01: '<path d="M12 6.2c-1.6-2.3-6.6-2.2-7.4 2.2-.8 4.5 2.6 10.6 5.2 11 1 .2 1.4-.4 2.2-.4s1.2.6 2.2.4c2.6-.4 6-6.5 5.2-11-.8-4.4-5.8-4.5-7.4-2.2z"/><path d="M12 6c0-1.6.8-2.8 2.4-3.4" fill="none" stroke="#fff" stroke-width="1.7" stroke-linecap="round"/>',
|
||
t02: '<circle cx="12" cy="6.5" r="3.6"/><path d="M4.5 21c0-4.6 3.4-7.6 7.5-7.6s7.5 3 7.5 7.6z"/><path d="M12 13.6l-1.4 2.2L12 21l1.4-5.2z" fill="rgba(0,0,0,.18)"/>',
|
||
t03: '<circle cx="12" cy="12.5" r="7.6"/><circle cx="9.3" cy="12" r="1.1" fill="rgba(0,0,0,.28)"/><circle cx="14.7" cy="12" r="1.1" fill="rgba(0,0,0,.28)"/><path d="M10 15.2c1.2 1 2.8 1 4 0" fill="none" stroke="rgba(0,0,0,.28)" stroke-width="1.3" stroke-linecap="round"/><path d="M12 4.9c-.4-1.4.6-2.5 2-2.2" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/>',
|
||
t04: '<path d="M8 3h8l-1 3.5H9z"/><rect x="7.5" y="7.5" width="9" height="13.5" rx="3.2"/><path d="M9.5 12h5M9.5 15.5h5" stroke="rgba(0,0,0,.2)" stroke-width="1.3"/>',
|
||
t05: '<rect x="3.5" y="7" width="17" height="13" rx="3"/><path d="M9 7V5.2C9 4.5 9.5 4 10.2 4h3.6c.7 0 1.2.5 1.2 1.2V7" fill="none" stroke="#fff" stroke-width="1.8"/><path d="M3.5 12.5h17" stroke="rgba(0,0,0,.18)" stroke-width="1.4"/><rect x="10.5" y="11.2" width="3" height="2.6" rx=".8" fill="rgba(0,0,0,.2)"/>',
|
||
t06: '<ellipse cx="12" cy="15.5" rx="8.5" ry="4.5"/><circle cx="16.8" cy="9.2" r="3.4"/><path d="M19.8 9.4l2 .6-2 .8z"/><circle cx="17.5" cy="8.6" r=".7" fill="rgba(0,0,0,.35)"/>',
|
||
t07: '<path d="M3 11h18c0 4.7-3.6 8.5-9 8.5S3 15.7 3 11z"/><path d="M8.5 8.5c-.8-1 .6-2-.2-3.2M12 8.5c-.8-1 .6-2-.2-3.2M15.5 8.5c-.8-1 .6-2-.2-3.2" fill="none" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/>',
|
||
t08: '<ellipse cx="9" cy="7.8" rx="4" ry="5"/><path d="M8.2 12.5h1.6l.7 8.2a1.5 1.5 0 01-3 0z"/><path d="M16 3v6.5M14 3v4.8a2 2 0 004 0V3M16 9.5V21" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/>',
|
||
t09: '<path d="M14.5 3.2A8.8 8.8 0 1020.8 15 7 7 0 0114.5 3.2z"/><path d="M17 5.5h3l-3 3.2h3" fill="none" stroke="#fff" stroke-width="1.4" stroke-linejoin="round"/>',
|
||
t10: '<path d="M12 2.8s-6.5 7.2-6.5 11.6a6.5 6.5 0 0013 0C18.5 10 12 2.8 12 2.8z"/><path d="M9 14.5a3 3 0 002.6 3" fill="none" stroke="rgba(0,0,0,.2)" stroke-width="1.5" stroke-linecap="round"/>',
|
||
t11: '<rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M3.5 9.5h17" stroke="rgba(0,0,0,.2)" stroke-width="1.4"/><path d="M8 3v4M16 3v4" stroke="#fff" stroke-width="2" stroke-linecap="round"/><path d="M8 14.6l2.4 2.2 4.6-4.4" fill="none" stroke="rgba(0,0,0,.28)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>',
|
||
t12: '<path d="M12 2.8l2.8 5.8 6.3.9-4.6 4.4 1.1 6.3L12 17.2l-5.6 3 1.1-6.3L2.9 9.5l6.3-.9z"/>',
|
||
t13: '<path d="M12 21v-8.5" stroke="#fff" stroke-width="2" stroke-linecap="round"/><path d="M12 13C12 8 8.5 5.5 4 6c0 4.5 3.2 7.2 8 7zM12 11.5c0-4 3-6.8 7.5-6.5 0 4.2-3 6.8-7.5 6.5z"/>',
|
||
t14: '<circle cx="9" cy="9" r="4"/><path d="M9 2v1.4M3.4 9H2M4.1 4.1l1 1M13.9 4.1l-1 1" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/><path d="M7.5 20.5a4.5 4.5 0 01.6-9 6 6 0 0111.4 2.2 3.4 3.4 0 01-.5 6.8z"/>',
|
||
t15: '<path d="M4 5.5c2.6-.9 5.4-.5 7.3 1v13c-1.9-1.4-4.7-1.8-7.3-.9zM20 5.5c-2.6-.9-5.4-.5-7.3 1v13c1.9-1.4 4.7-1.8 7.3-.9z"/><path d="M15 9.2l1.2.8 1.6-2" fill="none" stroke="rgba(0,0,0,.25)" stroke-width="1.3" stroke-linecap="round"/>',
|
||
t16: '<circle cx="8" cy="7" r="3"/><circle cx="16" cy="7" r="3"/><path d="M2.5 19c0-3.6 2.4-6 5.5-6s5.5 2.4 5.5 6zM10.5 19c0-3.6 2.4-6 5.5-6s5.5 2.4 5.5 6z"/><path d="M12 16.6s-2-1.2-2-2.6c0-.8.6-1.3 1.2-1.3.4 0 .7.2.8.5.1-.3.4-.5.8-.5.6 0 1.2.5 1.2 1.3 0 1.4-2 2.6-2 2.6z" fill="#FFD3DE"/>',
|
||
t17: '<path d="M7 19.5a4.5 4.5 0 01-.7-9 6.2 6.2 0 0111.8 1.3A3.9 3.9 0 0117.5 19.5z"/><path d="M8 22l1-2M12 22l1-2M16 22l1-2" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/>',
|
||
t18: '<path d="M12 3.5v16.5M6.5 20h11" stroke="#fff" stroke-width="1.8" stroke-linecap="round"/><path d="M4 7.5h16" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/><path d="M2.5 13.5L5 7.5l2.5 6zM16.5 13.5L19 7.5l2.5 6z"/><path d="M2.5 13.5a2.5 2 0 005 0zM16.5 13.5a2.5 2 0 005 0z"/>',
|
||
t19: '<circle cx="8" cy="8" r="3.2"/><circle cx="16.5" cy="10.5" r="2.5"/><path d="M2.5 20c0-4 2.4-6.6 5.5-6.6s5.5 2.6 5.5 6.6zM12.5 20c.2-3 1.8-5 4-5s3.8 2 4 5z"/>',
|
||
t20: '<circle cx="12" cy="8" r="4.2"/><path d="M4.5 21c0-4.5 3.4-7.4 7.5-7.4s7.5 2.9 7.5 7.4z"/><circle cx="10.2" cy="8.3" r="1.3" fill="none" stroke="rgba(0,0,0,.3)" stroke-width=".9"/><circle cx="13.8" cy="8.3" r="1.3" fill="none" stroke="rgba(0,0,0,.3)" stroke-width=".9"/><path d="M8.4 4.6c1.2-1.4 6-1.4 7.2 0" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/>',
|
||
t21: '<path d="M4 13a8 8 0 0116 0" fill="none" stroke="#fff" stroke-width="2"/><rect x="2.5" y="12.5" width="5" height="7.5" rx="2"/><rect x="16.5" y="12.5" width="5" height="7.5" rx="2"/><path d="M12 9.5v4.2a1.6 1.6 0 11-1-1.5V9.5h3.2" fill="none" stroke="#fff" stroke-width="1.4"/>',
|
||
t22: '<path d="M12 2.8a6.5 6.5 0 00-3.8 11.8V17h7.6v-2.4A6.5 6.5 0 0012 2.8z"/><rect x="8.6" y="18.2" width="6.8" height="2.6" rx="1.2"/><path d="M10.4 8.4l3.2 3.2M13.6 8.4l-3.2 3.2" stroke="rgba(0,0,0,.25)" stroke-width="1.5" stroke-linecap="round"/>',
|
||
t23: '<circle cx="12" cy="12" r="2.6" fill="rgba(0,0,0,.18)"/><path d="M12 9.4c-1.4-4 1.4-6.4 0-6.4s1.4 2.4 0 6.4z"/><ellipse cx="12" cy="5.8" rx="2.6" ry="3.6"/><ellipse cx="12" cy="18.2" rx="2.6" ry="3.6"/><ellipse cx="5.8" cy="12" rx="3.6" ry="2.6"/><ellipse cx="18.2" cy="12" rx="3.6" ry="2.6"/><circle cx="12" cy="12" r="2.4" fill="#FFE07A"/>',
|
||
t24: '<path d="M4 4h6v2.2a2 2 0 103.6 0V4H20v6h-2.2a2 2 0 100 3.6H20V20h-6v-2.2a2 2 0 10-3.6 0V20H4v-6.4h2.2a2 2 0 100-3.6H4z"/>',
|
||
t25: '<circle cx="12" cy="12" r="8.6"/><circle cx="9" cy="10" r="1.2" fill="rgba(0,0,0,.3)"/><circle cx="15" cy="10" r="1.2" fill="rgba(0,0,0,.3)"/><path d="M8 13.6c1.8 2.8 6.2 2.8 8 0" fill="none" stroke="rgba(0,0,0,.3)" stroke-width="1.6" stroke-linecap="round"/>',
|
||
t26: '<path d="M3 5h2.4l2.3 10.2h10.4L20.5 8H6.6"/><path d="M3 5h2.4l2.3 10.2h10.4L20.5 8H6.6" fill="none" stroke="#fff" stroke-width="1.8" stroke-linejoin="round"/><circle cx="9" cy="19" r="1.7"/><circle cx="16.5" cy="19" r="1.7"/>',
|
||
t27: '<rect x="3.5" y="9" width="17" height="11.5" rx="2"/><rect x="2.5" y="6" width="19" height="4" rx="1.5"/><path d="M12 6v14.5" stroke="rgba(0,0,0,.2)" stroke-width="1.6"/><path d="M12 6c-1.5-3.5-5.5-3-4 0M12 6c1.5-3.5 5.5-3 4 0" fill="none" stroke="#fff" stroke-width="1.6"/>',
|
||
t28: '<path d="M3 9.5l9-5.5 9 5.5V20H3z"/><rect x="7" y="13" width="4" height="4" rx=".8" fill="rgba(0,0,0,.18)"/><rect x="13" y="13" width="4" height="7" rx=".8" fill="rgba(0,0,0,.18)"/>',
|
||
t29: '<rect x="2.5" y="7.5" width="19" height="10" rx="5"/><path d="M7 10.5v4M5 12.5h4" stroke="rgba(0,0,0,.3)" stroke-width="1.5" stroke-linecap="round"/><circle cx="15.5" cy="11.3" r="1.1" fill="rgba(0,0,0,.3)"/><circle cx="17.8" cy="13.6" r="1.1" fill="rgba(0,0,0,.3)"/>',
|
||
t30: '<rect x="5" y="3.5" width="14" height="17.5" rx="2.5"/><rect x="9" y="2" width="6" height="3.4" rx="1.2" fill="rgba(0,0,0,.2)"/><path d="M8 9.5l1 1 2-2M8 14.5l1 1 2-2M13 9.8h3.5M13 14.8h3.5" fill="none" stroke="rgba(0,0,0,.28)" stroke-width="1.4" stroke-linecap="round"/>'
|
||
};
|
||
function csTI(x) { return CS_TI[x.id] ? '<svg viewBox="0 0 24 24" fill="#fff" aria-hidden="true">' + CS_TI[x.id] + '</svg>' : CS_ICO[x.group]; }
|
||
/* 头像:59 张人设照轮着取,同一张卡/行 3 个不重复,相邻两处也不撞(模拟,AGENTS.md 12b,12-31 复核) */
|
||
var CS_AVP = (function () { var a = [], i; for (i = 1; i <= 13; i++) a.push('k' + (i < 10 ? '0' : '') + i); for (i = 1; i <= 22; i++) a.push('m' + (i < 10 ? '0' : '') + i); for (i = 1; i <= 14; i++) a.push('p' + (i < 10 ? '0' : '') + i); for (i = 1; i <= 10; i++) a.push('s' + (i < 10 ? '0' : '') + i);
|
||
if (window.MB_AVA && MB_AVA.S.csStack) a = MB_AVA.S.csStack.slice(); /* 11-05 测试页头像叠改用分配表 csStack(30 个,只在测试页出现) */
|
||
for (i = a.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)), t = a[i]; a[i] = a[j]; a[j] = t; } return a; })();
|
||
var csSrc = function (c) { return /:|^\//.test(c) && window.MB_AVA ? MB_AVA.src(c, '../') : '../assets/img/mom/' + c + '.jpg'; };
|
||
var csAvK = 0;
|
||
function csAvs(n) { var h = '<span class="cav">'; for (var i = 0; i < n; i++) h += '<img src="' + csSrc(CS_AVP[csAvK++ % CS_AVP.length]) + '" alt="" loading="lazy">'; return h + '</span>'; }
|
||
var CS_SEC = { quiz: ['', '查漏补缺,温和掌握孕产育儿知识', 2], psy: ['', '看见情绪,也看见关系', 2], game: ['', '挑战一下,看能拿什么称号', 2], shop: ['', '测测你给娃买东西、挑东西是哪种风格', 2] };
|
||
/* 11-04 用户:「每个测试的背景图要做匹配的图片,不要同样的背景色;按组区分色块、组内统一」→ 每个测试一张插画(ceshi/cv/tNN.webp),
|
||
色调跟组走:常识小测暖桃 / 趣味心理薰衣草紫 / 趣味闯关薄荷绿 / 花钱风格天蓝;画面上半留白放标题。列表行的小方块也换成同一张图。 */
|
||
var CS_CV_V = 3; /* 同日二改:用户嫌插画乱 → 换真实风景照(按组选色调)+ 同色柔光遮罩 */
|
||
function csRowHTML(x, done, i) {
|
||
var d = done[x.id], who = (x.sub || '').split('·')[0].trim();
|
||
return '<button type="button" class="csr ' + CS_GPAL[x.group] + '" data-test="' + x.id + '"><span class="csr-i s' + (i % 3) + ' has-bg" style="background-image:url(ceshi/cv/' + x.id + '.webp?v=' + CS_CV_V + ')"></span>' +
|
||
'<span class="csr-m"><b>' + esc(x.title.replace(/^测一测|/, '')) + '</b><small>' + esc(who) + ' · ' + x.n + ' 题' + csAvs(3) + '<i>' + gcTestedText(x.id) + '</i></small></span>' +
|
||
'<em>' + (d ? '再测' : '去测') + '</em></button>';
|
||
}
|
||
var CS_PAL = ['pa', 'pb', 'pc', 'pd', 'pe', 'pf']; /* 6 套封面配色轮流:蜜桃 / 薰衣草 / 奶油蓝 / 浅紫 / 薄荷 / 杏橙 */
|
||
var CS_BLOB = '<svg class="cbl" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><path class="b1" d="M58 0C66 14 80 18 100 14V0z"/><path class="b2" d="M0 72C18 60 30 78 46 86S80 84 100 70V100H0z"/><path class="b3" d="M0 0H28C20 12 8 16 0 30z"/></svg>';
|
||
/* 11-04 用户:「封面下面那行完整标题放到图片上」→ 封面大字由短名改成完整标题,封面下只留人数 */
|
||
/* 11-04 用户:「几个模块颜色都一样,分不出来;图片样式可以一样,UI 按模块变一下」→ 配色 / 封面色块形状按分组走,不再全局轮换:
|
||
常识小测 蜜桃橙、趣味心理 薰衣草紫、趣味闯关 薄荷绿、花钱风格 天空蓝;四组各一种色块形状(CS_BLOBS),列表行同色。 */
|
||
var CS_GPAL = { quiz: 'gq', psy: 'gp', game: 'gg', shop: 'gs' };
|
||
var CS_BLOBS = {
|
||
quiz: CS_BLOB,
|
||
psy: '<svg class="cbl" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><circle class="b1" cx="86" cy="10" r="22"/><path class="b2" d="M0 78C22 70 40 92 62 88S90 74 100 80V100H0z"/><circle class="b3" cx="10" cy="24" r="12"/></svg>',
|
||
game: '<svg class="cbl" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><path class="b1" d="M70 0L100 0 100 34z"/><path class="b2" d="M0 100L0 70 34 100z M60 100L100 62 100 100z"/><path class="b3" d="M0 0H22L0 22z"/></svg>',
|
||
shop: '<svg class="cbl" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><rect class="b1" x="64" y="-8" width="44" height="30" rx="14"/><rect class="b2" x="-10" y="76" width="120" height="34" rx="16"/><rect class="b3" x="-6" y="6" width="26" height="14" rx="7"/></svg>'
|
||
};
|
||
/* 11-04 用户:「宫格卡随机几张,在『开始测试』下面、白边上面加一行『谁测出了什么结果』;有这行的卡底下不要头像,只留 N 人测过」
|
||
每组宫格(最多 6 张)随机挑 2~3 张(11-04 二改:1~2 张);昵称 / 头像同战报那批(模拟,AGENTS.md 12b),结果名取 meta.js GC_RES 真实结果名;同一屏昵称不重复 */
|
||
var ckHlUsed = [];
|
||
function ckHlLine(x) {
|
||
var rs = (window.GC_RES || {})[x.id]; if (!rs || !rs.length) return '';
|
||
var c = [], k; for (k = 0; k < CL_NM.length; k++) if (ckHlUsed.indexOf(k) < 0) c.push(k);
|
||
if (!c.length) { ckHlUsed = []; c = CL_NM.map(function (_, j) { return j; }); }
|
||
/* 一条备 3 句(3 个不同的人 + 不同结果),定时往上滚,同首页百宝箱 lv-i */
|
||
var it = [], n = Math.min(3, c.length), rr = rs.slice().sort(function () { return Math.random() - .5; });
|
||
while (it.length < n) {
|
||
k = c.splice(Math.floor(Math.random() * c.length), 1)[0]; ckHlUsed.push(k);
|
||
it.push('<span class="hl-i' + (it.length ? '' : ' on') + '"><img src="' + csSrc(CL_AV[k % CL_AV.length]) + '" alt="" loading="lazy"><u>' + esc(CL_NM[k]) + '</u><span>测出「' + esc(rr[it.length % rr.length]) + '」</span></span>');
|
||
}
|
||
return '<span class="ck-hl">' + it.join('') + '</span>';
|
||
}
|
||
var ckHlT = 0;
|
||
function ckHlRun() {
|
||
clearInterval(ckHlT);
|
||
ckHlT = setInterval(function () {
|
||
[].forEach.call(document.querySelectorAll('.ck-hl'), function (h, j) {
|
||
var l = h.children, i, cur = 0; if (l.length < 2) return;
|
||
for (i = 0; i < l.length; i++) if (l[i].classList.contains('on')) cur = i;
|
||
setTimeout(function () {
|
||
l[cur].classList.remove('on'); l[cur].classList.add('up');
|
||
var nx = l[(cur + 1) % l.length]; nx.classList.remove('up'); nx.classList.add('on');
|
||
setTimeout(function () { l[cur].classList.remove('up'); }, 500);
|
||
}, j * 600);
|
||
});
|
||
}, 3600);
|
||
}
|
||
function csCardHTML(x, done, i, hl) {
|
||
var d = done[x.id], who = (x.sub || '').split('·')[0].trim(), hs = hl ? ckHlLine(x) : '';
|
||
var top = byHot(TM).slice(0, 3).map(function (y) { return y.id; }).indexOf(x.id);
|
||
return '<button type="button" class="ck ' + CS_GPAL[x.group] + ' has-bg" data-test="' + x.id + '"><span class="cv"><img class="ck-bg" src="ceshi/cv/' + x.id + '.webp?v=' + CS_CV_V + '" alt="" loading="lazy" decoding="async"><i class="ck-wash"></i>' +
|
||
(top >= 0 ? '<i class="ck-top t' + (top + 1) + '">TOP' + (top + 1) + '</i>' : '') +
|
||
'<i class="ck-wm">' + csTI(x) + '</i><b>' + esc(x.title.replace(/^测一测|/, '')) + '</b><small>' + esc(who) + ' · ' + x.n + ' 题</small><em>' + (d ? '再测一次' : '开始测试') + '</em>' + (d ? '<i class="dn">已测</i>' : '') + hs + '</span>' +
|
||
'<span class="cnn">' + (hs ? '' : csAvs(3)) + '<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>' + gcTestedText(x.id) + '</span></button>';
|
||
}
|
||
/* ---------- 11-04 用户:「测试列表页太安静,要热闹、有创意」 ----------
|
||
① banner 下一条「此刻 N 人正在测」(红点呼吸、数字隔 2 秒小跳)+ 战报滚动「谁 刚测出「结果」· 哪个测试」(点了进那个测试);
|
||
② 右边「手气测」骰子:随机挑一个还没测过的测试,骰子转一下就进;
|
||
③ 卡片封面左上「● N 人在测」,隔几秒随机两张卡数字跳;全站最热 3 个封面右上 TOP1~3 角标;卡片进屏错落弹入、「开始测试」按钮定时扫光。
|
||
人数 / 昵称 / 头像都是模拟(同「N 人测过」口径,AGENTS.md 12b,12-31 复核);战报只写「测出了哪个结果」,结果名取 meta.js GC_RES(真实结果名)。 */
|
||
var CL_NM = ['小满妈妈', '糯米团子', '橙子不酸', '鹿鹿呀', '安安的妈', '豆包本包', '一只小葵', '阿圆', '栗子酱', '桃桃乌龙', '芝麻汤圆', '晴天娃娃',
|
||
'果冻布丁', '岁岁平安', '叮当妈', '饭团子', '奶糖不甜', '小鱼干', '朵朵妈咪', '暖暖', '布丁要长大', '花卷儿', '柚子茶', '星星的妈',
|
||
'甜甜圈', '小熊软糖', '一颗青梅', '冬冬妈', '可乐加冰', '麦穗儿', '云朵朵', '橘子汽水', '乐乐的妈', '荔枝', '蜜桃乌龙', '小葡萄'];
|
||
var CL_AV = ['p02', 'm05', 'p05', 'm12', 'k04', 'p09', 'm16', 'p11', 'm07', 'k10', 'p03', 'm19', 'p13', 'm02', 'k06', 'p06', 'm10', 'p12', 'm21', 'p07', 'm04', 'k12', 'p14', 'm15',
|
||
'p01', 'm01', 'k01', 'm03', 'p04', 'm06', 'k02', 'm08', 'p08', 'm09', 'k03', 'm11'];
|
||
/* 11-05 用户:各模块头像不要重复(原来这 36 人和首页百宝箱轮播是同一批)→ 改用分配表 csTicker 的 24 个人设,昵称 + 头像只在测试页出现 */
|
||
if (window.MB_AVA && MB_AVA.S.csTicker) { CL_NM = MB_AVA.S.csTicker.map(function (x) { return x[0]; }); CL_AV = MB_AVA.S.csTicker.map(function (x) { return x[1]; }); }
|
||
/* 11-04 用户:「手气测挺好玩,要明显、让用户玩起来」→ 独立一块「摇一摇」:骰子闲时晃一晃;点了骰子翻滚、标题像老虎机一样转、越转越慢停在一个没测过的测试上,撒彩点后进入 */
|
||
var DICE_P = { 1: [[12, 12]], 2: [[8, 8], [16, 16]], 3: [[7, 7], [12, 12], [17, 17]], 4: [[8, 8], [16, 8], [8, 16], [16, 16]], 5: [[7, 7], [17, 7], [12, 12], [7, 17], [17, 17]], 6: [[8, 6.5], [16, 6.5], [8, 12], [16, 12], [8, 17.5], [16, 17.5]] };
|
||
function diceSVG(n) {
|
||
return '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5.5" fill="#fff"/><rect x="2" y="17" width="20" height="5" rx="2.5" fill="#EDE6FF" opacity=".9"/>' +
|
||
DICE_P[n].map(function (c) { return '<circle cx="' + c[0] + '" cy="' + c[1] + '" r="2" fill="' + (n === 1 ? '#F0453A' : '#6A4BE0') + '"/>'; }).join('') + '</svg>';
|
||
}
|
||
function csNowBase() { return Math.round(TM.reduce(function (a, x) { return a + gcTested(x.id); }, 0) / 1150); }
|
||
function csLiveHTML() {
|
||
var left = TM.length - Object.keys(csDone()).filter(function (k) { return TM.some(function (x) { return x.id === k; }); }).length;
|
||
return '<button type="button" class="luck" id="csvGo"><span class="luck-dc" id="csdDc">' + diceSVG(5) + '</span><span class="luck-dc d2">' + diceSVG(3) + '</span>' +
|
||
'<span class="luck-t"><b>不知道测哪个?摇一下</b><span class="luck-w"><span id="csdW">' + (left > 0 ? '还有 ' + left + ' 个没测过,交给手气' : '全部测完啦,再摇一个重温') + '</span></span></span>' +
|
||
'<em class="luck-b">摇一摇</em><i class="luck-fx" id="csdFx"></i></button>' +
|
||
'<div class="csv"><div class="csv-n"><i class="csv-dot"></i>此刻 <b id="csvN" class="num">' + csNowBase().toLocaleString() + '</b> 人正在测<span class="csv-av" id="csvAv">' + csAvs(5) + '</span></div>' +
|
||
'<div class="csv-r" id="csvR"></div></div>';
|
||
}
|
||
/* 11-04 用户:「往下滑时『摇一摇』浮在最上面,让用户随时能用」→ 大卡滑出屏幕后,顶栏下面浮一条小的摇一摇(点了同样全屏摇号) */
|
||
var luckIO = null;
|
||
function luckFloat() {
|
||
var fl = document.getElementById('luckFl');
|
||
if (!fl) {
|
||
fl = document.createElement('button'); fl.type = 'button'; fl.id = 'luckFl'; fl.className = 'luck-fl';
|
||
fl.innerHTML = '<span class="luck-fl-d">' + diceSVG(5) + '</span><b>不知道测哪个?</b><em>摇一摇</em>';
|
||
fl.addEventListener('click', function () { var g = document.getElementById('csvGo'); if (g) csdRoll(g); });
|
||
document.body.appendChild(fl);
|
||
}
|
||
var tg = document.getElementById('csvGo'); if (!tg || !('IntersectionObserver' in window)) return;
|
||
if (luckIO) luckIO.disconnect();
|
||
luckIO = new IntersectionObserver(function (es) {
|
||
var e = es[0], nav = document.querySelector('#top .nav'), b = nav ? nav.getBoundingClientRect().bottom : 56;
|
||
fl.style.top = (Math.max(0, b) + 8) + 'px';
|
||
fl.classList.toggle('on', catF === 'ceshi' && !e.isIntersecting && e.boundingClientRect.top < b + 10);
|
||
}, { threshold: 0, rootMargin: '-60px 0px 0px 0px' });
|
||
luckIO.observe(tg);
|
||
}
|
||
var csdBusy = false;
|
||
/* 11-04 用户:「点摇一摇,整个页面上浮出一个动态效果,结束后再跳到那个测试」→ 全屏浮层:两颗大骰子翻滚 + 老虎机转测试名(越转越慢)→ 落定弹出那个测试的卡(分组配色 + 专属图标)+ 全屏撒彩纸 → 进入 */
|
||
/* 11-04 用户:「摇一摇的动效要有音效」→ Web Audio 现合成(不加音频文件):开摇骰子哗啦声、转名字每格一下「嗒」、落定「叮咚」+ 彩纸「啵」;
|
||
右上角喇叭可关,记在 mmbox.gc.snd。用户点按钮时才建 AudioContext(微信 / iOS 要求用户手势后才能出声)。 */
|
||
var SND = { ctx: null, on: true };
|
||
try { SND.on = localStorage.getItem('mmbox.gc.snd') !== '0'; } catch (e) {}
|
||
function sndCtx() {
|
||
if (!SND.on) return null;
|
||
try { if (!SND.ctx) SND.ctx = new (window.AudioContext || window.webkitAudioContext)(); if (SND.ctx.state === 'suspended') SND.ctx.resume(); } catch (e) { return null; }
|
||
return SND.ctx;
|
||
}
|
||
function tone(f, t0, d, type, vol, f2) {
|
||
var c = sndCtx(); if (!c) return;
|
||
var o = c.createOscillator(), g = c.createGain(), t = c.currentTime + (t0 || 0);
|
||
o.type = type || 'sine'; o.frequency.setValueAtTime(f, t); if (f2) o.frequency.exponentialRampToValueAtTime(f2, t + d);
|
||
g.gain.setValueAtTime(0, t); g.gain.linearRampToValueAtTime(vol || .2, t + .008); g.gain.exponentialRampToValueAtTime(.0008, t + d);
|
||
o.connect(g); g.connect(c.destination); o.start(t); o.stop(t + d + .02);
|
||
}
|
||
function noise(t0, d, vol, hp) {
|
||
var c = sndCtx(); if (!c) return;
|
||
var n = Math.floor(c.sampleRate * d), buf = c.createBuffer(1, n, c.sampleRate), ch = buf.getChannelData(0);
|
||
for (var i = 0; i < n; i++) ch[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / n, 3);
|
||
var s = c.createBufferSource(), f = c.createBiquadFilter(), g = c.createGain(), t = c.currentTime + (t0 || 0);
|
||
s.buffer = buf; f.type = 'bandpass'; f.frequency.value = hp || 2400; f.Q.value = 1.2; g.gain.value = vol || .3;
|
||
s.connect(f); f.connect(g); g.connect(c.destination); s.start(t);
|
||
}
|
||
var SFX = {
|
||
rattle: function () { for (var i = 0; i < 9; i++) noise(i * .045 + Math.random() * .02, .05, .35, 1800 + Math.random() * 1600); }, /* 骰子在杯里哗啦 */
|
||
tick: function (k) { tone(1250 + (k % 2) * 180, 0, .05, 'square', .05); noise(0, .025, .12, 3500); }, /* 转名字「嗒」 */
|
||
land: function () { tone(784, 0, .5, 'triangle', .22); tone(1175, .1, .7, 'triangle', .2); tone(1568, .2, .9, 'sine', .12); noise(.02, .18, .25, 900); }, /* 叮咚 + 啵 */
|
||
tap: function () { tone(660, 0, .08, 'sine', .12, 990); }
|
||
};
|
||
/* 11-04 用户:「摇出来以后两个选择:『就它了』或者重新摇」→ 落定后不再自动跳,给两个按钮;重新摇避开刚摇出的那个 */
|
||
function csdRoll(btn) {
|
||
if (csdBusy) return; csdBusy = true; haptic(); if (btn) btn.classList.add('roll');
|
||
var dn = csDone(), last = null, pk = null;
|
||
var ov = document.createElement('div'); ov.className = 'lko';
|
||
ov.innerHTML = '<div class="lko-bg"></div><button type="button" class="lko-x" aria-label="关闭">×</button><button type="button" class="lko-snd' + (SND.on ? '' : ' off') + '" aria-label="音效开关"></button>' +
|
||
'<div class="lko-in"><div class="lko-dc"><span class="a">' + diceSVG(6) + '</span><span class="b">' + diceSVG(3) + '</span></div>' +
|
||
'<p class="lko-tip">手气摇号中…</p><div class="lko-reel"><span id="lkoR">?</span></div><div class="lko-card" id="lkoC"></div>' +
|
||
'<div class="lko-act"><button type="button" class="lko-go">就它了,去测 ›</button><button type="button" class="lko-re">' + diceSVG(5) + '重新摇</button></div></div><div class="lko-fx" id="lkoFx"></div>';
|
||
document.body.appendChild(ov); void ov.offsetWidth; ov.classList.add('on');
|
||
var R = ov.querySelector('#lkoR'), dcs = ov.querySelectorAll('.lko-dc span');
|
||
function close() { ov.classList.remove('on'); setTimeout(function () { if (ov.parentNode) ov.parentNode.removeChild(ov); }, 260); csdBusy = false; if (btn) btn.classList.remove('roll', 'hit'); }
|
||
function roll() {
|
||
var pool = TM.filter(function (x) { return !dn[x.id] && x !== last; }); if (!pool.length) pool = TM.filter(function (x) { return x !== last; });
|
||
pk = pool[Math.floor(Math.random() * pool.length)];
|
||
var i = 0, steps = 18;
|
||
ov.classList.remove('hit', 'done'); ov.querySelector('.lko-tip').textContent = '手气摇号中…'; ov.querySelector('#lkoC').innerHTML = ''; ov.querySelector('#lkoFx').innerHTML = '';
|
||
SFX.rattle();
|
||
setTimeout(function spin() {
|
||
var end = i >= steps, t = end ? pk : TM[Math.floor(Math.random() * TM.length)];
|
||
R.className = ''; void R.offsetWidth; R.className = end ? 'hit' : 'sp'; R.textContent = CS_SHORT[t.id] || t.title;
|
||
[].forEach.call(dcs, function (d) { d.innerHTML = diceSVG(1 + Math.floor(Math.random() * 6)); });
|
||
if (!end) { SFX.tick(i); if (i % 3 === 0 && navigator.vibrate) try { navigator.vibrate(8); } catch (e) {} i++; setTimeout(spin, 45 + i * i * 1.15); return; }
|
||
ov.classList.add('hit'); haptic(); SFX.land();
|
||
ov.querySelector('.lko-tip').textContent = '摇到了!';
|
||
ov.querySelector('#lkoC').innerHTML = '<div class="ck ' + CS_GPAL[pk.group] + '"><span class="cv">' + (CS_BLOBS[pk.group] || CS_BLOB) + '<i class="ck-wm">' + csTI(pk) + '</i><i class="lko-ic">' + csTI(pk) + '</i>' +
|
||
'<b>' + esc(pk.title.replace(/^测一测|/, '')) + '</b><small>' + TG[pk.group] + ' · ' + pk.n + ' 题</small></span></div>';
|
||
var fx = ov.querySelector('#lkoFx'), cols = ['#FF8A65', '#9A7FE0', '#3FAE7A', '#4E8DE6', '#FFC94D', '#F0453A', '#FF8FB1'], h = '';
|
||
for (var k = 0; k < 46; k++) {
|
||
var ag = Math.random() * 6.283, r = 120 + Math.random() * 200;
|
||
h += '<i style="--x:' + Math.round(Math.cos(ag) * r) + 'px;--y:' + Math.round(Math.sin(ag) * r - 60) + 'px;--r:' + Math.round(Math.random() * 720) + 'deg;background:' + cols[k % 7] + ';animation-delay:' + Math.round(Math.random() * 120) + 'ms;' + (k % 3 ? '' : 'border-radius:50%;') + '"></i>';
|
||
}
|
||
fx.innerHTML = h;
|
||
setTimeout(function () { ov.classList.add('done'); }, 380); /* 卡片弹完再出按钮 */
|
||
last = pk;
|
||
}, 260);
|
||
}
|
||
ov.addEventListener('click', function (e) {
|
||
if (e.target.closest('.lko-go')) { SFX.tap(); location.href = ceshiURL(pk.id, true); return; }
|
||
if (e.target.closest('.lko-re')) { if (!ov.classList.contains('done')) return; haptic(); roll(); return; }
|
||
if (e.target.closest('.lko-x')) { close(); return; }
|
||
var sb = e.target.closest('.lko-snd');
|
||
if (sb) { SND.on = !SND.on; sb.classList.toggle('off', !SND.on); try { localStorage.setItem('mmbox.gc.snd', SND.on ? '1' : '0'); } catch (x) {} if (SND.on) SFX.tap(); }
|
||
});
|
||
roll();
|
||
}
|
||
window.addEventListener('pageshow', function () { csdBusy = false; [].forEach.call(document.querySelectorAll('.lko'), function (o) { o.parentNode.removeChild(o); }); var b = document.getElementById('csvGo'); if (b) { b.classList.remove('roll', 'hit'); var bb = b.querySelector('.luck-b'); if (bb) bb.textContent = '摇一摇'; } });
|
||
var csvT = 0, csvI = 0, csvRec = [], csvRecT = [];
|
||
function csvOne() {
|
||
var R = window.GC_RES || {}, ids = TM.filter(function (x) { return R[x.id] && R[x.id].length; });
|
||
if (!ids.length) return '';
|
||
var tp = ids.filter(function (x) { return csvRecT.indexOf(x.id) < 0; }); if (tp.length) ids = tp;
|
||
var t = ids[Math.floor(Math.random() * ids.length)], rs = R[t.id], r = rs[Math.floor(Math.random() * rs.length)], k, c = [];
|
||
csvRecT.push(t.id); if (csvRecT.length > 6) csvRecT.shift(); /* 最近 6 条不出同一个测试 */
|
||
for (k = 0; k < CL_NM.length; k++) if (csvRec.indexOf(k) < 0) c.push(k);
|
||
k = c[Math.floor(Math.random() * c.length)]; csvRec.push(k); if (csvRec.length > 14) csvRec.shift(); /* 同屏 3 行 + 最近 14 个人不重复 */
|
||
return '<button type="button" class="csv-i" data-test="' + t.id + '"><img src="' + csSrc(CL_AV[k]) + '" alt="" width="22" height="22">' +
|
||
'<span><em>' + esc(CL_NM[k]) + '</em>刚测出<b>「' + esc(r) + '」</b></span><small>' + esc(CS_SHORT[t.id] || '') + '</small></button>';
|
||
}
|
||
/* 11-04 用户:「此刻正在测下面一行太少,最多三行滚动」→ 同屏 3 行,新的一条从底下推上来,最上面那条淡出 */
|
||
var CSV_H = 30;
|
||
function csvLay(b) { [].forEach.call(b.querySelectorAll('.csv-i:not(.gone)'), function (el, i) { el.style.transform = 'translateY(' + i * CSV_H + 'px)'; el.style.opacity = i > 2 ? 0 : 1; }); }
|
||
function csLiveRun() {
|
||
clearInterval(csvT);
|
||
var box = $('#csvR'); if (!box) return;
|
||
box.innerHTML = csvOne() + csvOne() + csvOne(); csvLay(box);
|
||
var base = csNowBase(), n = base, tick = 0, seen = [n], goal = base, lo = Math.round(base * .9), hi = Math.round(base * 1.1);
|
||
csvT = setInterval(function () {
|
||
if (document.hidden || !document.getElementById('csvR')) return;
|
||
tick++;
|
||
if (tick % 2 === 0) { /* 每 2.6 秒推上来一条 */
|
||
var b = document.getElementById('csvR'), first = b.querySelector('.csv-i:not(.gone)');
|
||
b.insertAdjacentHTML('beforeend', csvOne());
|
||
var nw = b.lastElementChild; nw.style.transform = 'translateY(' + 3 * CSV_H + 'px)'; nw.style.opacity = 0; void nw.offsetWidth;
|
||
if (first) { first.classList.add('gone'); first.style.transform = 'translateY(' + -CSV_H + 'px)'; first.style.opacity = 0; setTimeout(function () { if (first.parentNode) first.parentNode.removeChild(first); }, 500); }
|
||
csvLay(b);
|
||
}
|
||
if (tick % 3 === 0) { /* 头像堆换一个人 */
|
||
var av = document.querySelectorAll('#csvAv img'); if (av.length) { var im = av[Math.floor(Math.random() * av.length)]; im.classList.add('sw'); setTimeout(function () { im.src = csSrc(CS_AVP[csAvK++ % CS_AVP.length]); im.classList.remove('sw'); }, 220); }
|
||
}
|
||
/* 11-05 用户:「数字别在短时间里重复,不要 1300、1301、1305 来回跳」→ 每次变 6~38 人,大体朝一个会换的目标值走(有涨有落);
|
||
最近 20 次(约 26 秒)出现过的数,±2 以内都不再出;范围放到基数的 ±10% */
|
||
if (!(tick % 12) || Math.abs(goal - n) < 10) goal = lo + Math.floor(Math.random() * (hi - lo));
|
||
for (var tr = 0, c; tr < 40; tr++) {
|
||
var dir = Math.random() < .72 ? (goal >= n ? 1 : -1) : (goal >= n ? -1 : 1), d = 6 + Math.floor(Math.random() * 33);
|
||
c = n + dir * d; if (c > hi || c < lo) c = n - dir * d; /* 出界就往回走,不贴着边界(贴边会反复出同一个数) */
|
||
if (!seen.some(function (v) { return Math.abs(v - c) <= 2; })) break;
|
||
}
|
||
n = c; seen.push(n); if (seen.length > 20) seen.shift();
|
||
var e = document.getElementById('csvN'); if (e) { e.textContent = n.toLocaleString(); e.classList.remove('bp'); void e.offsetWidth; e.classList.add('bp'); }
|
||
}, 1300);
|
||
}
|
||
function csFx() { /* 卡片进屏错落弹入 */
|
||
var els = document.querySelectorAll('#more .ck, #more .csr');
|
||
if (!('IntersectionObserver' in window)) return;
|
||
var io = new IntersectionObserver(function (es) {
|
||
var k = 0;
|
||
es.forEach(function (e) { if (!e.isIntersecting) return; e.target.style.animationDelay = (k++ * 70) + 'ms'; e.target.classList.add('pop-in'); io.unobserve(e.target); });
|
||
}, { threshold: .15 });
|
||
[].forEach.call(els, function (el) { el.classList.add('pre'); io.observe(el); });
|
||
}
|
||
function ceshiListHTML() {
|
||
var done = csDone(), gs = ['quiz', 'psy', 'game', 'shop'].filter(function (g) { return !tGrp || tGrp === g; }), k = 0; csAvK = 0; ckHlUsed = [];
|
||
return '<div class="csl">' + gs.map(function (g, gi) {
|
||
var l = byHot(TM.filter(function (x) { return x.group === g; })); if (!l.length) return '';
|
||
var c = CS_SEC[g], nc = Math.min(6, l.length - l.length % 2);
|
||
return (gi ? '<div class="csd"><span>' + (gi === 1 && !tGrp ? '点上方标签,可以只看某一类' : '继续往下看') + '</span></div>' : '') +
|
||
'<section class="csg g-' + g + '"><i class="csg-deco" aria-hidden="true">' + CS_ICO[g] + '</i><div class="csg-h"><b><i class="csg-ic">' + CS_ICO[g] + '</i>' + TG[g] + '<span class="csg-n">' + csAvs(4) + Math.round(l.reduce(function (a, x) { return a + gcTested(x.id); }, 0) / 1e4) + ' 万人测过</span></b><small>' + c[1] + '</small></div>' +
|
||
'<div class="ckg c2">' + (function () {
|
||
var ix = l.slice(0, nc).map(function (_, j) { return j; }).sort(function () { return Math.random() - .5; }).slice(0, nc >= 4 ? 1 + Math.floor(Math.random() * 2) : 1); /* 11-04 二改:每组 1~2 张,最多 2 */
|
||
return l.slice(0, nc).map(function (x, j) { return csCardHTML(x, done, k++, ix.indexOf(j) >= 0); }).join('');
|
||
})() + '</div>' +
|
||
(l.length > nc ? '<div class="csrl">' + l.slice(nc).map(function (x) { return csRowHTML(x, done, k++); }).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]; }));
|
||
/* 11-03 参考图:顶部一排分类小方签(不写数量),选中的高亮 */
|
||
fh.innerHTML = '<div class="cst">' + all.map(function (x) { return '<button type="button" data-tg="' + x[0] + '"' + (tGrp === x[0] ? ' class="on"' : '') + '>' + x[1] + '</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; }));
|
||
}
|
||
/* 选中标签时,标签下一行露出这一类里的 2~3 个热门话题(带 hot 的排前,没帖子的不出),点了进话题页 */
|
||
function gtpPaint() {
|
||
var bx = document.getElementById('gtp'); if (!bx) return;
|
||
var ids = tagF && GTBY[tagF];
|
||
if (!ids) { bx.innerHTML = ''; bx.hidden = true; return; }
|
||
var tl = hotList().filter(function (x) { return ids.indexOf(x.id) >= 0 && NOTES.some(function (n) { return n.t === x.id; }); }).slice(0, 3);
|
||
bx.hidden = !tl.length;
|
||
bx.innerHTML = '<span class="gtp-h">热门话题</span>' + tl.map(function (x) { return '<button type="button" data-t="' + x.id + '">#' + esc(x.name) + '#</button>'; }).join('');
|
||
}
|
||
/* ---------- 「谁的笔记上了广场」轮播(11-07) ---------- */
|
||
var rwI = 0, rwT = null;
|
||
function rwList() {
|
||
var real = NOTES.filter(function (n) { return n.real; }).slice(0, 10);
|
||
var pick = NOTES.filter(function (n) { return !n.real && n.photo; }).sort(function (a, b) { return b.likes - a.likes; });
|
||
var seen = {}, mock = [];
|
||
pick.forEach(function (n) { if (mock.length < 12 && !seen[n.author]) { seen[n.author] = 1; mock.push(n); } });
|
||
return real.concat(mock);
|
||
}
|
||
function rwItem(k) {
|
||
var L = rwList(); if (!L.length) return '';
|
||
var n = L[k % L.length], tt = n.title.length > 14 ? n.title.slice(0, 13) + '…' : n.title;
|
||
return '<button type="button" class="rwi" data-id="' + esc(n.id) + '"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span><b>' + esc(n.author) + '</b> 的《' + esc(tt) + '》' +
|
||
(n.real ? '<em>投稿上了广场</em>' : '<em>入选精选</em>') + '</span></button>';
|
||
}
|
||
function rwRun() {
|
||
clearInterval(rwT); rwI = 0;
|
||
if (rwList().length < 2) return;
|
||
rwT = setInterval(function () {
|
||
var box = document.getElementById('rwv'); if (!box) { clearInterval(rwT); return; }
|
||
if (document.hidden || openId) return;
|
||
var old = box.firstElementChild; rwI++;
|
||
box.insertAdjacentHTML('beforeend', rwItem(rwI));
|
||
var nw = box.lastElementChild; nw.classList.add('in'); void nw.offsetWidth;
|
||
nw.classList.remove('in'); if (old) { old.classList.add('out'); setTimeout(function () { if (old.parentNode) old.remove(); }, 420); }
|
||
}, 3200);
|
||
}
|
||
function renderHead() {
|
||
var t = TBY[cur], el = $('#head'), fh = $('#fh');
|
||
var fl0 = document.getElementById('luckFl'); if (fl0) fl0.classList.remove('on');
|
||
if (catF === 'ceshi') { el.innerHTML = cbnHTML('ceshi') + csLiveHTML(); ceshiFh(fh); csLiveRun(); luckFloat(); return; } /* 原一行介绍 ceshiHead 并进 banner */
|
||
if (!t && !catF) {
|
||
/* 11-05 用户:「职场那些标签和上面的话题整合到一个里面,感觉有点乱」→ 选方案 A:「全部」下去掉「热门话题」整块,
|
||
标签作为唯一入口(末尾加「全部话题 ›」);选中标签时标签下露出这一类的 2~3 个热门话题(用户同意);投稿奖励一行挪到「大家在聊」上面。
|
||
话题本身不变:投稿选话题、帖子卡上的 #话题#、话题详情页照旧。分类视图(catF)仍是原来的热门话题列表。 */
|
||
el.innerHTML = qifuHTML() +
|
||
'<div class="rww"><div class="rwc"><svg class="ic"><use href="#i-gift"/></svg><div class="rwv" id="rwv">' + rwItem(0) + '</div><button type="button" class="rwb" data-rule="1">我也投稿</button></div></div>';
|
||
rwRun();
|
||
fh.className = 'shtg';
|
||
fh.innerHTML = '<div class="sh"><h2>大家在聊</h2><small>孕妈们的分享</small></div>' +
|
||
'<div class="gtg"><button type="button" data-tag=""' + (tagF ? '' : ' class="on"') + '>全部</button>' +
|
||
GTAGS.map(function (g) { return '<button type="button" data-tag="' + g[0] + '"' + (tagF === g[0] ? ' class="on"' : '') + '>' + g[0] + '</button>'; }).join('') +
|
||
'<button type="button" class="gall" data-all="1">全部话题 ›</button></div><div class="gtp" id="gtp" hidden></div>';
|
||
gtpPaint();
|
||
return;
|
||
}
|
||
if (!t) {
|
||
var hl = hotList();
|
||
el.innerHTML = (catF ? cbnHTML(catF) : qifuHTML()) + /* 祈福树只在「全部」 */
|
||
'<div class="sh"><svg class="fire"><use href="#i-fire"/></svg><h2>热门话题</h2><button type="button" class="more" data-all="1">全部<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">查看全部话题 ›</button></div>';
|
||
if (catF) { fhLevels(fh); return; }
|
||
/* 11-03 用户:广场里不显示具体有多少篇、多少个话题 → 篇数 / 话题数一律不露
|
||
11-05 用户:「大家都在聊下面加一些标签,比如职场、护肤经验,再加一些别的」→ 标题下一行横滑标签,点了只看这类帖子(GTAGS 按话题归类) */
|
||
fh.className = 'shtg';
|
||
fh.innerHTML = '<div class="sh"><h2>大家在聊</h2><small>孕妈们的分享</small></div>' +
|
||
'<div class="gtg"><button type="button" data-tag=""' + (tagF ? '' : ' class="on"') + '>全部</button>' +
|
||
GTAGS.map(function (g) { return '<button type="button" data-tag="' + g[0] + '"' + (tagF === g[0] ? ' class="on"' : '') + '>' + g[0] + '</button>'; }).join('') + '</div>';
|
||
var gon = fh.querySelector('.gtg .on'); if (gon && tagF) fh.querySelector('.gtg').scrollLeft = Math.max(0, gon.offsetLeft - 60);
|
||
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>话题</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>';
|
||
}
|
||
/* 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>' +
|
||
(cur ? '<button type="button" class="ba" data-t="">看这块全部 ›</button>' : '') + '</div>' +
|
||
'<div class="tcs"><button type="button" data-t=""' + (cur ? '' : ' class="on"') + '>全部</button>' +
|
||
tl.map(function (x) { return '<button type="button" data-t="' + x.id + '"' + (cur === x.id ? ' class="on"' : '') + '>#' + esc(x.name) + '#</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]); });
|
||
var tagOn = !cur && !catF && tagF && GTBY[tagF];
|
||
if (tagOn) list = list.filter(function (n) { return GTBY[tagF].indexOf(n.t) >= 0; });
|
||
/* 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% */
|
||
/* 11-04 用户:「从孕期百宝箱点进来的孕期百问 / 计算器 / 趣味小测试,最上边都要是孕期百宝箱」→ 小程序顶栏取 document.title */
|
||
document.title = catF === 'ceshi' ? '孕期百宝箱' : '孕妈广场';
|
||
if (catF === 'ceshi') {
|
||
$('#more').innerHTML = ceshiListHTML(); csFx(); ckHlRun(); return;
|
||
}
|
||
/* 「全部」信息流:穿插测试卡 */
|
||
/* 11-05 用户:点「花钱囤货」标签时植入「带娃花钱」测试卡,放第 2 位 */
|
||
var TAG_TEST = { '花钱囤货': 't29' };
|
||
if (tagOn && TAG_TEST[tagF] && TMBY[TAG_TEST[tagF]]) { dn = csDone(); list.splice(Math.min(1, list.length), 0, { test: TMBY[TAG_TEST[tagF]] }); }
|
||
if (!cur && !catF && !tagOn && TM.length) {
|
||
var dn = csDone(), mixed = [], ci = 0;
|
||
/* 测试卡:先出 CS_MIX 精选,再按热度轮完其余测试。
|
||
11-03 用户:「笔记里测一测减少一些,已经有测一测模块了」→ 原来第 3 位起每 8 张插 1 张(约 20 张),改成第 6 位起每 30 张插 1 张、最多 3 张 */
|
||
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 >= 6 && (k - 6) % 30 === 0 && ci < 3) { var tid = csq[ci++ % csq.length]; if (TMBY[tid]) mixed.push({ test: TMBY[tid] }); } mixed.push(n); });
|
||
list = [{ mine: 1 }].concat(PIN_ON ? [{ pin: 1 }] : [], mixed); /* 11-07 置顶笔记「孕妈悄悄话」 */
|
||
}
|
||
/* 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));
|
||
else if (n.pin) specials.push(pinHTML());
|
||
});
|
||
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.pin) { add(specials[si], 1, spH[si++]); lastTx[1] = false; 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));
|
||
});
|
||
if (PIN_ON) setTimeout(whRoll, 0);
|
||
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) {
|
||
mo.innerHTML = '<button type="button" class="mo k-' + tc.cat + '" data-t=""><small>这个话题就这些啦</small><b>广场里还有更多分享,去看看 ›</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 = ''; /* 11-03 分类标签取消:进话题时顶部停在「全部」 */
|
||
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 catF === 'ceshi' ? ['ceshi'] : 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 gt = e.target.closest('[data-tag]');
|
||
if (gt) {
|
||
if (gt.dataset.tag === tagF) return;
|
||
tagF = gt.dataset.tag; haptic();
|
||
var gl = $('#fh .gtg'), sl0 = gl ? gl.scrollLeft : 0;
|
||
[].forEach.call(gl.children, function (x) { x.classList.toggle('on', x.dataset.tag === tagF); });
|
||
gl.scrollLeft = sl0; gtpPaint(); renderFeed();
|
||
var sc0 = $('#sc'), fhT = $('#fh').offsetTop - 8; if (sc0.scrollTop > fhT) sc0.scrollTop = fhT; /* 已经往下滑了的话,回到标签这一行 */
|
||
return;
|
||
}
|
||
if (e.target.closest('[data-all]')) { haptic(); openTopics(); return; }
|
||
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 cb = e.target.closest('.cbn[data-test], .csv-i[data-test]'); if (cb) { haptic(); location.href = ceshiURL(cb.dataset.test, true); return; }
|
||
var dc = e.target.closest('#csvGo'); if (dc) { csdRoll(dc); return; }
|
||
var j = e.target.closest('[data-join]'); if (j) { haptic(); openRule(j.dataset.join); return; }
|
||
if (e.target.closest('[data-rule]')) { openRule(''); return; }
|
||
var rw = e.target.closest('.rwi[data-id]'); if (rw) { haptic(); openNote(rw.dataset.id, true); 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) + '</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></span>' + (t.hot ? '<i>热</i>' : '') + '</button>';
|
||
}).join('') + '</div>';
|
||
};
|
||
/* 11-05 用户:全部话题固定顺序 经验 → 家庭婚姻 → 职场(不再把当前分类提到最前;别处的 CAT_ORDER 不动) */
|
||
openSheet('topics', '<h3>全部话题</h3>' + ['baby', 'family', 'work'].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) {
|
||
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>' +
|
||
(c.t ? '<p class="ci-t">' + cpT(c.t) + '</p>' : '') + cpH(c.img) + (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>' +
|
||
(c.t ? '<p class="ci-t">' + cpT(c.t) + '</p>' : '') + cpH(c.img) + '<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, img: c.images, 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;
|
||
if (n.pin) return openPin(n, push);
|
||
$('#dt').classList.remove('is-pin');
|
||
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 = ''; if (CP) CP.clear(); $('#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));
|
||
}
|
||
/* 11-07 置顶笔记「孕妈悄悄话」详情:夜空封面(点「去星空看看」进首页星空页)+ 说明 + 留言区(同普通笔记,先审后发) */
|
||
var PIN_PH = '对宝宝说一句悄悄话…';
|
||
function openPin(n, push) {
|
||
openId = n.id;
|
||
var th = PIN_TH, l = WHD ? (WHD.list || []).filter(function (x) { return !x.mine; }) : [];
|
||
$('#dt').classList.add('is-pin');
|
||
$('#dav').src = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#3E2F5E"/><stop offset="1" stop-color="#6B4AA8"/></linearGradient></defs><circle cx="20" cy="20" r="20" fill="url(#g)"/><path transform="translate(10 10)" d="M10 .5C10.9 7.4 12.6 9.1 19.5 10 12.6 10.9 10.9 12.6 10 19.5 9.1 12.6 7.4 10.9.5 10 7.4 9.1 9.1 7.4 10 .5Z" fill="#FFE2B8"/></svg>');
|
||
$('#dnm').textContent = '孕妈悄悄话';
|
||
$('#dst').textContent = th ? '本周话题 · ' + th.name : '';
|
||
$('#dsc').innerHTML = '<div class="dcv">' + pinCoverHTML(th, l, pinSky(), true) + '</div>' +
|
||
'<div class="dbody"><h2>每一颗星星,都是一位孕妈的一句话</h2><div class="tx">' +
|
||
'<p>这周的话题是「' + esc(th ? th.name : '说给宝宝听的悄悄话') + '」。' + esc(th && th.tip ? th.tip + '。' : '') + '</p>' +
|
||
'<p>在下面留言区写一句,审核通过后大家都能看到。点赞多的悄悄话会挂上星空,变成一颗星星,同孕周的妈妈点一下,就能看到它像流星一样划过。</p>' +
|
||
'<p>一天最多说 3 句,每一句都会被认真对待。</p></div>' +
|
||
'<div class="tm">孕妈悄悄话 · 置顶</div></div>' +
|
||
'<div class="cm" id="cmw"><div class="cm-h" id="cmh"></div>' +
|
||
'<div class="cm-in"><span class="me">我</span><button type="button" id="cmgo">' + PIN_PH + '</button></div>' +
|
||
'<div id="cml"></div><div class="cm-end">— 没有更多悄悄话了 —</div></div>';
|
||
renderComments(n); syncBar(n); loadRC(n); whRoll();
|
||
$('#cin').value = ''; $('#cin').placeholder = PIN_PH; if (CP) CP.clear(); $('#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: n.id }, '', setQuery(cur, n.id)); pushed = true; }
|
||
else history.replaceState(history.state, '', setQuery(cur, n.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 = (NBY[openId] || {}).pin ? PIN_PH : '说点什么…'; $('#cin').focus(); }
|
||
if (e.target.closest('[data-star]')) { haptic(); var q = new URLSearchParams(location.search); ['t', 'n', 'c'].forEach(function (k) { q.delete(k); }); q.set('wh', '1'); location.href = '../?' + q + location.hash; }
|
||
});
|
||
$('#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');
|
||
/* 11-05 评论 / 回复可带图(最多 3 张,js/cm-pics.js):选了图底栏保持展开,只有图没有字也能发 */
|
||
var CP = window.MBCmPics ? MBCmPics.picker({ strip: $('#cmPics'), emoPanel: $('#cmEmo'), toast: toast, onChange: function () { $('#csend').disabled = !canSend(); $('#cemo').classList.toggle('on', CP.hasEmo() || CP.emoOpen()); if (CP.count() || CP.emoOpen()) $('#bar').classList.add('typing'); } }) : null;
|
||
var canSend = function () { return !!cin.value.trim() || !!(CP && CP.count()); };
|
||
if (CP) { $('#cpic').innerHTML = MBCmPics.ICON; $('#cpic').addEventListener('mousedown', function (e) { e.preventDefault(); }); $('#cpic').addEventListener('click', function (e) { e.preventDefault(); $('#bar').classList.add('typing'); CP.pick(); }); }
|
||
if (CP) { $('#cemo').innerHTML = MBCmPics.EMO_ICON; $('#cemo').addEventListener('mousedown', function (e) { e.preventDefault(); }); $('#cemo').addEventListener('click', function (e) { e.preventDefault(); $('#bar').classList.add('typing'); CP.toggleEmo(); }); }
|
||
else { $('#cpic').remove(); $('#cemo').remove(); }
|
||
cin.addEventListener('focus', function () { $('#bar').classList.add('typing'); });
|
||
cin.addEventListener('blur', function () { setTimeout(function () { if (!canSend() && !(CP && CP.emoOpen())) { $('#bar').classList.remove('typing'); REPLY = null; cin.placeholder = (NBY[openId] || {}).pin ? PIN_PH : '说点什么…'; } }, 120); });
|
||
cin.addEventListener('input', function () { $('#csend').disabled = !canSend(); });
|
||
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 || !canSend() || send.busy) return;
|
||
if (CP && CP.busy()) { toast('图片还在上传,稍等一下'); return; }
|
||
var imgs = CP ? CP.urls() : [], emo = CP ? CP.emoji() : '';
|
||
if (!v && !imgs.length && !emo) { toast('图片没传上去,删掉重新选一下'); 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 - emo.length) + emo).trim(), images: imgs, 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 = !canSend(); 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 = (NBY[openId] || {}).pin ? PIN_PH : '说点什么…';
|
||
haptic();
|
||
cin.value = ''; if (CP) CP.clear(); $('#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 = !canSend(); 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);
|
||
});
|
||
/* 返回兜爸的头像(11-03 用户:「图标换成用户的头像,上面加渐变圈」)—— 同数胎动的取值顺序:
|
||
① 跨应用 user-center/info 的真头像(权威);② 授权回传在 hash 里的 avatar;③ 都没有 → 按 openid 固定给一个默认妈妈头像
|
||
(同 /_bridge/avatar-picker.js 的 defaultFor,同一人在每个应用看到的一样)。商城默认头像 /uploads/system/ 当没有。
|
||
小房子 SVG 不删:头像加载失败就露回来,这是回首页的入口,不能变空位。 */
|
||
var realAv = function (u) { return !!u && !/\/uploads\/system\//.test(u); };
|
||
function defAv(oid) { var h = 0, s = String(oid || ''); for (var i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0; return 'https://mp.yizhezhe.com/_bridge/avatars/mom-' + ((h % 20) + 1 < 10 ? '0' : '') + ((h % 20) + 1) + '.png'; }
|
||
function paintTabAv(url) {
|
||
var ico = $('#tabAv'), im = ico.querySelector('.tab-avimg');
|
||
if (!url) return;
|
||
if (!im) {
|
||
im = document.createElement('img'); im.className = 'tab-avimg'; im.alt = ''; 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>');
|
||
}
|
||
im.onload = function () { ico.classList.add('has-av'); };
|
||
im.onerror = function () { if (im.getAttribute('src') !== defAv(OPENID)) im.src = defAv(OPENID); else ico.classList.remove('has-av'); };
|
||
if (im.getAttribute('src') !== url) im.src = url;
|
||
}
|
||
function loadTabAv() {
|
||
if (!OPENID || !window.fetch) return;
|
||
fetch('/api/mp/public/user-center/info?openid=' + encodeURIComponent(OPENID) + (param('unionid') ? '&unionid=' + encodeURIComponent(param('unionid')) : ''))
|
||
.then(function (r) { return r.ok ? r.json() : null; }).then(function (d) {
|
||
var av = d && d.result && d.result.found && d.result.data && d.result.data.avatar;
|
||
if (realAv(av)) paintTabAv(av);
|
||
}).catch(function () {});
|
||
}
|
||
if (OPENID) { paintTabAv(realAv(param('avatar')) ? param('avatar') : defAv(OPENID)); loadTabAv(); }
|
||
window.addEventListener('pageshow', function (e) { if (e.persisted) loadTabAv(); }); /* 从别的应用改完头像退回来,跟着换 */
|
||
|
||
/* ---------- 吸顶阴影 ---------- */
|
||
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 (c0 === 'ceshi') catF = c0; /* 11-03 分类取消:旧链接 ?c=family / work / baby 一律落「全部」 */
|
||
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); });
|
||
/* 11-04 微信转发图:跟着地址走 —— ?n= 笔记(g/<id>.jpg,真实投稿用广场图)、?t= 话题(g/t-<id>.jpg)、?c=ceshi 测试列表、其余广场首页;见 js/share-card.js */
|
||
if (window.mbShareWatch) window.mbShareWatch(function () {
|
||
var q = new URLSearchParams(location.search), n = NBY[q.get('n')], t = TBY[q.get('t')];
|
||
if (n && n.pin) return ['../assets/share/g/home.jpg', '孕妈悄悄话|每一颗星星,都是一位孕妈对宝宝说的一句话']; /* 11-07 置顶笔记暂用广场首页图 */
|
||
if (n) return n.real ? ['../assets/share/g/home.jpg', n.title] : ['../assets/share/g/' + n.id + '.jpg', n.title];
|
||
if (t) return ['../assets/share/g/t-' + t.id + '.jpg', '#' + t.name + '#'];
|
||
if (q.get('c') === 'ceshi') return ['../assets/share/g/ceshi.jpg', '趣味小测试|30 个孕育小测试,1 分钟测出你是哪种孕妈'];
|
||
return ['../assets/share/g/home.jpg', '孕妈广场|孕期的那些事,听听过来人怎么说'];
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|