v26110289 新增预产期计算器替换孕期增重;百宝箱滚动头像现挑、同时不重复且近16次不重复
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,7 +68,7 @@
|
||||
function getJSON(u) { return fetch(u, { cache: 'no-cache' }).then(function (r) { if (!r.ok) throw r.status; return r.json(); }); }
|
||||
|
||||
function related(box) {
|
||||
getJSON('../_shared/idx.json?v=26110288').then(function (idx) {
|
||||
getJSON('../_shared/idx.json?v=26110289').then(function (idx) {
|
||||
var me = null; idx.forEach(function (x) { if (x[0] === SLUG) me = x; });
|
||||
var tag = me ? me[2] : '', h = 0; for (var i = 0; i < SLUG.length; i++) h = (h * 31 + SLUG.charCodeAt(i)) >>> 0;
|
||||
var rest = idx.filter(function (x) { return x[0] !== SLUG; });
|
||||
@@ -175,7 +175,7 @@
|
||||
}
|
||||
fetch(API + '/comments?kind=topic&target=' + encodeURIComponent(SLUG) + (OID ? '&openid=' + encodeURIComponent(OID) : ''))
|
||||
.then(function (r) { return r.json(); }).then(function (j) { if (j && j.code === 200) { RC = j.result; paint(); } }).catch(function () {});
|
||||
getJSON('../_shared/cm/' + SLUG + '.json?v=26110288').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); });
|
||||
getJSON('../_shared/cm/' + SLUG + '.json?v=26110289').then(function (d) { L = d.c || []; paint(); }).catch(function () { paint(); });
|
||||
}
|
||||
|
||||
function extras(el) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>孕期计算器</title>
|
||||
<!-- 11-03 首页「测一测 · 科普 · 计算器」模块(js/kit.js)里「孕期计算器」入口的列表页。
|
||||
用户:「这几个模块不是进去测一个,而是进去之后是列表页」。测试 / 科普已有列表(广场测一测、全部问题),计算器原来没有,这页补上。
|
||||
条目:专题页里带计算器的(生娃花费 topic/huafei、产假天数 topic/zhichang)+ 会算数的孕期工具(胎儿估重、孕期体重管理)。
|
||||
条目:专题页里带计算器的(生娃花费 topic/huafei、产假天数 topic/zhichang)+ 会算数的孕期工具(胎儿估重)+ 预产期计算器 topic/yuchanqi-js(11-04 替换孕期体重管理)。
|
||||
跳转一律同源相对路径,带回 search + hash(openid);胎儿估重孕 15 周前提示(同首页 STAGE_GATE)。自成一页,不引 app.js。 -->
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
|
||||
@@ -73,13 +73,14 @@ button{font:inherit;border:0;background:none;color:inherit;cursor:pointer}
|
||||
try { var g = JSON.parse(localStorage.getItem('mmbox.gcwk.v1') || 'null'); week = g && !g.pp ? +g.w || 0 : 0; } catch (e) {}
|
||||
var SV = {
|
||||
money: '<svg viewBox="0 0 24 24"><rect x="5" y="3" width="14" height="18" rx="3"/><path d="M8.5 7h7M8.5 11h1M12 11h1M15.5 11h0M8.5 14.5h1M12 14.5h1M8.5 18h1M12 18h1M15.5 14.5v3.5"/></svg>',
|
||||
cal: '<svg viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M8 3v4M16 3v4M3.5 10h17M8 14h3M8 17h6"/></svg>'
|
||||
cal: '<svg viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M8 3v4M16 3v4M3.5 10h17M8 14h3M8 17h6"/></svg>',
|
||||
due: '<svg viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M8 3v4M16 3v4M3.5 10h17"/><path d="M12 18.2s-3-1.8-3-3.7c0-1 .8-1.7 1.6-1.7.6 0 1.1.3 1.4.8.3-.5.8-.8 1.4-.8.8 0 1.6.7 1.6 1.7 0 1.9-3 3.7-3 3.7z"/></svg>'
|
||||
};
|
||||
var L = [
|
||||
{ n: '生娃花费计算器', tag: '最多人用', d: '产检、分娩、月子、宝宝第一年,一共要花多少钱', u: '../huafei/', heat: .118, c: '#F07A2E', bg: '#FFF0E4', ic: SV.money },
|
||||
{ n: '产假天数计算器', d: '能休几天、哪天开始休、哪天回去上班', u: '../zhichang/', cm: 1, heat: .062, c: '#5B6CFF', bg: '#EEF0FF', ic: SV.cal },
|
||||
{ n: '胎儿体重估算', d: '填 B 超上的几个数,估宝宝现在多重', u: '/taier-guzhong/', heat: .071, c: '#2E9B78', bg: '#E6F6F0', img: '/upload/picture/715333a69fb67d8812ab093f342fa00f.png', gate: 15 },
|
||||
{ n: '孕期增重计算', d: '按孕前身高体重,算你整个孕期该长多少斤', u: '/yunqi-tizhong/', heat: .083, c: '#E25C7A', bg: '#FFECEF', img: '/upload/picture/a6d7e61edee2ff0395cf00587a7c4036.svg' }
|
||||
{ n: '预产期计算器', d: '填末次月经或移植日,算预产期、现在几周、产检哪天去', u: '../yuchanqi-js/', heat: .083, c: '#E25C7A', bg: '#FFECEF', ic: SV.due } /* 11-04 换掉「孕期增重」(那是记录工具) */
|
||||
];
|
||||
$('#list').innerHTML = L.map(function (x, i) {
|
||||
var lk = x.gate && week && week < x.gate;
|
||||
|
||||
191
topic/yuchanqi-js/index.html
Normal file
191
topic/yuchanqi-js/index.html
Normal file
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>预产期计算器</title>
|
||||
<!-- 孕期计算器 · 预产期(2026-11-04 用户:「孕期增重那个是记录工具、不是算出来的,换掉,给我一个能算的」→ 新做本页替换百宝箱 / topic/jisuan 里的「孕期增重」)。
|
||||
算法(常规产科算法):
|
||||
末次月经:预产期 = 末次月经第一天 + 280 天 +(周期 − 28)天;
|
||||
试管移植:第 3 天胚胎 = 移植日 + 263 天,第 5 天囊胚 = 移植日 + 261 天;
|
||||
孕周 = 今天 −(预产期 − 280 天),各项产检窗口按孕周换算成日期。
|
||||
自成一页:不引 app.js;返回走 back,直接打开回 ../../(带回 search + hash)。上次填的值记在 localStorage「mmbox.edd.calc」,再进来直接出结果。 -->
|
||||
<style>
|
||||
:root{--c:#E25C7A;--cbg:#FFEEF2;--h:#1F2329;--t:#4E5969;--m:#86909C;--line:#F1E9EB}
|
||||
*{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.7 -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))}
|
||||
button,input{font:inherit;border:0;background:none;color:inherit}
|
||||
button{cursor:pointer}
|
||||
.num{font-variant-numeric:tabular-nums}
|
||||
.ic{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
|
||||
.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);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 .t{font-size:15px;font-weight:700;color:var(--h)}
|
||||
.hd{margin-top:-48px;padding:60px 20px 6px;background:linear-gradient(180deg,var(--cbg),#fff)}
|
||||
.hd p{font-size:12.5px;font-weight:700;color:var(--c);letter-spacing:1px}
|
||||
.hd h1{margin-top:4px;font-size:25px;font-weight:900;line-height:1.3;color:var(--h)}
|
||||
.hd span{display:block;margin-top:4px;font-size:14px;color:var(--m)}
|
||||
.calc{margin:12px 16px 0;padding:16px;border-radius:20px;background:#fff;box-shadow:0 10px 30px -18px rgba(226,92,122,.55);border:1px solid #F7E3E8}
|
||||
.res{padding:16px;border-radius:16px;background:linear-gradient(135deg,#FF8FA8,#E25C7A);color:#fff}
|
||||
.res .empty{padding:14px 0;text-align:center;font-size:14px;opacity:.9}
|
||||
.res small{font-size:12.5px;opacity:.9}
|
||||
.res .due{display:block;margin-top:2px;font-size:28px;font-weight:900;line-height:1.25}
|
||||
.res .wk{display:flex;gap:10px;margin-top:12px}
|
||||
.res .wk div{flex:1;padding:8px 10px;border-radius:12px;background:rgba(255,255,255,.18)}
|
||||
.res .wk b{display:block;font-size:17px;font-weight:900}
|
||||
.res .pg{position:relative;height:6px;margin-top:12px;border-radius:99px;background:rgba(255,255,255,.3);overflow:hidden}
|
||||
.res .pg i{position:absolute;left:0;top:0;bottom:0;border-radius:99px;background:#fff}
|
||||
.tabs{display:flex;gap:6px;margin-top:16px;padding:4px;border-radius:12px;background:#F7F1F3}
|
||||
.tabs button{flex:1;height:34px;border-radius:9px;font-size:14px;font-weight:700;color:var(--m)}
|
||||
.tabs button.on{background:#fff;color:var(--c);box-shadow:0 2px 6px rgba(226,92,122,.15)}
|
||||
.fld{margin-top:14px}
|
||||
.lb{display:block;font-size:13.5px;font-weight:700;color:var(--h)}
|
||||
.lb small{margin-left:6px;font-weight:400;color:var(--m)}
|
||||
.in{display:block;width:100%;height:46px;margin-top:6px;padding:0 14px;border-radius:12px;background:#F8F5F6;font-size:16px;color:var(--h)}
|
||||
.stp{display:flex;align-items:center;gap:10px;margin-top:6px}
|
||||
.stp button{width:42px;height:42px;border-radius:12px;background:#F8F5F6;font-size:20px;font-weight:700;color:var(--c)}
|
||||
.stp b{flex:1;text-align:center;font-size:18px;color:var(--h)}
|
||||
.seg{display:flex;gap:8px;margin-top:6px}
|
||||
.seg button{flex:1;height:42px;border-radius:12px;background:#F8F5F6;font-size:14px;font-weight:700;color:var(--t)}
|
||||
.seg button.on{background:var(--cbg);color:var(--c);box-shadow:inset 0 0 0 1.5px var(--c)}
|
||||
.hide{display:none!important}
|
||||
.sec{margin:26px 20px 0}
|
||||
.sec h2{font-size:18px;font-weight:900;color:var(--h)}
|
||||
.sec .lead{margin-top:2px;font-size:13px;color:var(--m)}
|
||||
.tl{list-style:none;margin-top:12px}
|
||||
.tl li{position:relative;display:flex;gap:12px;padding:0 0 16px 0}
|
||||
.tl li::before{content:"";position:absolute;left:7px;top:18px;bottom:0;width:2px;background:#F3E3E7}
|
||||
.tl li:last-child::before{display:none}
|
||||
.tl .d{flex:none;width:16px;height:16px;margin-top:3px;border-radius:50%;border:3px solid #F6CBD6;background:#fff}
|
||||
.tl li.done .d{border-color:var(--c);background:var(--c)}
|
||||
.tl li.now .d{border-color:var(--c);box-shadow:0 0 0 4px rgba(226,92,122,.18)}
|
||||
.tl .m{flex:1;min-width:0}
|
||||
.tl .m b{font-size:15px;color:var(--h)}
|
||||
.tl .m b em{margin-left:6px;padding:0 6px;border-radius:99px;background:var(--cbg);color:var(--c);font-size:11px;font-style:normal;font-weight:800}
|
||||
.tl .m span{display:block;font-size:13px;color:var(--m)}
|
||||
.tl .m span i{font-style:normal;font-weight:700;color:var(--t)}
|
||||
.tip{margin:18px 20px 0;padding:12px 14px;border-radius:14px;background:#FFF8F4;font-size:13px;line-height:1.7;color:var(--t)}
|
||||
.tip b{color:var(--h)}
|
||||
.foot{margin:14px 20px 0;font-size:12px;color:var(--m);text-align:center;line-height:1.6}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg style="position:absolute;width:0;height:0" aria-hidden="true"><symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol></svg>
|
||||
<div id="scroll">
|
||||
<header class="bar" id="bar">
|
||||
<button class="back" id="back" aria-label="返回"><svg class="ic"><use href="#i-back"/></svg></button>
|
||||
<span class="t">孕期计算器</span>
|
||||
</header>
|
||||
<section class="hd"><p>孕期计算器</p><h1>预产期计算器</h1><span>填末次月经或移植日,算出预产期、现在几周、每项产检哪天去</span></section>
|
||||
|
||||
<section class="calc">
|
||||
<div class="res" id="res"><div class="empty">填好下面的日期,马上出结果</div></div>
|
||||
<div class="tabs" id="tabs"><button type="button" data-m="lmp" class="on">按末次月经</button><button type="button" data-m="ivf">按试管移植</button></div>
|
||||
<div id="fLmp">
|
||||
<div class="fld"><label class="lb" for="cLmp">末次月经第一天</label><input class="in num" type="date" id="cLmp"></div>
|
||||
<div class="fld"><span class="lb">月经周期<small>两次月经第一天间隔几天</small></span>
|
||||
<div class="stp"><button type="button" id="cyM" aria-label="减一天">−</button><b class="num" id="cyV">28 天</b><button type="button" id="cyP" aria-label="加一天">+</button></div></div>
|
||||
</div>
|
||||
<div id="fIvf" class="hide">
|
||||
<div class="fld"><label class="lb" for="cTr">胚胎移植日</label><input class="in num" type="date" id="cTr"></div>
|
||||
<div class="fld"><span class="lb">移植的胚胎</span>
|
||||
<div class="seg" id="cEmb"><button type="button" data-v="3">第 3 天胚胎</button><button type="button" data-v="5" class="on">第 5 天囊胚</button></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sec hide" id="plan">
|
||||
<h2>我的产检时间表</h2>
|
||||
<p class="lead">按预产期倒推的建议时间,具体听你的产检医生安排</p>
|
||||
<ol class="tl" id="tl"></ol>
|
||||
</section>
|
||||
|
||||
<div class="tip"><b>以早孕 B 超为准:</b>月经不规律、记不清末次月经,或 B 超算出的孕周和月经差得多,医生会按孕早期 B 超(头臀长)改预产期。预产期是个参考,37~41+6 周生都算足月。</div>
|
||||
<p class="foot">计算结果仅供参考,不能代替医生诊断。</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
'use strict';
|
||||
var $ = function (s) { return document.querySelector(s); };
|
||||
var sc = $('#scroll'), KEY = 'mmbox.edd.calc', DAY = 864e5;
|
||||
$('#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 > 8); }, { passive: true });
|
||||
|
||||
/* 日期一律按北京时间的「日」算,避免时区差一天 */
|
||||
function today() { var n = new Date(Date.now() + 288e5); return Date.UTC(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate()); }
|
||||
function parse(v) { var m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v || ''); return m ? Date.UTC(+m[1], m[2] - 1, +m[3]) : NaN; }
|
||||
function fmt(t) { var d = new Date(t); return d.getUTCFullYear() + '-' + ('0' + (d.getUTCMonth() + 1)).slice(-2) + '-' + ('0' + d.getUTCDate()).slice(-2); }
|
||||
function cn(t, y) { var d = new Date(t); return (y ? d.getUTCFullYear() + ' 年 ' : '') + (d.getUTCMonth() + 1) + ' 月 ' + d.getUTCDate() + ' 日'; }
|
||||
var WD = '日一二三四五六';
|
||||
|
||||
var st = { m: 'lmp', lmp: '', cy: 28, tr: '', emb: 5 };
|
||||
try { var sv = JSON.parse(localStorage.getItem(KEY) || 'null'); if (sv) Object.keys(st).forEach(function (k) { if (sv[k] != null) st[k] = sv[k]; }); } catch (e) {}
|
||||
var T = today();
|
||||
$('#cLmp').max = fmt(T); $('#cLmp').min = fmt(T - 300 * DAY);
|
||||
$('#cTr').max = fmt(T); $('#cTr').min = fmt(T - 280 * DAY);
|
||||
|
||||
function ui() {
|
||||
[].forEach.call($('#tabs').children, function (b) { b.classList.toggle('on', b.dataset.m === st.m); });
|
||||
$('#fLmp').classList.toggle('hide', st.m !== 'lmp'); $('#fIvf').classList.toggle('hide', st.m !== 'ivf');
|
||||
$('#cLmp').value = st.lmp; $('#cTr').value = st.tr; $('#cyV').textContent = st.cy + ' 天';
|
||||
[].forEach.call($('#cEmb').children, function (b) { b.classList.toggle('on', +b.dataset.v === +st.emb); });
|
||||
}
|
||||
function due() {
|
||||
if (st.m === 'lmp') { var l = parse(st.lmp); return isNaN(l) ? NaN : l + (280 + st.cy - 28) * DAY; }
|
||||
var t = parse(st.tr); return isNaN(t) ? NaN : t + (+st.emb === 3 ? 263 : 261) * DAY;
|
||||
}
|
||||
/* 产检窗口(孕周,含首尾):常规产检时间,具体以医生安排为准 */
|
||||
var PLAN = [
|
||||
['建档 + 第一次产检', 6, 12, '查血、B 超确认胎心,拿到孕妇手册'],
|
||||
['NT 检查', 11, 13.86, '11~13+6 周,错过就不能补'],
|
||||
['唐筛 / 无创', 15, 20.86, '早唐可和 NT 一起做,中唐 15~20+6 周'],
|
||||
['大排畸', 20, 24, '系统超声,看宝宝结构'],
|
||||
['糖耐', 24, 28, '空腹去,喝糖水抽 3 次血'],
|
||||
['胎心监护', 34, 40, '一般 34~36 周起,每周一次'],
|
||||
['足月', 37, 37, '这之后生都算足月,待产包备好'],
|
||||
['预产期', 40, 40, '']
|
||||
];
|
||||
function paint() {
|
||||
var d = due(), R = $('#res');
|
||||
try { localStorage.setItem(KEY, JSON.stringify(st)); } catch (e) {}
|
||||
if (isNaN(d)) { R.innerHTML = '<div class="empty">填好下面的日期,马上出结果</div>'; $('#plan').classList.add('hide'); return; }
|
||||
var s0 = d - 280 * DAY, g = Math.floor((T - s0) / DAY), w = Math.floor(g / 7), dd = g % 7, left = Math.round((d - T) / DAY);
|
||||
var wk = g < 0 ? '还没开始' : w + ' 周' + (dd ? ' + ' + dd + ' 天' : ''), stage = w < 14 ? '孕早期' : w < 28 ? '孕中期' : '孕晚期';
|
||||
R.innerHTML = '<small>你的预产期</small><b class="due num">' + cn(d, 1) + ' 周' + WD[new Date(d).getUTCDay()] + '</b>' +
|
||||
'<div class="wk"><div><small>今天</small><b class="num">' + (g >= 0 && g <= 300 ? '孕 ' + wk : '—') + '</b></div><div><small>' + (left >= 0 ? '离见面还有' : '已过预产期') + '</small><b class="num">' + Math.abs(left) + ' 天</b></div></div>' +
|
||||
'<div class="pg"><i style="width:' + Math.max(0, Math.min(100, g / 280 * 100)).toFixed(1) + '%"></i></div>' +
|
||||
'<small style="display:block;margin-top:6px">' + (g >= 0 && left >= 0 ? stage + ' · 已走过 ' + Math.round(g / 280 * 100) + '%' : '预产期仅供参考,以医生判断为准') + '</small>';
|
||||
$('#tl').innerHTML = PLAN.map(function (p) {
|
||||
var a = s0 + Math.round(p[1] * 7) * DAY, b = s0 + Math.round(p[2] * 7) * DAY, done = T > b, now = T >= a && T <= b;
|
||||
return '<li class="' + (done ? 'done' : now ? 'now' : '') + '"><i class="d"></i><div class="m"><b>' + p[0] + (now ? '<em>就是现在</em>' : '') + '</b>' +
|
||||
'<span><i class="num">' + (a === b ? cn(a) : cn(a) + ' ~ ' + cn(b)) + '</i>' + (p[3] ? ' · ' + p[3] : '') + '</span></div></li>';
|
||||
}).join('');
|
||||
$('#plan').classList.remove('hide');
|
||||
}
|
||||
$('#tabs').addEventListener('click', function (e) { var b = e.target.closest('button'); if (!b) return; st.m = b.dataset.m; ui(); paint(); });
|
||||
$('#cLmp').addEventListener('change', function () { st.lmp = this.value; paint(); });
|
||||
$('#cTr').addEventListener('change', function () { st.tr = this.value; paint(); });
|
||||
$('#cyM').addEventListener('click', function () { st.cy = Math.max(21, st.cy - 1); ui(); paint(); });
|
||||
$('#cyP').addEventListener('click', function () { st.cy = Math.min(45, st.cy + 1); ui(); paint(); });
|
||||
$('#cEmb').addEventListener('click', function (e) { var b = e.target.closest('button'); if (!b) return; st.emb = +b.dataset.v; ui(); paint(); });
|
||||
ui(); paint();
|
||||
|
||||
/* 禁止下拉回弹:固定外壳 + 容器滚动 + 到顶/到底时拦 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>
|
||||
<script src="../_shared/brand.js?v=26110203"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user