孕妈广场:首页加逛广场入口、帖子返回落广场首页;参差瀑布流+图上压字;分类·话题胶囊层级;话题名与179篇帖子口语化重写

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-02 09:43:22 +00:00
parent 5fc072fb50
commit f2b27f9b6a
8 changed files with 744 additions and 674 deletions

View File

@@ -112,6 +112,26 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.th .join .ic{width:14px;height:14px}
.th .sw{height:34px;padding:0 14px;border-radius:99px;background:rgba(255,255,255,.8);color:var(--ht);font-size:13px;font-weight:800}
/* ---------- 层级:分类 · 话题胶囊(11-02) ---------- */
.lvw{margin:16px 0 0}
.lvw .lv{display:flex;align-items:baseline;gap:8px;padding:0 14px}
.lvw .lv h2{margin:0;font-size:17px;font-weight:900;letter-spacing:.3px;color:var(--kt)}
.lvw .lv small{font-size:12px;font-weight:600;color:var(--muted);white-space:nowrap}
.lvw .lv .ba{margin-left:auto;font-size:12.5px;font-weight:800;color:var(--kt)}
.tcs{display:flex;gap:7px;padding:9px 12px 2px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none}
.tcs::-webkit-scrollbar{display:none}
.tcs::after{content:"";flex:none;width:4px}
.tcs button{flex:none;height:30px;padding:0 11px;border-radius:99px;background:#fff;border:1px solid #EFE1DB;font-size:12.5px;font-weight:700;color:#5E4E4A;white-space:nowrap;display:inline-flex;align-items:center;gap:5px}
.tcs button i{font-style:normal;font-size:11px;font-weight:800;color:#B59A93;font-variant-numeric:tabular-nums}
.tcs button.on{background:var(--kf);border-color:var(--kf);color:#fff;box-shadow:0 5px 12px -6px var(--kf)}
.tcs button.on i{color:rgba(255,255,255,.85)}
.th .bc{position:relative;display:flex;align-items:center;gap:6px}
.th .bc button{display:inline-flex}
.th .bc span:last-child{font-size:12px;font-weight:700;color:var(--ht)}
.mo{display:block;width:calc(100% - 24px);margin:14px 12px 0;padding:13px 14px;border-radius:16px;text-align:center;background:linear-gradient(150deg,var(--kl),var(--kl2))}
.mo small{display:block;font-size:11.5px;font-weight:600;color:#9A817C}
.mo b{display:block;margin-top:3px;font-size:14.5px;font-weight:900;color:var(--kt)}
/* ---------- 瀑布流 ---------- */
.wf{display:flex;align-items:flex-start;gap:8px;padding:10px 12px 0}
.wf .col{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
@@ -151,6 +171,16 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
.cv.ph .kb{position:absolute;left:.95em;top:.95em;z-index:1;box-shadow:0 2px 6px rgba(0,0,0,.12)}
.cv .wm{position:absolute;right:-.1em;bottom:-.25em;font-size:5.6em;font-weight:900;line-height:1;color:#fff;opacity:.55;font-family:"STKaiti","KaiTi","Kaiti SC",serif;pointer-events:none;z-index:0}
/* 图上压字(11-02 用户:文字放到图片上穿插来,小红书式):ov 底部渐变大字 / tg 贴纸字 */
.nc .ovt{position:absolute;left:0;right:0;bottom:0;padding:34px 10px 10px;background:linear-gradient(transparent,rgba(30,18,14,.62));color:#fff;pointer-events:none}
.nc .ovt b{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;font-size:17px;font-weight:900;line-height:1.3;letter-spacing:.5px;text-shadow:0 1px 4px rgba(0,0,0,.25)}
.nc .ovt small{display:block;margin-top:4px;font-size:11px;font-weight:700;opacity:.9;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nc .tgt{position:absolute;left:9px;right:9px;bottom:12px;pointer-events:none}
.nc .tgt b{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;font-size:15px;font-weight:900;line-height:1.55;color:#2A1E1E}
.nc .tgt span{background:#FFF2A6;padding:1px 5px;-webkit-box-decoration-break:clone;box-decoration-break:clone;border-radius:3px}
.nc:nth-child(odd) .tgt span{background:#fff}
.nc .ovt~*,.nc .tgt~*{display:none}
/* ---------- 详情层 ---------- */
#dt{position:fixed;inset:0;z-index:40;background:#fff;transform:translateX(100%);transition:transform .32s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column}
#dt.show{transform:none}
@@ -367,6 +397,7 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<div id="head"></div>
<div class="sh" id="fh"></div>
<div class="wf" id="wf"><div class="col"></div><div class="col"></div></div>
<div id="more"></div>
<div class="end"><b>— 到底啦 —</b><small>内容为示例占位,正式版将替换为妈妈们的真实分享</small></div>
</div>
@@ -402,9 +433,9 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
<div id="sheet" role="dialog" aria-modal="true"><i class="sg"></i><div class="sbd" id="sbd"></div></div>
<div class="toast" id="toast"></div>
<script src="topics.js?v=26110204"></script>
<script src="data.js?v=26110204"></script>
<script src="feed.js?v=26110204"></script>
<script src="topics.js?v=26110205"></script>
<script src="data.js?v=26110205"></script>
<script src="feed.js?v=26110205"></script>
<script>
(function () {
'use strict';
@@ -439,13 +470,15 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
/* ---------- 笔记:data.js 的原始内容 + 确定性补字段(id / 封面样式 / 比例 / 评论) ---------- */
var NOTES = [], NBY = {}; /* 真实投稿到达后会往前插(loadApproved),所以 NOTES / MIXED 用 var 可重赋值 */
var RATIO = [1.12, 0.94, 1.04, 0.88, 1.18, 0.98, 0.9];
/* 11-02 用户:「要参差不齐的小红书瀑布流,现在都横向对齐」→ 照片封面高度按 id 哈希在 0.95~1.45 之间取,不再统一 1.3 */
var PR = [1.33, 1.05, 1.25, 1.45, 1.15, 0.95, 1.38, 1.2];
T.forEach(function (t, ti) {
var d = D[t.id]; if (!d) return;
(d.notes || []).forEach(function (n, i) {
var o = {
id: t.id + '-' + (i + 1), t: t.id, i: i, title: n.title, cover: n.cover || n.title, coverSub: n.coverSub || '',
author: n.author, stage: n.stage, likes: +n.likes || 0, body: n.body || '',
ratio: n.photo ? 1.3 : RATIO[(ti + i * 3) % RATIO.length], tone: (ti + i) % 3, photo: n.photo || ''
ratio: n.photo ? PR[seed(t.id + '-' + (i + 1) + 'r') % PR.length] : RATIO[(ti + i * 3) % RATIO.length], tone: (ti + i) % 3, photo: n.photo || ''
};
NOTES.push(o); NBY[o.id] = o;
});
@@ -516,10 +549,14 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var on = liked(n.id);
return '<span class="lk' + (on ? ' on' : '') + '" data-like="' + n.id + '" role="button" aria-label="点赞"><svg class="ic"><use href="#i-heart' + (on ? '-f' : '') + '"/></svg>' + cfmt(likeN(n)) + '</span>';
}
function cardHTML(n, showTopic) {
var t = TBY[n.t];
return '<button type="button" class="nc" data-id="' + n.id + '"><div class="cvw">' +
coverHTML(n, 'calc(var(--cw) * ' + n.ratio + ')') + '</div>' +
/* 卡片样式 sty(只对照片封面):'' 普通图 / 'ov' 图上压大字(底部渐变)/ 'tg' 图上贴纸字 —— 11-02 用户:「把一些文字放到图片上,穿插着来,类似小红书」 */
function cardHTML(n, showTopic, sty) {
var t = TBY[n.t], r = n.ratio, ov = '';
if (!n.photo) sty = '';
if (sty === 'ov') { r = Math.max(r, 1.28); ov = '<div class="ovt"><b>' + esc(n.cover) + '</b>' + (n.coverSub ? '<small>' + esc(n.coverSub) + '</small>' : '') + '</div>'; }
else if (sty === 'tg') ov = '<div class="tgt"><b><span>' + esc(n.cover) + '</span></b></div>';
return '<button type="button" class="nc' + (sty ? ' s-' + sty : '') + '" data-id="' + n.id + '"><div class="cvw">' +
coverHTML(n, 'calc(var(--cw) * ' + r + ')') + ov + '</div>' +
'<div class="nb"><h3>' + esc(n.title) + '</h3>' + (showTopic ? '<span class="tp k-' + t.cat + '"># ' + esc(t.name) + '</span>' : '') + '<div class="nf"><img src="' + esc(avOf(n)) + '" alt="" loading="lazy"><span class="nm">' + esc(n.author) + '</span>' + likeHTML(n) + '</div></div></button>';
}
@@ -565,14 +602,29 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
'<h3># ' + esc(x.name) + '</h3><p>' + esc((D[x.id] || {}).desc || '') + '</p>' +
'<button type="button" class="jn" data-join="' + x.id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button></div>';
}).join('') + '</div>';
fh.innerHTML = '<h2>' + (catF ? CAT_NAME[catF] : '大家在聊') + '</h2>' + (catF ? '<small>' + CAT_SUB[catF] + '</small>' : '');
if (catF) { fhLevels(fh); return; }
fh.className = 'sh';
fh.innerHTML = '<h2>大家在聊</h2><small>' + T.filter(function (x) { return cntT(x.id); }).length + ' 个话题 · 共 ' + NOTES.length + ' 篇</small>';
return;
}
var d = D[t.id] || {};
el.innerHTML = '<div class="th k-' + t.cat + '"><i class="wm" aria-hidden="true">' + esc(t.g) + '</i><button type="button" class="x" data-t="" aria-label="看全部"><svg class="ic"><use href="#i-x"/></svg></button>' +
kbHTML(t.cat) + '<h2><em>#</em>' + esc(t.name) + '</h2><p>' + esc(d.desc || '') + '</p>' +
'<div class="bc"><button type="button" data-t="">' + kbHTML(t.cat).replace('</span>', ' ›</span>') + '</button><span>话题 · ' + cntT(t.id) + ' 篇</span></div>' +
'<h2><em>#</em>' + esc(t.name) + '</h2><p>' + esc(d.desc || '') + '</p>' +
'<div class="tf"><button type="button" class="join" data-join="' + t.id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button><button type="button" class="sw" data-all="1">换个话题</button></div></div>' + rewardHTML(true);
fh.innerHTML = '<h2>这个话题下的分享</h2>';
fhLevels(fh);
}
/* 11-02 用户:「选了家庭婚姻下一个话题,看着像这块就这几篇,层次感没出来」→ 选了分类 / 话题时,列表上方固定一行「分类 · N 个话题 · 共 M 篇」+ 该分类全部话题胶囊(带篇数),当前话题高亮,「全部」回分类 */
var cntT = function (id) { return NOTES.filter(function (n) { return n.t === id; }).length; };
function fhLevels(fh) {
var tl = hotList().filter(function (x) { return cntT(x.id); }), all = 0;
tl.forEach(function (x) { all += cntT(x.id); });
fh.className = 'lvw k-' + catF;
fh.innerHTML = '<div class="lv"><h2>' + CATS.filter(function (c) { return c[0] === catF; })[0][1] + '</h2><small>' + tl.length + ' 个话题 · 共 ' + all + ' 篇</small>' +
(cur ? '<button type="button" class="ba" data-t="">看这块全部 ›</button>' : '') + '</div>' +
'<div class="tcs"><button type="button" data-t=""' + (cur ? '' : ' class="on"') + '>全部<i>' + all + '</i></button>' +
tl.map(function (x) { return '<button type="button" data-t="' + x.id + '"' + (cur === x.id ? ' class="on"' : '') + '># ' + esc(x.name) + '<i>' + cntT(x.id) + '</i></button>'; }).join('') + '</div>';
var on = fh.querySelector('.tcs .on'); if (on && cur) fh.querySelector('.tcs').scrollLeft = Math.max(0, on.offsetLeft - 60);
}
function renderFeed() {
var list = cur ? NOTES.filter(function (n) { return n.t === cur; }) : MIXED.filter(function (n) { return inCat(TBY[n.t]); });
@@ -583,14 +635,20 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
var cw = cols[0].clientWidth || 175;
wf.style.setProperty('--cw', cw + 'px');
/* 真瀑布流:每张卡放进当前更矮的那一列(逐张量高,标题一行/两行也算进去) */
var hs = [0, 0], tmp = document.createElement('div');
var hs = [0, 0], tmp = document.createElement('div'), STY = ['', 'ov', '', '', 'tg', '', '', 'ov', '', 'tg', '', ''];
list.forEach(function (n, k) {
tmp.innerHTML = cardHTML(n, !cur);
tmp.innerHTML = cardHTML(n, !cur, STY[k % STY.length]);
var el = tmp.firstChild; el.style.animationDelay = Math.min(k, 10) * 30 + 'ms';
var c = hs[0] <= hs[1] ? 0 : 1;
cols[c].appendChild(el);
hs[c] += el.offsetHeight + 8;
});
/* 话题下帖子看完,接着引到同分类其他话题,避免以为这块只有这几篇 */
var mo = $('#more'), tc = cur && TBY[cur];
if (tc) {
var rest = NOTES.filter(function (n) { return n.t !== cur && TBY[n.t].cat === tc.cat; }).length;
mo.innerHTML = '<button type="button" class="mo k-' + tc.cat + '" data-t=""><small>这个话题就这些啦</small><b>「' + CATS.filter(function (c) { return c[0] === tc.cat; })[0][1] + '」还有 ' + rest + ' 篇,去看看 ›</b></button>';
} else mo.innerHTML = '';
}
function setQuery(t, n) {
var q = new URLSearchParams(location.search);
@@ -615,6 +673,13 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
catF = b.dataset.c; haptic();
selectTopic(''); /* 换分类回到该类「全部」,避免停在别类话题上 */
});
$('#fh').addEventListener('click', function (e) {
var b = e.target.closest('[data-t]'); if (!b || b.dataset.t === cur) return;
haptic(); var sl = $('#fh .tcs') ? $('#fh .tcs').scrollLeft : 0;
selectTopic(b.dataset.t, false);
var tc = $('#fh .tcs'); if (tc && !b.dataset.t) tc.scrollLeft = sl;
});
$('#more').addEventListener('click', function (e) { if (e.target.closest('[data-t]')) { haptic(); selectTopic(''); } });
$('#head').addEventListener('click', function (e) {
var j = e.target.closest('[data-join]'); if (j) { haptic(); openRule(j.dataset.join); return; }
if (e.target.closest('[data-rule]')) { openRule(''); return; }