Files
mama-box/topic/huafei/index.html

448 lines
27 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<title>生娃计算器 · 到底要花多少钱</title>
<!-- 孕期专题 · 生娃计算器(孕期首页「其他妈妈也在搜」第 1 条入口)。
2026-10-31 v2 重做:按 topic-spec v2(主色 #18A058),改成「一屏一题 → 出结果」的分步计算器。
开始屏 → 7 个问题(城市 / 医院 / 分娩 / 月子 / 喂养 / 1~3 岁谁带 / 花钱风格)→ 结果屏(生下来 / 养到 1、2、3 岁切换)。
选择存 localStorage「mmbox.huafei.v2」,再进来直接看上次结果。改价格只改脚本顶部 COST 表。
自成一页:不引 app.js;返回走 history.back 或相对路径 ../../ 并带回 search + hash。 -->
<style>
:root{--c:#18A058;--cbg:#EAF7F0;--h:#1F2329;--t:#4E5969;--s:#86909C;--line:#EEF0F3;--gray:#F7F8FA}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%;overflow:hidden;background:#fff;color:var(--t);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(28px + 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}
/* 顶栏 */
.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:rgba(255,255,255,0);border-bottom:1px solid transparent;transition:background .2s,border-color .2s}
.bar.on{background:#fff;border-bottom-color:var(--line)}
.bar .back{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;color:var(--h)}
.bar .back .ic{width:22px;height:22px}
.bar .t{font-size:16px;font-weight:600;color:var(--h)}
.screen{display:none;padding:0 20px}
.screen.on{display:block;animation:fd .35s ease both}
@keyframes fd{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.screen.on{animation:none}}
.btn{display:flex;align-items:center;justify-content:center;width:100%;height:46px;border-radius:99px;background:var(--c);color:#fff;font-size:16px;font-weight:600}
.btn.ghost{background:#fff;color:var(--c);border:1px solid var(--c)}
/* 开始屏 */
.hero{margin-top:8px;height:200px;border-radius:20px;overflow:hidden;background:var(--gray)}
.hero img{width:100%;height:100%;object-fit:cover}
h1{margin-top:22px;font-size:26px;font-weight:800;line-height:1.3;color:var(--h)}
.lead{margin-top:8px;color:var(--t)}
.start-list{margin:20px 0 26px;padding:14px 16px;border-radius:18px;background:var(--gray);display:grid;grid-template-columns:1fr 1fr;gap:6px 12px;font-size:13.5px;color:var(--t);line-height:1.6}
.start-list span{display:flex;align-items:center;gap:6px}
.start-list i{flex:none;width:5px;height:5px;border-radius:50%;background:var(--c)}
.tiny{margin-top:12px;font-size:12.5px;color:var(--s);text-align:center;line-height:1.6}
/* 问题屏 */
.prog{display:flex;align-items:center;gap:12px;margin-top:6px}
.prog .pb{flex:1;height:6px;border-radius:9px;background:var(--line);overflow:hidden}
.prog .pb i{display:block;height:100%;border-radius:9px;background:var(--c);transition:width .3s}
.prog span{font-size:13px;color:var(--s);font-variant-numeric:tabular-nums}
.qh{margin-top:26px;font-size:22px;font-weight:800;line-height:1.35;color:var(--h)}
.qs{margin-top:4px;font-size:13.5px;color:var(--s)}
.opts{margin-top:20px;display:flex;flex-direction:column;gap:12px}
.opt{display:flex;align-items:center;gap:12px;width:100%;min-height:68px;padding:12px 16px;border-radius:18px;border:1.5px solid var(--line);background:#fff;text-align:left;transition:border-color .15s,background .15s}
.opt .ox{flex:1;min-width:0}
.opt b{display:block;font-size:16.5px;font-weight:700;color:var(--h);line-height:1.4}
.opt small{display:block;margin-top:2px;font-size:13px;color:var(--s);line-height:1.45}
.opt .rd{flex:none;width:22px;height:22px;border-radius:50%;border:1.5px solid #D5D9DE;display:grid;place-items:center}
.opt.on{border-color:var(--c);background:var(--cbg)}
.opt.on .rd{border-color:var(--c);background:var(--c)}
.opt.on .rd::after{content:"";width:8px;height:8px;border-radius:50%;background:#fff}
.prev{display:inline-flex;align-items:center;gap:2px;margin-top:22px;padding:6px 4px;font-size:14px;color:var(--s)}
.prev .ic{width:18px;height:18px}
/* 结果屏 */
.r-t{margin-top:6px;font-size:20px;font-weight:800;color:var(--h)}
.chips{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px}
.chips button{padding:2px 10px;border-radius:99px;background:var(--gray);font-size:12.5px;color:var(--t);line-height:1.8}
.hint{margin-top:6px;font-size:12.5px;color:var(--s)}
.tabs{margin-top:16px;display:flex;padding:3px;border-radius:99px;background:var(--gray)}
.tabs button{flex:1;min-width:0;height:36px;border-radius:99px;font-size:14px;color:var(--t);white-space:nowrap;transition:background .2s,color .2s}
.tabs button.on{background:#fff;color:var(--c);font-weight:700;box-shadow:0 2px 8px rgba(0,0,0,.06)}
.total{margin-top:14px;padding:20px 16px 18px;border-radius:18px;background:var(--cbg);text-align:center}
.total .l{font-size:13px;color:var(--t)}
.total .v{margin-top:2px;font-size:30px;font-weight:800;color:var(--c);line-height:1.3;font-variant-numeric:tabular-nums}
.total .v span{white-space:nowrap}
.total .m{margin-top:4px;font-size:13.5px;color:var(--t)}
.total .m b{color:var(--h)}
.stack{margin-top:18px;display:flex;gap:2px;height:12px;border-radius:9px;overflow:hidden}
.stack i{display:block;height:100%;transition:flex-grow .4s,background .3s}
.list{margin-top:10px;border-top:1px solid var(--line)}
.list details{border-bottom:1px solid var(--line)}
.list summary{list-style:none;display:flex;align-items:center;gap:10px;padding:13px 2px;cursor:pointer}
.list summary::-webkit-details-marker{display:none}
.list .dot{flex:none;width:10px;height:10px;border-radius:3px}
.list .nm{flex:1;min-width:0;font-size:15px;color:var(--h)}
.list .rg{font-size:15px;font-weight:700;color:var(--h);white-space:nowrap;font-variant-numeric:tabular-nums}
.list .ar{flex:none;width:16px;height:16px;color:#C0C5CC;transition:transform .2s}
.list details[open] .ar{transform:rotate(180deg)}
.list .ds{padding:0 2px 12px 20px;font-size:13px;color:var(--s);line-height:1.6}
.list details.off .nm,.list details.off .rg{color:#C0C5CC;font-weight:400}
.list details.off .rg{font-size:13px}
.card{margin-top:16px;padding:14px 16px;border-radius:18px;border:1px solid var(--line);background:#fff}
.row{display:flex;gap:10px;align-items:flex-start}
.row+.row{margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.row .ic{margin-top:3px;color:var(--c)}
.row b{display:block;font-size:15px;color:var(--h);line-height:1.5}
.row b em{font-style:normal;color:var(--c)}
.row p{font-size:13.5px;color:var(--t);line-height:1.6}
.ins p{margin-top:2px}
.ins .f span{white-space:nowrap}
.ins .f{display:inline-block;margin-top:6px;padding:4px 10px;border-radius:10px;background:var(--gray);font-size:12.5px;color:var(--h)}
.acts{margin-top:22px}
.note{margin-top:14px;font-size:12px;color:var(--s);line-height:1.6;text-align:center}
</style>
</head>
<body>
<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-down" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></symbol>
<symbol id="i-coin" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9 7.5l3 4 3-4M12 11.5V17M9 12.5h6M9 15h6"/></symbol>
<symbol id="i-bulb" viewBox="0 0 24 24"><path d="M9 18.5h6M10.2 21.5h3.6M12 3a6 6 0 0 0-4 10.5c.7.7 1 1.5 1 2.5h6c0-1 .3-1.8 1-2.5A6 6 0 0 0 12 3z"/></symbol>
<symbol id="i-shield" viewBox="0 0 24 24"><path d="M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6z"/><path d="M9 12l2 2 4-4"/></symbol>
</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>
<!-- 开始屏 -->
<section class="screen" id="sStart">
<div class="hero"><img src="img/hero.webp" alt="孕妈在桌前记账"></div>
<h1>生娃计算器<br>到底要花多少钱?</h1>
<p class="lead">回答 7 个小问题,算出从怀孕到宝宝 3 岁大概要花多少。</p>
<div class="start-list">
<span><i></i>孕期产检</span><span><i></i>分娩住院</span>
<span><i></i>坐月子</span><span><i></i>养到 1~3 岁</span>
</div>
<button class="btn" id="go">开始计算</button>
<p class="tiny">约 1 分钟 · 不用填个人信息</p>
</section>
<!-- 问题屏 -->
<section class="screen" id="sQ">
<div class="prog"><div class="pb"><i id="pbar"></i></div><span id="pnum">1 / 7</span></div>
<h2 class="qh" id="qh"></h2>
<p class="qs" id="qs"></p>
<div class="opts" id="opts"></div>
<button class="prev" id="prev"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg>上一步</button>
</section>
<!-- 结果屏 -->
<section class="screen" id="sRes">
<h2 class="r-t">你家大概要花</h2>
<div class="chips" id="chips"></div>
<p class="hint">点任一项可单独修改</p>
<div class="tabs" id="tabs">
<button data-s="0">生下来</button><button data-s="1">养到1岁</button><button data-s="2">养到2岁</button><button data-s="3">养到3岁</button>
</div>
<div class="total" aria-live="polite">
<div class="l" id="totL"></div>
<div class="v" id="totV"></div>
<div class="m" id="totM"></div>
</div>
<div class="stack" id="stack"></div>
<div class="list" id="list"></div>
<div class="card">
<div class="row"><svg class="ic"><use href="#i-coin" xlink:href="#i-coin"/></svg><div><b id="bigT"></b><p id="bigD"></p></div></div>
<div class="row"><svg class="ic"><use href="#i-bulb" xlink:href="#i-bulb"/></svg><div><b>能省的地方</b><p id="save"></p></div></div>
</div>
<div class="card ins">
<div class="row"><svg class="ic"><use href="#i-shield" xlink:href="#i-shield"/></svg><div>
<b>生育保险能报一部分</b>
<p>产检和分娩费用可按规定报销;产假期间还能领生育津贴。以当地医保为准。</p>
<span class="f"><span>生育津贴 = 单位上年度职工月平均工资</span> <span>÷ 30 × 产假天数</span></span>
</div></div>
</div>
<div class="acts"><button class="btn ghost" id="redo">重新选择</button></div>
<p class="note">按常见价格区间粗略估算,各地各医院差别很大,以实际为准;不含孕期并发症、早产、住院等意外支出。</p>
</section>
</div>
<script>
(function () {
'use strict';
/* ================= 费用表(单位:元,[低, 高],医保报销前的常见区间,偏保守取整) =================
城市下标 c:0 一线 / 1 新一线及省会 / 2 普通地级市 / 3 县城及乡镇
×STYLE 的项是「可选消费」,按第 7 题花钱风格乘系数;其余是刚性支出,不乘。 */
var COST = {
// —— 生下来 ——
// 孕期产检全程(约 10~13 次 + 筛查)[c][医院],医院 0 公立普通 / 1 公立特需或单间 / 2 私立
check: [
[[6000, 10000], [15000, 30000], [20000, 50000]],
[[4000, 8000], [10000, 20000], [15000, 35000]],
[[3000, 6000], [6000, 12000], [8000, 20000]],
[[2000, 4000], [4000, 8000], [5000, 12000]]
],
// 孕妇装、待产包等孕期用品 [c],×STYLE
pregGoods: [[2000, 5000], [1500, 4000], [1200, 3000], [1000, 2500]],
// 分娩住院 [c][医院][方式],方式 0 顺产 / 1 剖宫产;「还不确定」取两者合并区间(顺产低值 ~ 剖宫产高值)
birth: [
[[[6000, 12000], [12000, 20000]], [[15000, 30000], [25000, 45000]], [[30000, 60000], [45000, 90000]]],
[[[4000, 8000], [8000, 15000]], [[10000, 20000], [15000, 30000]], [[18000, 40000], [28000, 60000]]],
[[[3000, 6000], [6000, 11000]], [[6000, 12000], [10000, 18000]], [[10000, 25000], [15000, 35000]]],
[[[2000, 4000], [4000, 8000]], [[4000, 8000], [6000, 12000]], [[6000, 15000], [10000, 22000]]]
],
// 坐月子(含月子餐、产妇用品)[c][方式],0 家人照顾 / 1 月嫂约 26 天 / 2 月子中心约 28 天
yuezi: [
[[3000, 8000], [15000, 30000], [40000, 100000]],
[[2500, 6000], [10000, 20000], [25000, 60000]],
[[2000, 5000], [7000, 14000], [15000, 35000]],
[[1500, 4000], [5000, 10000], [10000, 25000]]
],
// —— 0~1 岁 ——
eat01: [[1000, 3000], [5000, 9000], [8000, 14000]], // 奶粉/辅食 [喂养]:0 母乳为主 / 1 混合 / 2 奶粉为主(不分城市)
diaper01: [3000, 5000], // 纸尿裤湿巾(不分城市)
goods01: [[5000, 10000], [4000, 8000], [3000, 6000], [2500, 5000]], // 衣物、婴儿床推车安全座椅、洗护玩具 [c],×STYLE
med01: [[1500, 6000], [1200, 5000], [1000, 4000], [800, 3000]], // 看病 + 自费疫苗 [c]
// 0~1 岁按产假 + 家人带计,不算带娃费用(第 6 题只管 1~3 岁)
// —— 1~2 岁 ——
eat12: [[3000, 6000], [5000, 9000], [6000, 11000]], // 奶粉/辅食/日常饮食 [喂养]
diaper12: [2500, 4000],
goods12: [[4000, 8000], [3000, 6000], [2500, 5000], [2000, 4000]], // 衣物用品玩具 [c],×STYLE
edu12: [[2000, 8000], [1500, 6000], [1000, 4000], [500, 3000]], // 早教、绘本、游乐 [c],×STYLE
med12: [[1200, 4000], [1000, 3500], [800, 3000], [600, 2500]],
// —— 2~3 岁 ——
eat23: [[6000, 10000], [5000, 8000], [4000, 7000], [3000, 6000]], // 日常饮食 + 牛奶 [c]
diaper23: [800, 2000], // 逐步戒纸尿裤
goods23: [[4000, 8000], [3000, 6000], [2500, 5000], [2000, 4000]], // ×STYLE
edu23: [[3000, 10000], [2000, 8000], [1500, 5000], [800, 3500]], // ×STYLE
med23: [[1000, 3500], [800, 3000], [600, 2500], [500, 2000]],
// —— 1~3 岁谁来带(按年计)[带法][c] ——
// 0 老人或自己带:少量补贴(约 100~1000 元/月)
// 1 育儿嫂或保姆:月薪 × 12;2 托育园全日托:月费 × 12
care: [
[[4800, 12000], [3600, 9600], [2400, 7200], [1200, 6000]],
[[7000 * 12, 10000 * 12], [5000 * 12, 7500 * 12], [4000 * 12, 6000 * 12], [3000 * 12, 4500 * 12]],
[[4000 * 12, 8000 * 12], [2500 * 12, 5000 * 12], [1800 * 12, 3500 * 12], [1200 * 12, 2500 * 12]]
],
STYLE: [0.6, 1, 1.8] // 花钱风格系数:精打细算 / 适中 / 想给最好的
};
/* ================= 问题 ================= */
var QS = [
{ k: 'city', h: '你在哪类城市?', s: '各地价格差别最大的一项', o: [
['一线城市', '北京、上海、广州、深圳'], ['新一线及省会', '如成都、杭州、武汉、各省会'], ['普通地级市', '三四线城市'], ['县城及乡镇', '县城、镇上']] },
{ k: 'hosp', h: '打算在哪生?', s: '产检一般也在同一家', o: [
['公立医院普通病房', '多人间,大多数人的选择'], ['公立医院特需或单间', '单人间、特需门诊,部分自费'], ['私立医院', '环境服务好,基本全自费']] },
{ k: 'way', h: '分娩方式?', s: '最终听医生评估', o: [
['顺产', '住院约 2~3 天'], ['剖宫产', '住院约 4~6 天,费用更高'], ['还不确定', '两种都算进去,区间宽一些']] },
{ k: 'yz', h: '月子怎么坐?', s: '这项差距最大', o: [
['家人照顾', '主要花在月子餐和产妇用品'], ['请月嫂', '上门照顾,一般 26 天'], ['月子中心', '一般 28 天套餐']] },
{ k: 'feed', h: '宝宝怎么喂?', s: '大概的打算就行', o: [
['母乳为主', '奶粉钱很少'], ['混合喂养', '母乳加一部分奶粉'], ['奶粉为主', '奶粉是每月固定开销']] },
{ k: 'care', h: '1~3 岁谁来带?', s: '产假结束后的安排', o: [
['老人或自己带', '给老人一点补贴'], ['请育儿嫂或保姆', '按月薪算'], ['上托育园(全日托)', '按月费算']] },
{ k: 'style', h: '平时花钱风格?', s: '影响用品、衣物、玩具、早教', o: [
['精打细算', '够用就行,能借能用二手'], ['适中', '买点好的,不追高'], ['想给最好的', '用品玩具早教都挑好的']] }
];
var SHORT = { // 结果页的选择标签
city: ['一线', '新一线/省会', '地级市', '县城乡镇'], hosp: ['公立普通', '公立特需', '私立'], way: ['顺产', '剖宫产', '方式未定'],
yz: ['家人坐月子', '请月嫂', '月子中心'], feed: ['母乳', '混合喂养', '奶粉'], care: ['老人带', '育儿嫂', '托育园'], style: ['精打细算', '适中', '给最好的']
};
var STAGES = ['孕期产检', '分娩住院', '坐月子', '0~1岁', '1~2岁', '2~3岁'];
var SHADES = ['#0B6E3A', '#18A058', '#45B779', '#79CC9E', '#A8DFC0', '#D2F0DF'];
var TAB_L = ['怀孕到坐完月子', '怀孕到宝宝 1 岁', '怀孕到宝宝 2 岁', '怀孕到宝宝 3 岁'];
var UPTO = [3, 4, 5, 6]; // 每个标签包含前几段
var MONTHS = [10, 21, 33, 45]; // 平均每月的分母:怀孕约 9 个月 + 月子 1 个月;之后每岁 12 个月
var KEY = 'mmbox.huafei.v2';
var $ = function (s) { return document.querySelector(s); };
var sc = $('#scroll');
var st = { city: 1, hosp: 0, way: 2, yz: 0, feed: 1, care: 0, style: 1 };
var stage = 1, qi = 0, editing = false;
function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
function mul(a, k) { return [a[0] * k, a[1] * k]; }
function sum() { return [].slice.call(arguments).reduce(add, [0, 0]); }
/* 六段费用,返回 [[低, 高] × 6] */
function calc(s) {
var c = s.city, k = COST.STYLE[s.style];
var b = COST.birth[c][s.hosp];
var birth = s.way === 2 ? [Math.min(b[0][0], b[1][0]), Math.max(b[0][1], b[1][1])] : b[s.way];
var care = COST.care[s.care][c];
return [
sum(COST.check[c][s.hosp], mul(COST.pregGoods[c], k)),
birth,
COST.yuezi[c][s.yz],
sum(COST.eat01[s.feed], COST.diaper01, mul(COST.goods01[c], k), COST.med01[c]),
sum(COST.eat12[s.feed], COST.diaper12, mul(COST.goods12[c], k), mul(COST.edu12[c], k), COST.med12[c], care),
sum(COST.eat23[c], COST.diaper23, mul(COST.goods23[c], k), mul(COST.edu23[c], k), COST.med23[c], care)
];
}
function wan(n) { return (Math.round(n / 1000) / 10) + '万'; }
function yuan(n) { return String(Math.round(n / 100) * 100).replace(/\B(?=(\d{3})+(?!\d))/g, ','); }
function rng(a) { return wan(a[0]) + '~' + wan(a[1]); } // 统一用「万」,一位小数
function detail(i) {
var s = st;
var careTxt = ['老人带的少量补贴', '育儿嫂 12 个月工资', '托育园 12 个月费用'][s.care];
return [
'约 10~13 次产检和筛查(' + QS[1].o[s.hosp][0] + '),加孕妇装、待产包',
(s.way === 2 ? '按顺产到剖宫产的范围算' : QS[2].o[s.way][0] + ',' + QS[2].o[s.way][1].replace(',费用更高', '')) + ';含接生或手术、麻醉、床位、新生儿筛查',
['月子餐食材、产妇用品、产后复查', '月嫂约 26 天工资,加月子餐和产妇用品', '月子中心约 28 天套餐,含住宿餐食和母婴护理'][s.yz],
QS[4].o[s.feed][0] + '的奶粉辅食、纸尿裤、衣物和婴儿床推车等用品、看病和自费疫苗',
'奶粉辅食、纸尿裤、衣物玩具早教、看病疫苗,加' + careTxt,
'日常饮食、纸尿裤(逐步戒掉)、衣物玩具早教、看病,加' + careTxt
][i];
}
/* 能省的地方(≤30 字),按最花钱的那段给 */
function saveTip(i) {
var s = st;
if (i === 0) return s.hosp ? '常规产检在公立医院做,只把分娩放在想去的医院。' : '跟着医生的产检表走,不额外加做没必要的项目。';
if (i === 1) return s.hosp ? '公立医院普通病房也安全,单间按需再升级。' : '提前问清医保能不能直接结算,出院少垫钱。';
if (i === 2) return s.yz === 2 ? '月子中心可只住 2 周,后面换月嫂或家人接手。' : s.yz === 1 ? '月嫂可只请前 2 周,之后家人接手。' : '月子餐自己做,产妇用品按需买不囤货。';
if (i === 3) return s.feed ? '奶粉先买小罐试,宝宝适合再按需补,别囤货。' : '大件用品能借就借,衣服各尺码几套够换洗就行。';
if (s.care === 1) return '老人能搭把手的话,育儿嫂可只请白天或半天。';
if (s.care === 2) return '托育园可先上半日托,或等 2 岁后再上全日托。';
return s.style === 2 ? '早教班不用早报,玩具绘本可以轮换或借阅。' : '衣物玩具亲友送、买二手都行,省下的留作备用金。';
}
/* ================= 屏幕切换 ================= */
function show(id) {
[].forEach.call(document.querySelectorAll('.screen'), function (el) { el.classList.toggle('on', el.id === id); });
sc.scrollTop = 0;
}
function renderQ() {
var q = QS[qi];
$('#pbar').style.width = ((qi + 1) / QS.length * 100) + '%';
$('#pnum').textContent = (qi + 1) + ' / ' + QS.length;
$('#qh').textContent = q.h;
$('#qs').textContent = q.s;
$('#opts').innerHTML = q.o.map(function (o, v) {
return '<button class="opt' + (st[q.k] === v && st._done ? ' on' : '') + '" data-v="' + v + '"><span class="ox"><b>' + o[0] + '</b><small>' + o[1] + '</small></span><span class="rd"></span></button>';
}).join('');
$('#prev').style.visibility = editing ? 'hidden' : 'visible';
show('sQ');
}
$('#opts').addEventListener('click', function (e) {
var b = e.target.closest('.opt'); if (!b || $('#opts').dataset.lock) return;
[].forEach.call(this.children, function (x) { x.classList.toggle('on', x === b); });
st[QS[qi].k] = +b.dataset.v;
$('#opts').dataset.lock = '1';
setTimeout(function () {
delete $('#opts').dataset.lock;
if (editing || qi === QS.length - 1) { st._done = true; editing = false; save(); renderRes(); show('sRes'); }
else { qi++; renderQ(); }
}, 220);
});
$('#prev').addEventListener('click', function () { if (qi > 0) { qi--; renderQ(); } else show('sStart'); });
$('#go').addEventListener('click', function () { qi = 0; editing = false; renderQ(); });
$('#redo').addEventListener('click', function () { qi = 0; editing = false; renderQ(); });
function renderRes() {
var parts = calc(st), n = UPTO[stage];
var mids = parts.map(function (p) { return (p[0] + p[1]) / 2; });
var all = mids.reduce(function (a, b) { return a + b; }, 0);
var tot = parts.slice(0, n).reduce(add, [0, 0]);
[].forEach.call($('#tabs').children, function (b, i) { b.classList.toggle('on', i === stage); });
$('#chips').innerHTML = QS.map(function (q, i) { return '<button data-q="' + i + '">' + SHORT[q.k][st[q.k]] + '</button>'; }).join('');
$('#totL').textContent = TAB_L[stage] + ',合计约';
var w = tot[1] >= 10000;
$('#totV').innerHTML = '<span>' + (w ? wan(tot[0]) : yuan(tot[0])) + '~</span><wbr><span>' + (w ? wan(tot[1]) : yuan(tot[1]) + '元') + '</span>';
$('#totM').innerHTML = '平均每月约 <b>' + yuan((tot[0] + tot[1]) / 2 / MONTHS[stage]) + '</b> 元';
$('#stack').innerHTML = mids.map(function (m, i) {
return '<i style="flex-grow:' + (m / all * 1000).toFixed(0) + ';background:' + (i < n ? SHADES[i] : '#E5E8EC') + '"></i>';
}).join('');
var open = {};
[].forEach.call(document.querySelectorAll('#list details'), function (d, i) { if (d.open) open[i] = 1; });
$('#list').innerHTML = parts.map(function (p, i) {
var on = i < n;
return '<details' + (on ? '' : ' class="off"') + (open[i] ? ' open' : '') + '><summary><span class="dot" style="background:' + (on ? SHADES[i] : '#E5E8EC') + '"></span>' +
'<span class="nm">' + STAGES[i] + '</span><span class="rg">' + (on ? rng(p) : '未计入') + '</span>' +
'<svg class="ic ar"><use href="#i-down" xlink:href="#i-down"/></svg></summary><div class="ds">' + detail(i) + '</div></details>';
}).join('');
var big = 0;
for (var i = 1; i < n; i++) if (mids[i] > mids[big]) big = i;
$('#bigT').innerHTML = '最花钱的是<em>' + STAGES[big] + '</em>';
var why = [
st.hosp ? '特需和私立的产检套餐偏贵' : '主要是产检和筛查',
st.hosp ? '贵在病房和服务升级' : '主要是接生、手术和住院',
['主要是月子餐和产妇用品', '主要是月嫂工资', '主要是月子中心套餐'][st.yz],
st.feed ? '奶粉和纸尿裤每月都要买' : '主要是用品、纸尿裤和看病',
['主要是日常吃用和老人补贴', '主要是育儿嫂工资', '主要是托育园月费'][st.care]
][Math.min(big, 4)];
$('#bigD').textContent = '约 ' + rng(parts[big]) + ',' + why + '。';
$('#save').textContent = saveTip(big);
}
$('#tabs').addEventListener('click', function (e) {
var b = e.target.closest('button'); if (!b) return;
stage = +b.dataset.s; save(); renderRes();
});
$('#chips').addEventListener('click', function (e) {
var b = e.target.closest('button'); if (!b) return;
qi = +b.dataset.q; editing = true; renderQ();
});
function save() {
try { var o = {}; QS.forEach(function (q) { o[q.k] = st[q.k]; }); o.stage = stage; localStorage.setItem(KEY, JSON.stringify(o)); } catch (e) {}
}
function load() {
try {
var o = JSON.parse(localStorage.getItem(KEY) || 'null'); if (!o) return false;
var ok = QS.every(function (q) { return o[q.k] >= 0 && o[q.k] < q.o.length; });
if (!ok) return false;
QS.forEach(function (q) { st[q.k] = o[q.k]; });
if (o.stage >= 0 && o.stage < 4) stage = o.stage;
st._done = true; return true;
} catch (e) { return false; }
}
if (load()) { renderRes(); show('sRes'); } else show('sStart');
/* 返回:从首页点进来就 back;直接打开(分享 / 刷新)就回同目录的首页,身份原样带回 */
$('#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('on', sc.scrollTop > 4); }, { passive: true });
/* 禁止下拉回弹:固定外壳 + 容器滚动 + 到顶/到底时拦 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>