805 lines
56 KiB
HTML
805 lines
56 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
|
||
<meta name="format-detection" content="telephone=no">
|
||
<title>测一测:你最近的孕期压力有多大?</title>
|
||
<!-- 孕期专题 · 趣味测试 3:「你最近的孕期压力有多大?」(2026-11-02 新建)。
|
||
结构 / 交互 / 视觉完全照 ../ceshi/、../duiyou/,只换内容与主色:主色柔和青绿 #2FA39A、浅底 #E6F6F4。
|
||
孕妈自答;12 题,每题 4 个选项按 0~3 分,共 36 分;题目覆盖 4 个压力来源(睡眠与身体 / 工作与节奏 / 家人与关系 / 分娩与育儿),各 3 题。
|
||
按总分分 4 档:云淡风轻 0-8 / 偶有小浪 9-17 / 需要抱抱 18-26 / 该放个假啦 27-36。
|
||
结果页:压力卡(插画 + 档位 + 压力指数条 + 来源雷达)+ 你现在的状态 + 可能的压力来源(引用作答)+ 3 条小放松 + 家人帮的一件事
|
||
+ 最高档温和提醒可找医生 / 心理咨询 + 推荐工具 + 保存结果卡。按用户要求不放「复制发给 xx」类按钮。
|
||
只做生活层面的自查,页内注明「仅供参考,不能代替医生判断,有不适请及时就医」。
|
||
结果存 localStorage「mmbox.yali.v1」(含每题作答)。插画 img/*.webp(hero + 4 档同一画风)。
|
||
自成一页:不引 app.js;返回走 history 或相对路径 ../../,推荐工具走 ../_shared/tools.js。
|
||
纯自测,不采集、不上报答题数据;不造「已有 N 人测过」数字(TESTED_COUNT=0 不显示)。 -->
|
||
<style>
|
||
:root{--c:#2FA39A;--cbg:#E6F6F4;--c06:rgba(47,163,154,.06);--c10:rgba(47,163,154,.10);--c20:rgba(47,163,154,.20);--ink:#1F2329;--txt:#4E5969;--sub:#86909C;--line:#EEF0F3;--soft:#F7F8FA}
|
||
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
|
||
html,body{height:100%;overflow:hidden;background:#fff;color:var(--txt);font:15px/1.75 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif}
|
||
#scroll{position:fixed;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:none;padding-bottom:calc(24px + env(safe-area-inset-bottom))}
|
||
img{display:block;max-width:100%}
|
||
button{font:inherit;border:0;background:none;color:inherit;cursor:pointer}
|
||
.ic{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
|
||
.hide{position:absolute;width:0;height:0;overflow:hidden}
|
||
[hidden]{display:none !important}
|
||
.num{font-variant-numeric:tabular-nums}
|
||
mark{background:linear-gradient(transparent 62%,var(--c20) 0);color:inherit;padding:0 1px}
|
||
|
||
/* 顶栏 */
|
||
.bar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:4px;height:48px;padding:0 8px;padding-top:env(safe-area-inset-top);background:transparent;border-bottom:1px solid transparent;transition:background .2s,border-color .2s}
|
||
.bar.sh{background:#fff;border-bottom-color:var(--line)}
|
||
.bar .back{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;color:var(--ink)}
|
||
.bar .back .ic{width:22px;height:22px}
|
||
.bar .t{font-weight:600;font-size:16px;color:var(--ink)}
|
||
|
||
/* 三屏 */
|
||
.view{display:none}
|
||
.view.on{display:block;animation:vin .35s ease both}
|
||
@keyframes vin{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
|
||
.wrap{padding:0 20px}
|
||
|
||
.btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;height:46px;border-radius:99px;font-size:16px;font-weight:700;transition:transform .15s,opacity .15s}
|
||
.btn.pri{background:var(--c);color:#fff;box-shadow:0 6px 16px rgba(47,163,154,.28)}
|
||
.btn.sec{background:#fff;color:var(--c);border:1px solid var(--c)}
|
||
.btn:active,.tap:active{transform:scale(.98)}
|
||
|
||
/* 区块标题:小号序号 + 标题 */
|
||
.sh2{display:flex;align-items:baseline;gap:8px;margin-bottom:14px}
|
||
.sh2 i{font-style:normal;font-size:13px;font-weight:800;color:var(--c);letter-spacing:.5px}
|
||
.sh2 b{font-size:18px;font-weight:800;color:var(--ink);line-height:1.4}
|
||
.sh2 span{margin-left:auto;font-size:12.5px;color:var(--sub)}
|
||
|
||
/* ---------- ① 开始 ---------- */
|
||
#vStart{margin-top:-48px}
|
||
.hero{position:relative;overflow:hidden;min-height:430px;padding:72px 20px 0;background:linear-gradient(160deg,var(--cbg) 0%,#fff 72%)}
|
||
.hero .o1,.hero .o2{position:absolute;border-radius:50%;background:var(--c10);pointer-events:none}
|
||
.hero .o1{width:260px;height:260px;right:-90px;top:-70px}
|
||
.hero .o2{width:150px;height:150px;left:-60px;bottom:40px;background:var(--c06)}
|
||
.hero .eb{position:relative;display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 12px;border-radius:99px;background:#fff;color:var(--c);font-size:12.5px;font-weight:700;letter-spacing:.5px;box-shadow:0 2px 8px var(--c10)}
|
||
.hero h1{position:relative;margin-top:16px;font-size:30px;font-weight:800;line-height:1.32;color:var(--ink);letter-spacing:.5px}
|
||
.hero .meta{position:relative;display:flex;flex-direction:column;gap:8px;margin-top:18px;width:150px}
|
||
.hero .meta span{display:flex;align-items:center;gap:6px;font-size:13.5px;color:var(--txt);line-height:1.4}
|
||
.hero .meta .ic{width:18px;height:18px;color:var(--c)}
|
||
.hero .meta b{color:var(--ink);font-weight:800}
|
||
.hero .pic{position:absolute;right:-18px;bottom:0;width:min(228px,calc(100vw - 162px));height:min(228px,calc(100vw - 162px));object-fit:cover;object-position:center 30%;border-radius:28px 0 0 0;box-shadow:0 8px 24px var(--c10)}
|
||
.types{margin-top:28px}
|
||
.tgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
|
||
.tcard{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:18px;background:var(--soft)}
|
||
.tcard img{flex:none;width:46px;height:46px;border-radius:50%;object-fit:cover;object-position:center 22%;border:2px solid #fff;box-shadow:0 2px 8px var(--c10)}
|
||
.tcard b{display:block;font-size:14.5px;color:var(--ink);line-height:1.35}
|
||
.tcard small{display:block;font-size:12px;color:var(--sub);line-height:1.4}
|
||
.startbox{margin-top:28px;text-align:center}
|
||
.startbox .note{margin-top:10px;font-size:12.5px;color:var(--sub)}
|
||
|
||
/* ---------- ② 答题 ---------- */
|
||
#vQuiz{padding-top:4px}
|
||
.qtop{display:flex;align-items:center;justify-content:space-between;height:34px}
|
||
.qtop button{display:inline-flex;align-items:center;gap:2px;font-size:13.5px;color:var(--sub);padding:4px 8px 4px 0}
|
||
.qtop button .ic{width:16px;height:16px}
|
||
.qtop button:disabled{visibility:hidden}
|
||
.qtop .no{font-size:13px;color:var(--sub)}
|
||
.qtop .no b{font-size:18px;color:var(--c);font-weight:800}
|
||
.feet{display:flex;justify-content:space-between;align-items:center;height:30px;margin-top:4px;padding:0 2px}
|
||
.feet svg{width:15px;height:15px;fill:#BFE6E2;transition:fill .3s,transform .3s}
|
||
.feet svg:nth-child(odd){transform:translateY(-4px) rotate(-12deg)}
|
||
.feet svg:nth-child(even){transform:translateY(4px) rotate(12deg) scaleX(-1)}
|
||
.feet svg.done{fill:var(--c)}
|
||
.feet svg.cur{fill:var(--c)}
|
||
.feet svg.cur:nth-child(odd){transform:translateY(-4px) rotate(-12deg) scale(1.35)}
|
||
.feet svg.cur:nth-child(even){transform:translateY(4px) rotate(12deg) scaleX(-1) scale(1.35)}
|
||
.stage{margin-top:14px;transition:opacity .22s ease,transform .22s ease}
|
||
.stage.outL{opacity:0;transform:translateX(-36px)}
|
||
.stage.outR{opacity:0;transform:translateX(36px)}
|
||
.stage.inR{opacity:0;transform:translateX(36px);transition:none}
|
||
.stage.inL{opacity:0;transform:translateX(-36px);transition:none}
|
||
.qcard{position:relative;overflow:hidden;padding:20px 20px 18px;border-radius:24px;background:linear-gradient(160deg,var(--cbg),#fff 78%);box-shadow:0 8px 24px var(--c10)}
|
||
.qcard:after{content:"";position:absolute;width:120px;height:120px;right:-40px;top:-40px;border-radius:50%;background:var(--c10)}
|
||
.qcard .hd{position:relative;display:flex;align-items:center;justify-content:space-between}
|
||
.qcard .qi{width:56px;height:56px;border-radius:18px;display:grid;place-items:center;background:#fff;color:var(--c);box-shadow:0 4px 12px var(--c10)}
|
||
.qcard .qi .ic{width:30px;height:30px;stroke-width:1.6}
|
||
.qcard .cat{position:relative;z-index:1;height:24px;padding:0 10px;border-radius:99px;background:#fff;color:var(--c);font-size:12px;font-weight:700;line-height:24px}
|
||
.qcard h2{position:relative;margin-top:16px;font-size:21px;font-weight:800;line-height:1.45;color:var(--ink);min-height:61px;text-wrap:balance}
|
||
.opts{display:flex;flex-direction:column;gap:10px;margin-top:16px}
|
||
.opt{position:relative;display:flex;align-items:center;gap:12px;width:100%;min-height:56px;padding:11px 46px 11px 14px;border-radius:18px;background:#fff;border:1.5px solid var(--line);text-align:left;font-size:15.5px;line-height:1.45;color:var(--ink);transition:border-color .2s,background .2s,transform .15s}
|
||
.opt:active{transform:scale(.98)}
|
||
.opt .l{flex:none;width:26px;height:26px;border-radius:9px;display:grid;place-items:center;background:var(--soft);color:var(--sub);font-size:13px;font-weight:800;transition:background .2s,color .2s}
|
||
.opt .ck{position:absolute;right:14px;top:50%;width:22px;height:22px;margin-top:-11px;border-radius:50%;background:var(--c);color:#fff;display:grid;place-items:center;transform:scale(0);transition:transform .25s cubic-bezier(.3,1.6,.5,1)}
|
||
.opt .ck .ic{width:14px;height:14px;stroke-width:2.6}
|
||
.opt.sel{border-color:var(--c);background:#F5FBFA;font-weight:600}
|
||
.opt.sel .l{background:var(--c);color:#fff}
|
||
.opt.sel .ck{transform:scale(1)}
|
||
.qtip{margin-top:16px;text-align:center;font-size:12.5px;color:var(--sub)}
|
||
|
||
/* ---------- ③ 结果 ---------- */
|
||
#vResult{padding-top:6px}
|
||
.rcard{position:relative;overflow:hidden;padding:22px 20px 18px;border-radius:28px;background:linear-gradient(170deg,#D3F0EC 0%,#EEF9F7 44%,#fff 100%);box-shadow:0 8px 24px var(--c10);text-align:center}
|
||
.rcard .o1,.rcard .o2{position:absolute;border-radius:50%;pointer-events:none}
|
||
.rcard .o1{width:220px;height:220px;right:-80px;top:-60px;background:rgba(255,255,255,.55)}
|
||
.rcard .o2{width:140px;height:140px;left:-50px;top:150px;background:var(--c06)}
|
||
.rcard .top{position:relative;display:flex;justify-content:space-between;align-items:center;font-size:12px;line-height:24px}
|
||
.rcard .top b{padding:0 10px;border-radius:99px;background:#fff;color:var(--c);font-weight:700}
|
||
.rcard .top span{color:var(--sub)}
|
||
.rcard .ava{position:relative;width:172px;height:172px;margin:14px auto 0;border-radius:32px;overflow:hidden;border:5px solid #fff;box-shadow:0 8px 24px var(--c10)}
|
||
.rcard .ava img{width:100%;height:100%;object-fit:cover;object-position:center 30%}
|
||
.rcard .you{position:relative;margin-top:14px;font-size:13px;color:var(--sub);letter-spacing:2px}
|
||
.rcard h1{position:relative;font-size:28px;font-weight:800;line-height:1.3;color:var(--ink)}
|
||
.rcard .slo{position:relative;margin-top:6px;font-size:14.5px;color:var(--txt);line-height:1.6}
|
||
.rtags{position:relative;display:flex;justify-content:center;gap:8px;margin-top:14px}
|
||
.rtags span{height:30px;padding:0 12px;border-radius:99px;background:#fff;color:var(--c);font-size:13.5px;font-weight:700;line-height:30px;white-space:nowrap;box-shadow:0 2px 8px var(--c10)}
|
||
.dims{position:relative;display:flex;align-items:center;gap:12px;margin-top:18px;padding:14px 14px 14px 8px;border-radius:20px;background:rgba(255,255,255,.85);text-align:left}
|
||
.dims svg{flex:none;width:146px;height:128px}
|
||
.dl{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
|
||
.dr{display:grid;grid-template-columns:1fr auto;align-items:center;row-gap:3px;font-size:12.5px;color:var(--txt);line-height:1.3}
|
||
.dr .p{font-weight:700;color:var(--ink)}
|
||
.dr .tr{grid-column:1/3;height:5px;border-radius:5px;background:#E3F4F2;overflow:hidden}
|
||
.dr .tr i{display:block;height:100%;width:0;border-radius:5px;background:#9BD6CF;transition:width .8s cubic-bezier(.3,.7,.2,1)}
|
||
.dr.me{color:var(--c);font-weight:700}
|
||
.dr.me .p{color:var(--c)}
|
||
.dr.me .tr i{background:var(--c)}
|
||
.rcard .brand{position:relative;margin-top:14px;font-size:11.5px;color:var(--sub);letter-spacing:.5px}
|
||
|
||
.racts{display:flex;gap:10px;margin-top:16px}
|
||
.racts .btn{flex:1;font-size:15px}
|
||
.blk{margin-top:36px}
|
||
.read{padding:18px;border-radius:24px;background:var(--soft)}
|
||
.read p{font-size:15px;line-height:1.8;color:var(--txt)}
|
||
.read p+p{margin-top:10px}
|
||
.read b{color:var(--ink)}
|
||
.read q{quotes:"「" "」";color:var(--c);font-weight:700}
|
||
.tips{display:flex;flex-direction:column;gap:10px}
|
||
.tp{display:flex;gap:14px;align-items:flex-start;padding:14px 16px;border-radius:18px;background:#fff;border:1px solid var(--line)}
|
||
.tp .n{flex:none;width:30px;font-size:30px;font-weight:800;line-height:1;color:transparent;-webkit-text-stroke:1.4px var(--c);font-variant-numeric:tabular-nums}
|
||
.tp p{font-size:14.5px;line-height:1.65;color:var(--ink)}
|
||
.mate{display:flex;align-items:center;gap:14px;padding:14px 16px;border-radius:24px;background:linear-gradient(110deg,var(--cbg),#fff 80%)}
|
||
.mate img{flex:none;width:60px;height:60px;border-radius:50%;object-fit:cover;object-position:center 22%;border:3px solid #fff;box-shadow:0 4px 12px var(--c10)}
|
||
.mate small{display:block;font-size:12px;color:var(--sub);line-height:1.5}
|
||
.mate b{display:block;font-size:16px;color:var(--ink);line-height:1.4}
|
||
.mate p{margin-top:2px;font-size:13.5px;color:var(--txt);line-height:1.55}
|
||
#tools{margin-top:36px !important}
|
||
.again{margin-top:24px}
|
||
|
||
.foot{margin:28px 20px 0;font-size:12px;color:var(--sub);text-align:center}
|
||
.toast{position:fixed;left:50%;bottom:calc(80px + env(safe-area-inset-bottom));transform:translate(-50%,8px);max-width:300px;padding:10px 16px;border-radius:12px;background:rgba(31,35,41,.88);color:#fff;font-size:13.5px;line-height:1.6;text-align:center;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:60}
|
||
.toast.on{opacity:1;transform:translate(-50%,0)}
|
||
|
||
/* 保存结果卡弹层 */
|
||
.mask{position:fixed;inset:0;z-index:50;display:none;flex-direction:column;align-items:center;justify-content:center;padding:24px 28px calc(24px + env(safe-area-inset-bottom));background:rgba(10,34,32,.82)}
|
||
.mask.on{display:flex;animation:vin .25s ease both}
|
||
.mask img{max-width:100%;max-height:calc(100% - 96px);border-radius:16px;box-shadow:0 12px 32px rgba(0,0,0,.25);-webkit-touch-callout:default;user-select:auto}
|
||
.mask p{margin-top:14px;color:#fff;font-size:14.5px;font-weight:600;display:flex;align-items:center;gap:6px}
|
||
.mask .row{display:flex;gap:16px;margin-top:10px}
|
||
.mask .row button,.mask .row a{height:34px;padding:0 18px;border-radius:99px;border:1px solid rgba(255,255,255,.6);color:#fff;font-size:13.5px;line-height:32px;text-decoration:none}
|
||
|
||
.fade{opacity:0;transform:translateY(12px);transition:opacity .45s ease,transform .45s ease}
|
||
.fade.in{opacity:1;transform:none}
|
||
@media (prefers-reduced-motion:reduce){.fade,.stage,.view.on,.mask.on{opacity:1;transform:none;transition:none;animation:none}}
|
||
|
||
/* 压力指数条(yali 新增) */
|
||
.meter{position:relative;margin-top:16px;padding:12px 14px 10px;border-radius:20px;background:rgba(255,255,255,.85);text-align:left}
|
||
.meter .mh{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:var(--txt);line-height:1.4}
|
||
.meter .mh b{font-size:22px;font-weight:800;color:var(--c)}
|
||
.meter .mh small{font-size:12.5px;color:var(--sub);font-weight:600}
|
||
.mbar{position:relative;display:flex;gap:4px;height:8px;margin-top:8px}
|
||
.mbar i{flex:1;border-radius:4px;background:var(--c)}
|
||
.mbar i:nth-of-type(1){opacity:.22}.mbar i:nth-of-type(2){opacity:.42}.mbar i:nth-of-type(3){opacity:.68}
|
||
.mbar em{position:absolute;top:50%;left:0;width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%;background:#fff;border:4px solid var(--c);box-shadow:0 2px 6px rgba(47,163,154,.3);transition:left .8s cubic-bezier(.3,.7,.2,1)}
|
||
.ml{display:flex;margin-top:6px}
|
||
.ml span{flex:1;text-align:center;font-size:11.5px;color:var(--sub);line-height:1.4}
|
||
.ml span.on{color:var(--c);font-weight:800}
|
||
.meter+.dims{margin-top:10px}
|
||
.disc{margin-top:12px;font-size:12.5px;color:var(--sub);text-align:center;line-height:1.6}
|
||
.care{padding:16px 18px;border-radius:24px;background:var(--cbg)}
|
||
.care p{font-size:14.5px;line-height:1.8;color:var(--ink)}
|
||
.care p+p{margin-top:8px}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- 单色线性图标(每题一个场景图标 q-*) -->
|
||
<svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
|
||
<svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
|
||
<symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol>
|
||
<symbol id="i-arrow" viewBox="0 0 24 24"><path d="M5 12h13M13 6.5l5.5 5.5-5.5 5.5"/></symbol>
|
||
<symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.5l4.5 4.5L19 7.5"/></symbol>
|
||
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></symbol>
|
||
<symbol id="i-list" viewBox="0 0 24 24"><path d="M9 6.5h10M9 12h10M9 17.5h10M4.5 6.5h.01M4.5 12h.01M4.5 17.5h.01"/></symbol>
|
||
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="5" y="10.5" width="14" height="10" rx="3"/><path d="M8.5 10.5V8a3.5 3.5 0 0 1 7 0v2.5"/></symbol>
|
||
<symbol id="i-down" viewBox="0 0 24 24"><path d="M12 4v11M7.5 11l4.5 4.5 4.5-4.5M5 19.5h14"/></symbol>
|
||
<symbol id="i-refresh" viewBox="0 0 24 24"><path d="M20 12a8 8 0 1 1-2.4-5.7M20 4v4.5h-4.5"/></symbol>
|
||
<symbol id="i-hand" viewBox="0 0 24 24"><path d="M9 11V5.5a1.5 1.5 0 0 1 3 0V10M12 9.5V4.5a1.5 1.5 0 0 1 3 0V10M15 9.5V6a1.5 1.5 0 0 1 3 0v8a6.5 6.5 0 0 1-6.5 6.5h-.6a6 6 0 0 1-4.6-2.2L4 15.5a1.6 1.6 0 0 1 2.4-2.1L9 15.5V11"/></symbol>
|
||
<symbol id="i-foot" viewBox="0 0 24 24"><path d="M12 9c3 0 4.6 2.7 4.6 6.3S14.8 22 12 22s-4.6-3.1-4.6-6.7S9 9 12 9z"/><circle cx="7.6" cy="6.6" r="1.6"/><circle cx="10.6" cy="4.4" r="1.75"/><circle cx="14" cy="4.6" r="1.6"/><circle cx="16.8" cy="6.8" r="1.35"/></symbol>
|
||
<!-- 题目场景 -->
|
||
<symbol id="q-test" viewBox="0 0 24 24"><rect x="9" y="2.5" width="6" height="19" rx="3"/><path d="M9 9h6M9 15.5h6M11 11.5v2M13 11.5v2"/></symbol>
|
||
<symbol id="q-board" viewBox="0 0 24 24"><rect x="5" y="4.5" width="14" height="17" rx="2.5"/><path d="M9 3h6v3H9zM8.5 11l1.5 1.5 3-3M8.5 16.5h7"/></symbol>
|
||
<symbol id="q-wait" viewBox="0 0 24 24"><path d="M7 3h10M7 21h10M8 3c0 4.5 4 5.5 4 9s-4 4.5-4 9M16 3c0 4.5-4 5.5-4 9s4 4.5 4 9M10 18.5h4"/></symbol>
|
||
<symbol id="q-moon" viewBox="0 0 24 24"><path d="M19.5 14.5A8 8 0 1 1 9.5 4.5a6.5 6.5 0 0 0 10 10z"/><path d="M16 4v3M14.5 5.5h3"/></symbol>
|
||
<symbol id="q-scale" viewBox="0 0 24 24"><rect x="3.5" y="4" width="17" height="16" rx="4"/><path d="M8 11a4 4 0 0 1 8 0M12 11l2-2.2"/></symbol>
|
||
<symbol id="q-phone" viewBox="0 0 24 24"><rect x="6" y="2.5" width="12" height="19" rx="3"/><path d="M10.5 18.5h3M12 7v4.5M12 14h.01"/></symbol>
|
||
<symbol id="q-bowl" viewBox="0 0 24 24"><path d="M3.5 11.5h17a8.5 8.5 0 0 1-17 0zM9 20h6M14 8.5l5-5M17 8.5l3-3"/></symbol>
|
||
<symbol id="q-pot" viewBox="0 0 24 24"><path d="M4.5 10h15v6a4.5 4.5 0 0 1-4.5 4.5H9A4.5 4.5 0 0 1 4.5 16zM2.5 12h2M19.5 12h2M9 3.5c-.8 1 .8 2 0 3M12 3c-.8 1 .8 2 0 3M15 3.5c-.8 1 .8 2 0 3"/></symbol>
|
||
<symbol id="q-rain" viewBox="0 0 24 24"><path d="M7 15.5a4 4 0 0 1-.4-8A5.5 5.5 0 0 1 17.2 8a3.8 3.8 0 0 1-.2 7.5z"/><path d="M8.5 18.5l-.8 2M12.5 18.5l-.8 2M16.5 18.5l-.8 2"/></symbol>
|
||
<symbol id="q-chat" viewBox="0 0 24 24"><path d="M4 5.5h11a2 2 0 0 1 2 2V13a2 2 0 0 1-2 2H9l-4 3.5V15H4a2 2 0 0 1-2-2V7.5a2 2 0 0 1 2-2z"/><path d="M17 9h3a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-1v2.5L16 18h-2"/></symbol>
|
||
<symbol id="q-heart" viewBox="0 0 24 24"><path d="M12 20s-7.5-4.6-7.5-10A4.3 4.3 0 0 1 12 7.5 4.3 4.3 0 0 1 19.5 10c0 5.4-7.5 10-7.5 10z"/></symbol>
|
||
<symbol id="q-family" viewBox="0 0 24 24"><circle cx="8" cy="7" r="2.8"/><circle cx="16.5" cy="8" r="2.3"/><path d="M3 20v-1.5A5 5 0 0 1 8 13.5a5 5 0 0 1 5 5V20M13.5 14.2a4.2 4.2 0 0 1 7 3.1V20"/></symbol>
|
||
<symbol id="q-bag" viewBox="0 0 24 24"><rect x="3.5" y="8" width="17" height="12.5" rx="3"/><path d="M8.5 8V6a3.5 3.5 0 0 1 7 0v2M3.5 13h17M11 13v2h2v-2"/></symbol>
|
||
<symbol id="q-cal" viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M3.5 10h17M8 3v4M16 3v4M14 15.2l1.4 1.4 2.6-2.6"/></symbol>
|
||
<symbol id="q-camera" viewBox="0 0 24 24"><path d="M4.5 7.5h3l1.5-2.5h6l1.5 2.5h3a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2h-15a2 2 0 0 1-2-2V9.5a2 2 0 0 1 2-2z"/><circle cx="12" cy="13.5" r="3.5"/></symbol>
|
||
<symbol id="q-baby" viewBox="0 0 24 24"><circle cx="12" cy="12.5" r="8.5"/><path d="M9.2 11.2h.01M14.8 11.2h.01M10 16a2.6 2.6 0 0 1 4 0M12 4c-1.2 0-1.6 1.2-.8 2"/></symbol>
|
||
</svg>
|
||
</svg>
|
||
|
||
<div id="scroll">
|
||
<header class="bar" id="bar">
|
||
<button class="back" id="back" aria-label="返回"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg></button>
|
||
<span class="t">孕期专题</span>
|
||
</header>
|
||
|
||
<!-- ① 开始 -->
|
||
<main class="view" id="vStart">
|
||
<section class="hero">
|
||
<i class="o1"></i><i class="o2"></i>
|
||
<span class="eb">孕期趣味自测 · STRESS CHECK</span>
|
||
<h1>测一测<br>你最近的<mark>孕期压力</mark><br>有多大?</h1>
|
||
<div class="meta">
|
||
<span><svg class="ic"><use href="#i-list" xlink:href="#i-list"/></svg><b class="num">12</b>题 · 约<b class="num">2</b>分钟</span>
|
||
<span><svg class="ic"><use href="#i-lock" xlink:href="#i-lock"/></svg>只在本机算,不上传</span>
|
||
<span id="tested" hidden><svg class="ic"><use href="#q-heart" xlink:href="#q-heart"/></svg>已有<b class="num" id="testedN"></b>位妈妈测过</span>
|
||
</div>
|
||
<img class="pic" src="img/hero.webp" alt="孕妈坐在窗边沙发上,捧着热茶放松">
|
||
</section>
|
||
|
||
<div class="wrap">
|
||
<section class="types fade">
|
||
<div class="sh2"><i>4 LEVELS</i><b>4 种状态,你在哪一档?</b></div>
|
||
<div class="tgrid" id="tgrid"></div>
|
||
</section>
|
||
<div class="startbox fade">
|
||
<button class="btn pri" id="startBtn">开始测试<svg class="ic"><use href="#i-arrow" xlink:href="#i-arrow"/></svg></button>
|
||
<p class="note">想想最近两周的自己,凭第一感觉选</p>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<!-- ② 答题 -->
|
||
<main class="view wrap" id="vQuiz">
|
||
<div class="qtop">
|
||
<button id="prevBtn"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg>上一题</button>
|
||
<span class="no num"><b id="qNo">1</b> / <span id="qTotal">12</span></span>
|
||
</div>
|
||
<div class="feet" id="feet" aria-hidden="true"></div>
|
||
<div class="stage" id="stage">
|
||
<div class="qcard">
|
||
<div class="hd">
|
||
<span class="qi"><svg class="ic"><use id="qIc" href="#q-moon" xlink:href="#q-moon"/></svg></span>
|
||
<span class="cat" id="qCat"></span>
|
||
</div>
|
||
<h2 id="qTitle"></h2>
|
||
</div>
|
||
<div class="opts" id="qOpts"></div>
|
||
</div>
|
||
<p class="qtip">选完自动进入下一题</p>
|
||
</main>
|
||
|
||
<!-- ③ 结果 -->
|
||
<main class="view wrap" id="vResult">
|
||
<article class="rcard" id="rCard">
|
||
<i class="o1"></i><i class="o2"></i>
|
||
<div class="top"><b>我的孕期压力卡</b><span id="rLast"></span></div>
|
||
<div class="ava"><img id="rImg" src="" alt=""></div>
|
||
<p class="you">最近的我是</p>
|
||
<h1><mark id="rName"></mark></h1>
|
||
<p class="slo" id="rLine"></p>
|
||
<div class="rtags" id="rTags"></div>
|
||
<div class="meter">
|
||
<div class="mh"><span>压力指数</span><span><b class="num" id="rScore">0</b><small class="num"> / 36</small></span></div>
|
||
<div class="mbar"><i></i><i></i><i></i><i></i><em id="rPin"></em></div>
|
||
<div class="ml" id="rMl"></div>
|
||
</div>
|
||
<div class="dims">
|
||
<svg id="rRadar" viewBox="-16 -2 168 146" role="img" aria-label="4 个压力来源雷达图"></svg>
|
||
<div class="dl" id="rDims"></div>
|
||
</div>
|
||
<p class="brand">兜爸心选 · 孕期专题 · 你最近的孕期压力有多大</p>
|
||
</article>
|
||
|
||
<div class="racts">
|
||
<button class="btn pri" id="saveBtn"><svg class="ic"><use href="#i-down" xlink:href="#i-down"/></svg>保存结果卡</button>
|
||
</div>
|
||
<p class="disc">仅供参考,不能代替医生判断,有不适请及时就医</p>
|
||
|
||
<section class="blk fade">
|
||
<div class="sh2"><i>01</i><b>你现在的状态</b></div>
|
||
<div class="read" id="rRead"></div>
|
||
</section>
|
||
|
||
<section class="blk fade">
|
||
<div class="sh2"><i>02</i><b>可能的压力来源</b></div>
|
||
<div class="read" id="rSrc"></div>
|
||
</section>
|
||
|
||
<section class="blk fade">
|
||
<div class="sh2"><i>03</i><b>马上能做的小放松</b></div>
|
||
<div class="tips" id="rTips"></div>
|
||
</section>
|
||
|
||
<section class="blk fade">
|
||
<div class="sh2"><i>04</i><b>可以让家人帮的一件事</b></div>
|
||
<div class="mate" id="rMate"></div>
|
||
</section>
|
||
|
||
<section class="blk fade" id="careBlk" hidden>
|
||
<div class="sh2"><i>05</i><b>多一个人陪你聊聊</b></div>
|
||
<div class="care" id="rCare"></div>
|
||
</section>
|
||
|
||
<div id="tools" class="fade"></div>
|
||
|
||
<button class="btn sec again" id="againBtn"><svg class="ic"><use href="#i-refresh" xlink:href="#i-refresh"/></svg>重新测试</button>
|
||
</main>
|
||
|
||
<p class="foot">孕期自测,仅供参考,不能代替医生判断;照顾好自己,就是在照顾宝宝</p>
|
||
</div>
|
||
|
||
<div class="mask" id="mask">
|
||
<img id="maskImg" alt="我的孕期压力卡">
|
||
<p><svg class="ic"><use href="#i-hand" xlink:href="#i-hand"/></svg>长按图片,保存到相册</p>
|
||
<div class="row"><a id="dlBtn" download="孕期压力卡.png" hidden>下载图片</a><button id="maskClose">关闭</button></div>
|
||
</div>
|
||
<div class="toast" id="toast"></div>
|
||
|
||
<script src="../_shared/tools.js"></script>
|
||
<script>
|
||
(function () {
|
||
'use strict';
|
||
var $ = function (s) { return document.querySelector(s); };
|
||
var sc = $('#scroll');
|
||
var KEY = 'mmbox.yali.v1';
|
||
var TESTED_COUNT = 0; /* 「已有 N 位妈妈测过」:只有接上真实统计后才填,0 = 不显示(不造数字) */
|
||
var XL = 'http://www.w3.org/1999/xlink';
|
||
function useRef(el, id) { el.setAttribute('href', '#' + id); el.setAttributeNS(XL, 'xlink:href', '#' + id); }
|
||
function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); }
|
||
var openid = (function () {
|
||
var m = (location.hash + '&' + location.search).match(/[#?&]openid=([^&#]+)/);
|
||
return m ? decodeURIComponent(m[1]) : '';
|
||
})();
|
||
|
||
/* 返回:从首页点进来就 back;直接打开(分享 / 刷新)就回同目录的首页,身份 hash 原样带回 */
|
||
$('#back').addEventListener('click', function () {
|
||
if (document.referrer && document.referrer.indexOf(location.host) >= 0 && history.length > 1) history.back();
|
||
else location.href = '../../' + location.search + location.hash;
|
||
});
|
||
sc.addEventListener('scroll', function () { $('#bar').classList.toggle('sh', sc.scrollTop > 4); }, { passive: true });
|
||
|
||
/* ================= 4 个压力来源(雷达图 4 轴) =================
|
||
* ORDER 顺序 = 雷达图顺时针(上/右/下/左)。每个来源 3 题、满分 9,雷达 / 条形显示「该来源得分 / 9」。
|
||
* src:分数高时「可能的压力来源」里给的一句;calm:四项都平稳时对最高项的一句。 */
|
||
var CATS = {
|
||
body: { name: '睡眠与身体', ax: '身体',
|
||
src: '孕期激素和身体的变化,会直接影响睡眠和胃口;身体累了,心情也容易跟着往下掉。',
|
||
calm: '身体的小变化你都接得住,继续保持规律作息就好。' },
|
||
pace: { name: '工作与节奏', ax: '节奏',
|
||
src: '工作、家务和各种安排挤在一起,留给自己的时间被压缩,人就容易一直绷着。',
|
||
calm: '日子的节奏还在你自己手里,记得给自己留点空白。' },
|
||
fam: { name: '家人与关系', ax: '家人',
|
||
src: '身边人的期待、叮嘱和相处里的小摩擦,没说出口的话,会悄悄攒成压力。',
|
||
calm: '身边有人可以说话、可以依靠,这是很好的底气。' },
|
||
fear: { name: '分娩与育儿', ax: '担心',
|
||
src: '对分娩和「当妈妈」的未知,是孕期最常见的担心;信息看得越多,有时越容易放大。',
|
||
calm: '对未来你有期待也有准备,一步一步来就好。' }
|
||
};
|
||
var ORDER = ['body', 'pace', 'fam', 'fear'];
|
||
|
||
/* ================= 4 档结果(按总分 0~36) =================
|
||
* max:本档最高分;line:一句话状态;src:「可能的压力来源」开头一句;good:想对你说;
|
||
* tips:3 条马上能做的小放松;fam:可以让家人帮的一件事;care:仅最高档,温和提醒可以找医生 / 心理咨询聊聊。
|
||
* 语气:温柔、不说教、不吓人;只做生活层面的自查。 */
|
||
var LV = [
|
||
{ key: 'qing', max: 8, name: '云淡风轻', short: '轻松', img: 'img/qing.webp', alt: '孕妈躺在草地野餐垫上惬意看云',
|
||
line: '心里有片小晴天,日子过得稳稳的', tags: ['心态稳', '睡得香', '会照顾自己'],
|
||
desc: '最近的你状态不错:身体的变化接得住,生活的节奏也在自己手里,偶尔的小烦恼来得快、去得也快。',
|
||
src: '整体很平稳,没有哪件事特别压着你。孕期情绪像天气,后面身体负担变重时有点起伏,也很正常。',
|
||
good: '你很会照顾自己,这份松弛感也会传给宝宝。把现在让你舒服的小习惯留住,孕晚期累的时候用得上。',
|
||
tips: ['把最近让你开心的小事记进手机备忘录,哪天低落了翻出来看看。', '每天留 10 分钟散散步、晒晒太阳,让好状态继续保持。', '睡前把手放在肚子上,跟宝宝说说今天发生的事。'],
|
||
fam: '这个周末一起出门走走、吃顿喜欢的,把这份好心情一起存起来。',
|
||
tools: [
|
||
{ id: 'yundujinian', why: '心情好的时候,拍张孕肚照' },
|
||
{ id: 'taidong', why: '睡前一起数胎动,跟宝宝打招呼' },
|
||
{ id: 'chanjianrili', why: '产检日子排好,继续稳稳的' } ] },
|
||
{ key: 'lang', max: 17, name: '偶有小浪', short: '小浪', img: 'img/lang.webp', alt: '孕妈坐在海边,脚边是轻轻的小浪花',
|
||
line: '大体平静,偶尔会翻起几朵小浪花', tags: ['小起伏', '能自我调节', '想喘口气'],
|
||
desc: '大部分时候你都能稳住,只是有些事会时不时冒出来,让心里起一点小波澜。',
|
||
src: '小浪花通常来自几件具体的事,这次分数相对高的是:',
|
||
good: '有起伏不代表你做得不好。孕期身体和激素都在变,能察觉到自己的情绪,已经很棒了。',
|
||
tips: ['心里发紧时,试试慢慢吸气 4 秒、再呼气 6 秒,做 5 轮。', '把担心的事写下来,分成「现在能做的」和「先放一放的」。', '每周给自己留半天「什么都不安排」的时间。'],
|
||
fam: '每周留一个晚上,放下手机听我说说这周的心情,不急着给建议。',
|
||
tools: [
|
||
{ id: 'chanjianrili', why: '产检节点排清楚,心里更有数' },
|
||
{ id: 'daichanqingdan', why: '待产要买的照着清单来,少一件挂心事' },
|
||
{ id: 'yundujinian', why: '把孕期的小美好存下来' } ] },
|
||
{ key: 'bao', max: 26, name: '需要抱抱', short: '抱抱', img: 'img/bao.webp', alt: '孕妈靠在柔软的云朵抱枕里闭眼休息',
|
||
line: '最近有点累,心里想要一个大大的拥抱', tags: ['有点累', '心事多', '值得被照顾'],
|
||
desc: '这段时间你扛着不少事,身体累、心里也装得满满的,有时会觉得委屈,又不知道从哪儿说起。',
|
||
src: '让你累的往往不只一件事,这次分数最高的是:',
|
||
good: '你已经很努力了。想被照顾、想偷个懒都不是矫情,是身体在提醒你:该把自己放在前面一点了。',
|
||
tips: ['今天挑一件「不做也没关系」的事放下,比如晚饭点外卖、衣服明天再洗。', '找一个信得过的人,把心里的话说出来,哪怕只是说说。', '少刷让你心慌的帖子,换成一首喜欢的歌,或一部轻松的剧。'],
|
||
fam: '每天给我一个 10 秒以上的拥抱,再主动接过一件家务,不用等我开口。',
|
||
tools: [
|
||
{ id: 'daichanqingdan', why: '清单列好交给家人,少操一份心' },
|
||
{ id: 'yunqinengbuchi', why: '吃什么查一下就好,不用再纠结' },
|
||
{ id: 'chanjianrili', why: '产检日子提前排好,不用临时慌' } ] },
|
||
{ key: 'jia', max: 36, name: '该放个假啦', short: '放假', img: 'img/jia.webp', alt: '孕妈戴着草帽躺在吊床上休息',
|
||
line: '心里的弦绷得有点紧,该好好歇一歇了', tags: ['弦绷太紧', '需要休息', '值得被心疼'],
|
||
desc: '最近压在你身上的事有点多,睡不好、想得多,心里总是满满的。这些感受都很真实,也值得你停下来,好好照顾自己。',
|
||
src: '好几件事叠在一起,难怪会觉得喘不过气。分数最高的是:',
|
||
good: '这不是你不够坚强,而是你一直在用力。先把「做好」放一放,把「歇一歇」排到第一位。',
|
||
tips: ['今天只做一件让自己舒服的事:泡泡脚、睡个午觉,或者发会儿呆。', '把能推掉、能交出去的事列出来,至少交出去一件。', '难受的时候,把手放在胸口慢慢呼吸,对自己说「我已经很努力了」。'],
|
||
fam: '帮我接过一件最累的事(比如家务,或应付亲戚),再陪我一起去跟医生聊聊最近的状态。',
|
||
care: ['如果这种累和慌已经持续了两周以上,或者常常睡不着、对什么都提不起劲,可以在下次产检时跟医生说一声,或者找心理咨询师聊聊。', '很多医院都有孕产期心理门诊,去聊一聊就像感冒了去看医生一样平常,不代表你不够好。有人陪着,会轻松很多。'],
|
||
tools: [
|
||
{ id: 'chanjianrili', why: '产检时顺便跟医生聊聊心情' },
|
||
{ id: 'daichanqingdan', why: '待产的事交给清单和家人,你只管歇着' },
|
||
{ id: 'yundujinian', why: '翻翻孕期照片,看看你走了多远' } ] }
|
||
];
|
||
function level(score) { for (var i = 0; i < LV.length; i++) if (score <= LV[i].max) return i; return LV.length - 1; }
|
||
|
||
/* ================= 12 道题 · 计分表 =================
|
||
* 每题 4 个选项按 0/1/2/3 分(从轻松到吃力),共 36 分;每个来源 3 题,题目顺序按来源交错。
|
||
* k:来源;c:题卡标签;s:场景短语(解读里「说到 X,你选了…」);ic:场景图标。 */
|
||
var QS = [
|
||
{ k: 'body', ic: 'q-moon', s: '晚上的睡眠', q: '最近晚上的睡眠,大多是?', o: ['一觉到天亮,睡得挺香', '起夜一两次,还能睡着', '醒了就想事,很久才睡着', '翻来覆去,常睡不踏实'] },
|
||
{ k: 'pace', ic: 'q-bag', s: '手头的工作', q: '说到手头的工作或日常安排,你?', o: ['节奏刚好,还挺充实', '偶尔忙乱,能自己调开', '常担心做不完、做不好', '一想到就心累,想逃开'] },
|
||
{ k: 'fam', ic: 'q-family', s: '长辈的叮嘱', q: '长辈的「孕期叮嘱」越来越多,你?', o: ['听听就好,心里有数', '偶尔嫌烦,说开就好', '常憋着,不知道怎么说', '一听就紧张,压力好大'] },
|
||
{ k: 'fear', ic: 'q-baby', s: '分娩那一天', q: '想到分娩那一天,你?', o: ['有点期待,顺其自然', '偶尔紧张,查查就好', '常常会想,越想越怕', '一想就心慌,坐立不安'] },
|
||
{ k: 'body', ic: 'q-scale', s: '身体的变化', q: '看着身体一天天变化,你的心情?', o: ['挺新奇,常对着镜子笑', '偶尔不习惯,很快就好', '有时会对着体重叹气', '总觉得不像自己了'] },
|
||
{ k: 'pace', ic: 'i-clock', s: '自己的时间', q: '一天里只属于自己的时间?', o: ['每天都有,想干嘛干嘛', '不多,但总能挤出来', '很少,总在忙别的事', '几乎没有,喘不过气'] },
|
||
{ k: 'fam', ic: 'q-chat', s: '想说心里话', q: '想找人说说心里话的时候?', o: ['身边总有人愿意听', '找一找,总能找到人', '怕被说矫情,就忍着', '觉得没人真的懂我'] },
|
||
{ k: 'fear', ic: 'q-phone', s: '刷孕育帖子', q: '刷到孕育相关的文章、帖子,你?', o: ['看看就过,不往心里去', '有用的收藏,挺安心', '看完容易对号入座', '越刷越慌,又停不下来'] },
|
||
{ k: 'body', ic: 'q-bowl', s: '孕期小不适', q: '腰酸、胃口差这些小不适找上门时?', o: ['当成小插曲,过去就好', '有点烦,躺会儿就好', '心情也跟着往下掉', '很难熬,常觉得委屈'] },
|
||
{ k: 'pace', ic: 'q-cal', s: '空出来的周末', q: '周末突然空出半天,你最可能?', o: ['安排点喜欢的事,美滋滋', '躺着刷刷手机,也挺好', '想歇着,又惦记没做的事', '累得什么都不想做'] },
|
||
{ k: 'fam', ic: 'q-heart', s: '和另一半相处', q: '和另一半最近的相处?', o: ['比以前更黏糊了', '偶有小摩擦,很快和好', '常觉得他不太懂我', '一点小事就想掉眼泪'] },
|
||
{ k: 'fear', ic: 'q-wait', s: '宝宝出生后的生活', q: '想象宝宝出生后的生活,你?', o: ['满是期待,想快点见面', '会手忙脚乱,但能应付', '担心钱、带娃和工作', '怕自己当不好妈妈'] }
|
||
];
|
||
var MAXS = QS.length * 3, CATMAX = {};
|
||
ORDER.forEach(function (k) { CATMAX[k] = QS.filter(function (q) { return q.k === k; }).length * 3; });
|
||
$('#qTotal').textContent = QS.length;
|
||
|
||
/* 开始页:4 档小卡 + 测过人数(仅真实数据) */
|
||
$('#tgrid').innerHTML = LV.map(function (t) {
|
||
return '<div class="tcard"><img src="' + t.img + '" alt=""><span><b>' + t.name + '</b><small>' + t.tags[0] + '</small></span></div>';
|
||
}).join('');
|
||
if (TESTED_COUNT > 0) { $('#testedN').textContent = TESTED_COUNT.toLocaleString('zh-CN'); $('#tested').hidden = false; }
|
||
$('#rMl').innerHTML = LV.map(function (t) { return '<span>' + t.short + '</span>'; }).join('');
|
||
|
||
/* 进场动画:按顺序 60ms 错开 */
|
||
var views = { start: $('#vStart'), quiz: $('#vQuiz'), result: $('#vResult') };
|
||
var io = 'IntersectionObserver' in window ? new IntersectionObserver(function (es) {
|
||
var n = 0;
|
||
es.forEach(function (e) {
|
||
if (!e.isIntersecting) return;
|
||
var el = e.target; io.unobserve(el);
|
||
setTimeout(function () { el.classList.add('in'); }, 60 * n++);
|
||
});
|
||
}, { root: sc, threshold: .08 }) : null;
|
||
/* 11-03 用户:「重新测试后退回首页,再进来还是结果页」→ 记住最后停在哪(开始 / 第几题 / 结果),再进来回到那里 */
|
||
function pos(v) {
|
||
if (v) pos.v = v;
|
||
try { localStorage.setItem(KEY + '.pos', JSON.stringify({ v: pos.v, cur: cur, ans: ans })); } catch (e) {}
|
||
}
|
||
function resume() {
|
||
var p = null; try { p = JSON.parse(localStorage.getItem(KEY + '.pos') || 'null'); } catch (e) {}
|
||
if (!p) return false; /* 旧用户没有记录:照原来的(有结果看结果) */
|
||
if (p.v === 'start') { show('start'); return true; }
|
||
if (p.v === 'quiz' && Array.isArray(p.ans)) { cur = Math.max(0, Math.min(+p.cur || 0, QS.length - 1)); ans = p.ans.slice(0, QS.length); paint(); show('quiz'); return true; }
|
||
return false;
|
||
}
|
||
function show(name) {
|
||
pos(name);
|
||
Object.keys(views).forEach(function (k) { views[k].classList.toggle('on', k === name); });
|
||
sc.scrollTop = 0;
|
||
[].forEach.call(views[name].querySelectorAll('.fade'), function (el) {
|
||
el.classList.remove('in');
|
||
if (io) { io.unobserve(el); io.observe(el); } else el.classList.add('in');
|
||
});
|
||
}
|
||
|
||
/* ================= 答题 ================= */
|
||
var cur = 0, ans = [], busy = false;
|
||
var stage = $('#stage');
|
||
$('#feet').innerHTML = QS.map(function () { return '<svg viewBox="0 0 24 24"><use href="#i-foot" xlink:href="#i-foot"/></svg>'; }).join('');
|
||
var feet = document.querySelectorAll('#feet svg');
|
||
|
||
function paint() {
|
||
var q = QS[cur];
|
||
$('#qNo').textContent = cur + 1;
|
||
[].forEach.call(feet, function (f, i) { f.setAttribute('class', i < cur ? 'done' : i === cur ? 'cur' : ''); });
|
||
useRef($('#qIc'), q.ic);
|
||
$('#qCat').textContent = CATS[q.k].name;
|
||
$('#qTitle').textContent = q.q;
|
||
$('#qOpts').innerHTML = q.o.map(function (o, i) {
|
||
return '<button class="opt' + (ans[cur] === i ? ' sel' : '') + '" data-i="' + i + '"><span class="l">' + 'ABCD'[i] + '</span><span>' + esc(o) +
|
||
'</span><span class="ck"><svg class="ic"><use href="#i-check" xlink:href="#i-check"/></svg></span></button>';
|
||
}).join('');
|
||
$('#prevBtn').disabled = cur === 0;
|
||
if (pos.v === 'quiz') pos();
|
||
}
|
||
|
||
/* 左右滑动:前进 → 当前向左滑出、新题从右滑入;上一题反过来 */
|
||
function swap(dir, after) {
|
||
busy = true;
|
||
stage.classList.add(dir > 0 ? 'outL' : 'outR');
|
||
setTimeout(function () {
|
||
after();
|
||
stage.classList.remove('outL', 'outR');
|
||
stage.classList.add(dir > 0 ? 'inR' : 'inL');
|
||
void stage.offsetWidth;
|
||
stage.classList.remove('inR', 'inL');
|
||
setTimeout(function () { busy = false; }, 220);
|
||
}, 220);
|
||
}
|
||
|
||
$('#qOpts').addEventListener('click', function (e) {
|
||
var b = e.target.closest('.opt'); if (!b || busy) return;
|
||
busy = true;
|
||
ans[cur] = +b.dataset.i;
|
||
[].forEach.call(document.querySelectorAll('#qOpts .opt'), function (x) { x.classList.toggle('sel', x === b); });
|
||
setTimeout(function () {
|
||
if (cur < QS.length - 1) swap(1, function () { cur++; paint(); });
|
||
else { busy = false; finish(); }
|
||
}, 380);
|
||
});
|
||
$('#prevBtn').addEventListener('click', function () {
|
||
if (busy || cur === 0) return;
|
||
swap(-1, function () { cur--; paint(); });
|
||
});
|
||
|
||
function startQuiz() {
|
||
cur = 0; ans = []; busy = false;
|
||
stage.classList.remove('outL', 'outR', 'inL', 'inR');
|
||
paint();
|
||
show('quiz');
|
||
}
|
||
$('#startBtn').addEventListener('click', startQuiz);
|
||
$('#againBtn').addEventListener('click', startQuiz);
|
||
|
||
/* ================= 计分 ================= */
|
||
function score(answers) {
|
||
var c = { body: 0, pace: 0, fam: 0, fear: 0 }, total = 0;
|
||
answers.forEach(function (i, qi) { c[QS[qi].k] += i; total += i; });
|
||
return { cats: c, score: total };
|
||
}
|
||
function pcts(c) { var p = {}; ORDER.forEach(function (k) { p[k] = Math.round(c[k] / CATMAX[k] * 100); }); return p; }
|
||
/* 来源从高到低;同分按 ORDER */
|
||
function rank(c) { return ORDER.slice().sort(function (x, y) { return c[y] - c[x] || ORDER.indexOf(x) - ORDER.indexOf(y); }); }
|
||
/* 某来源里(或全部)分数最高的那道题;同分取靠后的 */
|
||
function heaviest(a, k) {
|
||
var best = -1;
|
||
a.forEach(function (i, qi) { if ((!k || QS[qi].k === k) && (best < 0 || i >= a[best])) best = qi; });
|
||
return best;
|
||
}
|
||
|
||
function finish() {
|
||
var r = score(ans);
|
||
var rec = { score: r.score, cats: r.cats, ans: ans.slice(), at: Date.now() };
|
||
try { localStorage.setItem(KEY, JSON.stringify(rec)); } catch (e) {}
|
||
render(rec, false);
|
||
}
|
||
|
||
/* ================= 解读:引用作答 ================= */
|
||
function quote(a, qi) { return '说到' + QS[qi].s + ',你选了<q>' + esc(QS[qi].o[a[qi]]) + '</q>'; }
|
||
function reading(rec, L) {
|
||
var a = rec.ans, hq = heaviest(a);
|
||
var html = '<p>' + QS.length + ' 道题下来,你的压力指数是 <b class="num">' + rec.score + '</b> / ' + MAXS + ',落在「' + L.name + '」这一档。' + esc(L.desc) + '</p>';
|
||
html += a[hq] >= 2 ? '<p>其中最让你费心的:' + quote(a, hq) + '。能把它说出来,就已经是在照顾自己了。</p>'
|
||
: '<p>比如' + quote(a, hq) + ',这份从容很难得。</p>';
|
||
html += '<p><b>想对你说:</b>' + esc(L.good) + '</p>';
|
||
return html;
|
||
}
|
||
function sources(rec, p, li) {
|
||
var a = rec.ans, L = LV[li], rk = rank(rec.cats);
|
||
var hit = li === 0 ? [] : rk.filter(function (k) { return rec.cats[k] >= 3; }).slice(0, 2);
|
||
var html = '<p>' + esc(L.src) + '</p>';
|
||
if (!hit.length) {
|
||
var k = rk[0];
|
||
html += '<p>' + (rec.cats[k] > 0 ? '相对多一点的是「' + CATS[k].name + '」(<span class="num">' + p[k] + '%</span>):' + quote(a, heaviest(a, k)) + '。' : '') + CATS[k].calm + '</p>';
|
||
} else hit.forEach(function (k) {
|
||
html += '<p><b>' + CATS[k].name + '</b>(<span class="num">' + p[k] + '%</span>):' + CATS[k].src + quote(a, heaviest(a, k)) + '。</p>';
|
||
});
|
||
return html;
|
||
}
|
||
|
||
/* ================= 雷达图(SVG 手写,单系列;刻度固定 100%) ================= */
|
||
function radarPts(p, cx, cy, R) {
|
||
/* 上、右、下、左 */
|
||
var d = [[0, -1], [1, 0], [0, 1], [-1, 0]];
|
||
return ORDER.map(function (k, i) { var r = Math.max(p[k] / 100, .06) * R; return [cx + d[i][0] * r, cy + d[i][1] * r]; });
|
||
}
|
||
function radarSVG(p, top) {
|
||
var cx = 68, cy = 68, R = 44, g = '';
|
||
[1 / 3, 2 / 3, 1].forEach(function (f) {
|
||
var r = R * f; g += '<polygon points="' + [cx, cy - r, cx + r, cy, cx, cy + r, cx - r, cy].join(',') + '" fill="none" stroke="#BFE6E2" stroke-width="1"/>';
|
||
});
|
||
g += '<path d="M' + cx + ' ' + (cy - R) + 'V' + (cy + R) + 'M' + (cx - R) + ' ' + cy + 'H' + (cx + R) + '" stroke="#BFE6E2" stroke-width="1"/>';
|
||
var pts = radarPts(p, cx, cy, R);
|
||
g += '<polygon points="' + pts.map(function (x) { return x.join(','); }).join(' ') + '" fill="rgba(47,163,154,.18)" stroke="#2FA39A" stroke-width="2" stroke-linejoin="round"/>';
|
||
pts.forEach(function (x, i) { g += '<circle cx="' + x[0] + '" cy="' + x[1] + '" r="' + (ORDER[i] === top ? 4.5 : 3.2) + '" fill="#2FA39A" stroke="#fff" stroke-width="1.5"/>'; });
|
||
var L = [[cx, 12, 'middle'], [cx + R + 6, cy + 4, 'start'], [cx, cy + R + 18, 'middle'], [cx - R - 6, cy + 4, 'end']];
|
||
ORDER.forEach(function (k, i) {
|
||
g += '<text x="' + L[i][0] + '" y="' + L[i][1] + '" text-anchor="' + L[i][2] + '" font-size="11" font-weight="' + (k === top ? 800 : 500) + '" fill="' + (k === top ? '#2FA39A' : '#86909C') + '">' + CATS[k].ax + '</text>';
|
||
});
|
||
return g;
|
||
}
|
||
|
||
/* ================= 渲染结果 ================= */
|
||
var curRec = null, curP = null, curL = 0, wk = 0;
|
||
function render(rec, fromCache) {
|
||
var li = level(rec.score), L = LV[li], p = pcts(rec.cats), rk = rank(rec.cats), top = rk[0];
|
||
curRec = rec; curP = p; curL = li;
|
||
$('#rImg').src = L.img; $('#rImg').alt = L.alt;
|
||
$('#rName').textContent = L.name;
|
||
$('#rLine').textContent = L.line;
|
||
var d = new Date(rec.at || Date.now());
|
||
$('#rLast').textContent = (fromCache ? '上次测试 · ' : '') + (d.getMonth() + 1) + '月' + d.getDate() + '日';
|
||
$('#rTags').innerHTML = L.tags.map(function (a) { return '<span>' + esc(a) + '</span>'; }).join('');
|
||
$('#rScore').textContent = rec.score;
|
||
[].forEach.call(document.querySelectorAll('#rMl span'), function (s, i) { s.classList.toggle('on', i === li); });
|
||
$('#rPin').style.left = '0%';
|
||
$('#rRadar').innerHTML = radarSVG(p, top);
|
||
$('#rDims').innerHTML = rk.map(function (k) {
|
||
return '<div class="dr' + (k === top ? ' me' : '') + '"><span>' + CATS[k].name + '</span><span class="p num">' + p[k] + '%</span><span class="tr"><i data-w="' + p[k] + '"></i></span></div>';
|
||
}).join('');
|
||
$('#rRead').innerHTML = reading(rec, L);
|
||
$('#rSrc').innerHTML = sources(rec, p, li);
|
||
$('#rTips').innerHTML = L.tips.map(function (x, i) { return '<div class="tp"><span class="n">' + (i + 1) + '</span><p>' + esc(x) + '</p></div>'; }).join('');
|
||
$('#rMate').innerHTML = '<img src="' + L.img + '" alt=""><span><small>截图或念给家人听,都可以</small><b>请家人帮我一个忙</b><p>' + esc(L.fam) + '</p></span>';
|
||
$('#careBlk').hidden = !L.care;
|
||
$('#rCare').innerHTML = L.care ? L.care.map(function (x) { return '<p>' + esc(x) + '</p>'; }).join('') : '';
|
||
renderTools();
|
||
show('result');
|
||
setTimeout(function () {
|
||
[].forEach.call(document.querySelectorAll('#rDims i'), function (b) { b.style.width = b.dataset.w + '%'; });
|
||
$('#rPin').style.left = (rec.score / MAXS * 100) + '%';
|
||
}, 250);
|
||
}
|
||
function renderTools() {
|
||
if (!curRec || !window.TopicTools) return;
|
||
var el = $('#tools'); el.className = 'fade in';
|
||
TopicTools.render(el, LV[curL].tools, { title: '给自己减减负', color: '#2FA39A', bg: '#E6F6F4', wk: wk });
|
||
}
|
||
|
||
/* 孕周:只用来给推荐工具打「孕N周开放」标签 */
|
||
if (openid) {
|
||
fetch('/api/mp/public/mama-box/pregnancy?openid=' + encodeURIComponent(openid))
|
||
.then(function (r) { return r.ok ? r.json() : null; })
|
||
.then(function (j) {
|
||
var p = j && j.code === 200 && j.result;
|
||
if (p && !p.postpartum && !p.empty && p.week != null) { wk = +p.week || 0; renderTools(); }
|
||
}).catch(function () {});
|
||
}
|
||
|
||
/* ================= 提示(用户要求结果页不放「复制发给 xx」类按钮) ================= */
|
||
var tt;
|
||
function toast(msg) {
|
||
var el = $('#toast'); el.textContent = msg; el.classList.add('on');
|
||
clearTimeout(tt); tt = setTimeout(function () { el.classList.remove('on'); }, 2400);
|
||
}
|
||
|
||
/* ================= 保存结果卡:canvas 画图 → <img> 长按保存 ================= */
|
||
var FONT = '-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif';
|
||
function rr(ctx, x, y, w, h, r) {
|
||
ctx.beginPath(); ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r);
|
||
ctx.arcTo(x, y + h, x, y, r); ctx.arcTo(x, y, x + w, y, r); ctx.closePath();
|
||
}
|
||
function loadImg(src) { return new Promise(function (ok, no) { var im = new Image(); im.onload = function () { ok(im); }; im.onerror = no; im.src = src; }); }
|
||
function drawCard(im) {
|
||
var L = LV[curL], p = curP, rk = rank(curRec.cats), top = rk[0], W = 750, H = 1310;
|
||
var cv = document.createElement('canvas'); cv.width = W; cv.height = H;
|
||
var ctx = cv.getContext('2d');
|
||
var g = ctx.createLinearGradient(0, 0, W * .3, H);
|
||
g.addColorStop(0, '#D3F0EC'); g.addColorStop(.45, '#EEF9F7'); g.addColorStop(1, '#FFFFFF');
|
||
ctx.fillStyle = g; ctx.fillRect(0, 0, W, H);
|
||
ctx.fillStyle = 'rgba(255,255,255,.55)'; ctx.beginPath(); ctx.arc(660, 90, 230, 0, 7); ctx.fill();
|
||
ctx.fillStyle = 'rgba(47,163,154,.06)'; ctx.beginPath(); ctx.arc(40, 470, 150, 0, 7); ctx.fill();
|
||
ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
|
||
/* 顶部胶囊 */
|
||
ctx.font = '700 24px ' + FONT;
|
||
var lb = '我的孕期压力卡', lw = ctx.measureText(lb).width + 44;
|
||
ctx.fillStyle = '#fff'; rr(ctx, (W - lw) / 2, 52, lw, 48, 24); ctx.fill();
|
||
ctx.fillStyle = '#2FA39A'; ctx.fillText(lb, W / 2, 84);
|
||
/* 插画 */
|
||
var S = 320, ix = (W - S) / 2, iy = 132;
|
||
ctx.save(); ctx.shadowColor = 'rgba(47,163,154,.18)'; ctx.shadowBlur = 36; ctx.shadowOffsetY = 12;
|
||
ctx.fillStyle = '#fff'; rr(ctx, ix - 10, iy - 10, S + 20, S + 20, 60); ctx.fill(); ctx.restore();
|
||
ctx.save(); rr(ctx, ix, iy, S, S, 52); ctx.clip();
|
||
var sw = im.naturalWidth, sh = im.naturalHeight, side = Math.min(sw, sh);
|
||
ctx.drawImage(im, (sw - side) / 2, (sh - side) * .3, side, side, ix, iy, S, S); ctx.restore();
|
||
/* 档位名 */
|
||
ctx.fillStyle = '#86909C'; ctx.font = '400 26px ' + FONT; ctx.fillText('最近的我是', W / 2, 520);
|
||
ctx.font = '800 60px ' + FONT;
|
||
var nm = L.name, nw = ctx.measureText(nm).width;
|
||
ctx.fillStyle = 'rgba(47,163,154,.20)'; ctx.fillRect((W - nw) / 2 - 4, 566, nw + 8, 24);
|
||
ctx.fillStyle = '#1F2329'; ctx.fillText(nm, W / 2, 588);
|
||
ctx.fillStyle = '#4E5969'; ctx.font = '400 28px ' + FONT; ctx.fillText(L.line, W / 2, 640);
|
||
/* 关键词 */
|
||
ctx.font = '700 26px ' + FONT;
|
||
var ws = L.tags.map(function (s) { return ctx.measureText(s).width + 44; }), gap = 16;
|
||
var tx = (W - ws.reduce(function (a, b) { return a + b; }, 0) - gap * 2) / 2;
|
||
L.tags.forEach(function (s, i) {
|
||
ctx.save(); ctx.shadowColor = 'rgba(47,163,154,.12)'; ctx.shadowBlur = 14; ctx.shadowOffsetY = 4;
|
||
ctx.fillStyle = '#fff'; rr(ctx, tx, 680, ws[i], 56, 28); ctx.fill(); ctx.restore();
|
||
ctx.fillStyle = '#2FA39A'; ctx.fillText(s, tx + ws[i] / 2, 717); tx += ws[i] + gap;
|
||
});
|
||
/* 压力指数条 */
|
||
ctx.fillStyle = 'rgba(255,255,255,.9)'; rr(ctx, 40, 760, 670, 106, 32); ctx.fill();
|
||
ctx.textAlign = 'left'; ctx.fillStyle = '#4E5969'; ctx.font = '400 25px ' + FONT; ctx.fillText('压力指数', 72, 802);
|
||
ctx.textAlign = 'right'; ctx.fillStyle = '#86909C'; ctx.font = '600 24px ' + FONT; ctx.fillText(' / ' + MAXS, 678, 802);
|
||
var sl = ctx.measureText(' / ' + MAXS).width;
|
||
ctx.fillStyle = '#2FA39A'; ctx.font = '800 38px ' + FONT; ctx.fillText(String(curRec.score), 678 - sl, 804);
|
||
var bx = 72, bw = 606, by = 822, sg = 8, segw = (bw - sg * 3) / 4;
|
||
[.22, .42, .68, 1].forEach(function (o, i) { ctx.fillStyle = 'rgba(47,163,154,' + o + ')'; rr(ctx, bx + i * (segw + sg), by, segw, 14, 7); ctx.fill(); });
|
||
ctx.beginPath(); ctx.arc(bx + bw * curRec.score / MAXS, by + 7, 14, 0, 7); ctx.fillStyle = '#fff'; ctx.fill(); ctx.lineWidth = 7; ctx.strokeStyle = '#2FA39A'; ctx.stroke();
|
||
/* 来源面板 */
|
||
var P = 884;
|
||
ctx.fillStyle = 'rgba(255,255,255,.9)'; rr(ctx, 40, P, 670, 300, 36); ctx.fill();
|
||
var cx = 205, cy = P + 150, R = 88;
|
||
ctx.strokeStyle = '#BFE6E2'; ctx.lineWidth = 2;
|
||
[1 / 3, 2 / 3, 1].forEach(function (f) { var r = R * f; ctx.beginPath(); ctx.moveTo(cx, cy - r); ctx.lineTo(cx + r, cy); ctx.lineTo(cx, cy + r); ctx.lineTo(cx - r, cy); ctx.closePath(); ctx.stroke(); });
|
||
ctx.beginPath(); ctx.moveTo(cx, cy - R); ctx.lineTo(cx, cy + R); ctx.moveTo(cx - R, cy); ctx.lineTo(cx + R, cy); ctx.stroke();
|
||
var pts = radarPts(p, cx, cy, R);
|
||
ctx.beginPath(); pts.forEach(function (x, i) { i ? ctx.lineTo(x[0], x[1]) : ctx.moveTo(x[0], x[1]); }); ctx.closePath();
|
||
ctx.fillStyle = 'rgba(47,163,154,.18)'; ctx.fill(); ctx.strokeStyle = '#2FA39A'; ctx.lineWidth = 4; ctx.lineJoin = 'round'; ctx.stroke();
|
||
pts.forEach(function (x, i) { ctx.beginPath(); ctx.arc(x[0], x[1], ORDER[i] === top ? 9 : 6.5, 0, 7); ctx.fillStyle = '#2FA39A'; ctx.fill(); ctx.lineWidth = 3; ctx.strokeStyle = '#fff'; ctx.stroke(); });
|
||
var LB = [[cx, cy - R - 16, 'center'], [cx + R + 12, cy + 8, 'left'], [cx, cy + R + 34, 'center'], [cx - R - 12, cy + 8, 'right']];
|
||
ORDER.forEach(function (k, i) {
|
||
ctx.textAlign = LB[i][2]; ctx.font = (k === top ? '800' : '500') + ' 22px ' + FONT;
|
||
ctx.fillStyle = k === top ? '#2FA39A' : '#86909C'; ctx.fillText(CATS[k].ax, LB[i][0], LB[i][1]);
|
||
});
|
||
rk.forEach(function (k, i) {
|
||
var y = P + 62 + i * 64, me = k === top;
|
||
ctx.textAlign = 'left'; ctx.font = (me ? '700' : '400') + ' 25px ' + FONT; ctx.fillStyle = me ? '#2FA39A' : '#4E5969'; ctx.fillText(CATS[k].name, 388, y + 10);
|
||
ctx.textAlign = 'right'; ctx.font = '700 25px ' + FONT; ctx.fillStyle = me ? '#2FA39A' : '#1F2329'; ctx.fillText(p[k] + '%', 674, y + 10);
|
||
ctx.fillStyle = '#E3F4F2'; rr(ctx, 388, y + 24, 286, 10, 5); ctx.fill();
|
||
ctx.fillStyle = me ? '#2FA39A' : '#9BD6CF'; rr(ctx, 388, y + 24, Math.max(10, 286 * p[k] / 100), 10, 5); ctx.fill();
|
||
});
|
||
/* 底部 */
|
||
ctx.textAlign = 'center';
|
||
ctx.fillStyle = '#1F2329'; ctx.font = '700 26px ' + FONT; ctx.fillText('测一测:你最近的孕期压力有多大?', W / 2, 1238);
|
||
ctx.fillStyle = '#86909C'; ctx.font = '400 21px ' + FONT; ctx.fillText('兜爸心选 · 孕期专题 · 自测仅供参考,不能代替医生判断', W / 2, 1274);
|
||
return cv.toDataURL('image/png');
|
||
}
|
||
var isWx = /MicroMessenger/i.test(navigator.userAgent);
|
||
$('#saveBtn').addEventListener('click', function () {
|
||
if (!curRec) return;
|
||
toast('正在生成结果卡…');
|
||
loadImg(LV[curL].img).then(function (im) {
|
||
var url = drawCard(im);
|
||
$('#maskImg').src = url;
|
||
var dl = $('#dlBtn'); dl.href = url; dl.hidden = isWx;
|
||
$('#toast').classList.remove('on');
|
||
$('#mask').classList.add('on');
|
||
}).catch(function () { toast('生成失败,截个图保存也可以'); });
|
||
});
|
||
$('#maskClose').addEventListener('click', function () { $('#mask').classList.remove('on'); });
|
||
$('#mask').addEventListener('click', function (e) { if (e.target === this) this.classList.remove('on'); });
|
||
|
||
/* 入口:有上次结果直接看结果,否则开始页 */
|
||
var saved = null;
|
||
try { saved = JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) {}
|
||
if (resume()) ;
|
||
else if (saved && saved.cats && saved.ans && saved.ans.length === QS.length && typeof saved.score === 'number') render(saved, true);
|
||
else show('start');
|
||
|
||
/* 禁止下拉回弹:固定外壳 + 容器滚动 + 到顶/到底时拦 touchmove */
|
||
var y0 = 0;
|
||
sc.addEventListener('touchstart', function (e) { y0 = e.touches[0].clientY; }, { passive: true });
|
||
sc.addEventListener('touchmove', function (e) {
|
||
var dy = e.touches[0].clientY - y0;
|
||
if ((sc.scrollTop <= 0 && dy > 0) || (sc.scrollTop + sc.clientHeight >= sc.scrollHeight - 1 && dy < 0)) e.preventDefault();
|
||
}, { passive: false });
|
||
document.addEventListener('touchmove', function (e) { if (!sc.contains(e.target)) e.preventDefault(); }, { passive: false });
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|