其他妈妈也在搜:孕4-40周每周18条问答,首页露6条+全部问题页;孕期数据去花哨背景、文字实色 v26103108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-10-31 12:45:07 +00:00
parent e3c92d1f8c
commit b70236a354
39 changed files with 219 additions and 38 deletions

116
js/app.js
View File

@@ -3,7 +3,7 @@
(function () {
'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26103107';
var VER = '26103108';
const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -5057,30 +5057,52 @@
sec.classList.remove('hide');
revealTipsGrid();
}
/* 2026-10-31 首页「其他妈妈也在搜」:6 条问题,全部有落点(专题页 / 小知识详情页),按孕周每周换 */
/* 2026-10-31 首页「其他妈妈也在搜」:问题库 assets/data/qa/<周>.json(孕 4–40 周,每周 18 条问答),
首页只露 6 条(孕 12 周起第一条是妊娠纹专题),点任意一条 / 「查看全部」进 #detailQA 看答案和其余问题。
问题库没加载到时退回 6 条本周小知识入口(落点 #detailTips),首页不空。 */
let QA = null, qaLoading = null;
/* 按周拆成小文件 assets/data/qa/<周>.json(每份约 6KB),只拉当前孕周;孕周变了再拉新的一份 */
function loadQA() {
const w = qaWeek();
if (QA && QA[w]) return Promise.resolve(QA);
if (!qaLoading || qaLoading.w !== w) {
qaLoading = fetch('assets/data/qa/' + w + '.json?v=' + VER).then(r => (r.ok ? r.json() : [])).catch(() => [])
.then(a => { QA = QA || {}; QA[w] = Array.isArray(a) ? a : []; return QA; });
qaLoading.w = w;
}
return qaLoading;
}
const QA_CATS = ['产检', '身体', '饮食', '补剂', '宝宝', '生活', '心情', '准备'];
let qaCat = '全部';
function qaWeek() { return Math.max(4, Math.min(40, state.week || 0)); }
function renderSearch(wk, today, size) {
const W = state.week, L = $('#msList');
if (!L) return;
if (!QA || !QA[qaWeek()]) { loadQA().then(q => { if (q[qaWeek()] && q[qaWeek()].length) renderSearch(wk, today, size); }); }
$('#msWk').textContent = '孕 ' + W + ' 周';
$('#msCnt').textContent = '孕 ' + W + ' 周的妈妈都在看';
const pool = AVA_TOP.concat(AVA_FEED), s0 = (W * 7) % pool.length;
$('#msAvs').innerHTML = [0, 1, 2, 3, 4, 5, 6, 7].map(i => avaImg(pool[(s0 + i * 3) % pool.length])).join('');
const q = t => /[??吗呢]$/.test(t) ? t : t + (/怎么办|什么|多少|怎么|几/.test(t) ? '?' : '');
const bank = (QA && QA[qaWeek()]) || [];
const items = [];
if (W >= 12) items.push({ q: '妊娠纹怎么防?现在该抹什么', tag: '专题', cls: 'hot', href: 'topic/wen/' + location.search + location.hash });
const d0 = wk.days[today];
if (d0 && d0.t) items.push({ q: q(d0.t), tag: '今日', cls: 'new' });
items.push({ q: '孕' + W + '周,宝宝长多大了?', tag: '热', cls: 'hot', pt: 'baby' });
items.push({ q: '这周身体会有哪些变化?', pt: 'mom' });
items.push({ q: '孕' + W + '周吃什么对宝宝好?', pt: 'eat' });
items.push({ q: '这周产检和生活要留心什么?', pt: 'care' });
const d1 = today > 0 && wk.days[today - 1];
if (items.length < 6 && d1 && d1.t) items.push({ q: q(d1.t), tag: '昨天' });
if (bank.length) {
bank.slice(0, 6 - items.length).forEach((x, i) => items.push({ q: x.q, tag: x.hot ? '热' : '', cls: 'hot', qa: i }));
} else {
const q = t => /[??吗呢]$/.test(t) ? t : t + (/怎么办|什么|多少|怎么|几/.test(t) ? '?' : '');
const d0 = wk.days[today];
if (d0 && d0.t) items.push({ q: q(d0.t), tag: '今日', cls: 'new', pt: '' });
items.push({ q: '孕' + W + '周,宝宝长多大了?', tag: '热', cls: 'hot', pt: 'baby' });
items.push({ q: '这周身体会有哪些变化?', pt: 'mom' });
items.push({ q: '孕' + W + '周吃什么对宝宝好?', pt: 'eat' });
items.push({ q: '这周产检和生活要留心什么?', pt: 'care' });
}
L.textContent = '';
items.slice(0, 6).forEach((it, i) => {
const el = document.createElement(it.href ? 'a' : 'button');
el.className = 'ms-it ripple';
if (it.href) el.href = it.href; else { el.type = 'button'; el.addEventListener('click', () => openTips(it.pt)); }
if (it.href) el.href = it.href;
else { el.type = 'button'; el.addEventListener('click', () => (it.qa != null ? openQA(it.qa) : openTips(it.pt))); }
const no = document.createElement('i'); no.className = 'ms-no'; no.textContent = i + 1;
const t = document.createElement('span'); t.className = 'ms-q'; t.textContent = it.q;
el.appendChild(no); el.appendChild(t);
@@ -5088,7 +5110,75 @@
const go = document.createElement('i'); go.className = 'ms-go'; go.textContent = '›'; el.appendChild(go);
L.appendChild(el);
});
const all = $('#msAll');
if (all) {
const n = bank.length + (W >= 12 ? 1 : 0);
all.classList.toggle('hide', !bank.length);
all.textContent = '查看全部 ' + n + ' 个问题 ›';
}
}
/* 全部问题页:focus = 从首页点的那条在本周问题库里的下标(展开 + 滚到它);不传 = 从「查看全部」进来 */
function openQA(focus) {
const W = state.week, bank = (QA && QA[qaWeek()]) || [];
if (!bank.length) { openTips(); return; }
$('#qaTitle').textContent = '孕 ' + W + ' 周 · 其他妈妈也在搜';
$('#qaHeroT').textContent = '孕 ' + W + ' 周,妈妈们最常问的 ' + bank.length + ' 个问题';
$('#qaHeroD').textContent = '点开问题看答案,每周按孕周自动更新';
const tp = $('#qaTopic');
tp.classList.toggle('hide', !(W >= 12));
tp.setAttribute('href', 'topic/wen/' + location.search + location.hash);
const cats = QA_CATS.filter(c => bank.some(x => x.tag === c));
const cb = $('#qaCats');
cb.textContent = '';
['全部'].concat(cats).forEach(c => {
const b = document.createElement('button');
b.type = 'button'; b.className = 'qa-cat'; b.dataset.cat = c;
b.textContent = c;
const sm = document.createElement('small'); sm.textContent = c === '全部' ? bank.length : bank.filter(x => x.tag === c).length;
b.appendChild(sm);
b.addEventListener('click', () => qaFilter(c));
cb.appendChild(b);
});
const L = $('#qaList');
L.textContent = '';
bank.forEach((x, i) => {
const it = document.createElement('div');
it.className = 'qa-it' + (i < 3 ? ' top' : '');
it.dataset.cat = x.tag || '';
const h = document.createElement('button'); h.type = 'button'; h.className = 'qa-q';
const no = document.createElement('i'); no.className = 'qa-no'; no.textContent = i + 1;
const t = document.createElement('span'); t.className = 'qa-tx'; t.textContent = x.q;
const g = document.createElement('span'); g.className = 'qa-tag' + (x.hot ? ' hot' : ''); g.textContent = x.hot ? '热' : (x.tag || '');
const ch = document.createElement('i'); ch.className = 'qa-ch'; ch.textContent = '›';
h.appendChild(no); h.appendChild(t); if (g.textContent) h.appendChild(g); h.appendChild(ch);
const a = document.createElement('div'); a.className = 'qa-a'; a.textContent = x.a || '';
h.addEventListener('click', () => { it.classList.toggle('open'); haptic(); });
it.appendChild(h); it.appendChild(a);
L.appendChild(it);
});
qaFilter('全部');
openPanel('detailQA');
const body = $('#detailQA .detail-body');
body.scrollTop = 0;
if (focus != null && L.children[focus]) {
const c = L.children[focus];
c.classList.add('open');
setTimeout(() => {
body.scrollTo({ top: Math.max(0, c.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop - 12), behavior: 'smooth' });
c.classList.remove('hit'); void c.offsetWidth; c.classList.add('hit');
}, 400); // 等详情页滑入再滚
}
}
function qaFilter(c) {
qaCat = c;
$$('#qaCats .qa-cat').forEach(b => b.classList.toggle('on', b.dataset.cat === c));
$$('#qaList .qa-it').forEach(it => it.classList.toggle('hide', c !== '全部' && it.dataset.cat !== c));
const tp = $('#qaTopic'); if (tp) tp.style.display = c === '全部' ? '' : 'none';
}
(function () {
const all = $('#msAll'); if (all) all.addEventListener('click', () => openQA());
const tp = $('#qaTips'); if (tp) tp.addEventListener('click', () => openTips());
})();
/* 首页四个入口 → 详情页,滚到对应那张卡并闪一下 */
function openTips(key) {
openPanel('detailTips');
@@ -5240,7 +5330,7 @@
if (!r) { vtSet('glu', ''); return; }
const t = (tm.targets && tm.targets[r.slot]) || VT_TGT[r.slot] || [3.3, 7.8];
const st = r.value > t[1] ? ['偏高', 'hi'] : r.value < t[0] ? ['偏低', 'lo'] : ['达标', 'ok'];
vtSet('glu', (+r.value).toFixed(1), st[0], st[1], vtDay(r.ts) + (VT_SLOT[r.slot] ? ' · ' + VT_SLOT[r.slot] : ''));
vtSet('glu', (+r.value).toFixed(1), st[0], st[1], vtDay(r.ts) + (VT_SLOT[r.slot] ? ' ' + VT_SLOT[r.slot] : ''));
});
}
$$('.vt-it[data-vt]').forEach(b => b.addEventListener('click', () => {