Files
mama-box/js/gch/v6.js

170 lines
14 KiB
JavaScript
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.
/* 11-03 上正式:从 demo/gch/ 并入 js/gch/(正式首页默认加载这一版)
11-02 首页「孕妈广场」效果稿 V6 · 合并版:孕妈广场(V4 故事卡堆,压矮)+ 其他妈妈也在搜(6 个问题)合成一个模块
用户定:小标题仍叫「其他妈妈也在搜」(11-03 用户改为「其他孕妈也在搜」);卡堆左右手滑、点箭头都能翻。
做法:先套 V4(v4.css + v4.js),再在卡堆下面接「其他妈妈也在搜」,原来那块 #pregTips 藏起来。
列表沿用首页 .ms-* 样式(写在 #pregTips 里的 <style>,块藏了样式照样生效),数据同 assets/data/qa/hot.json 前 6 条。 */
(function () {
var sec = document.getElementById('gcHome');
if (!sec) return;
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'js/gch/v4.css?v=26110448';
document.head.appendChild(l);
var s = document.createElement('script'); s.src = 'js/gch/v4.js?v=26110448';
s.onload = function () { if (sec.querySelector('.g4-foot')) merge(); else sec.addEventListener('gc4-ready', merge, { once: true }); }; /* v4 要先拉 feed.js 才渲染 */
document.body.appendChild(s);
var FIRE = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12.6 2.5c.4 3-1.6 4.6-3 6.2C8 10.4 7 12 7 14.3A5 5 0 0012 19.5a5 5 0 005-5.2c0-2-1-3.6-1.9-4.6-.2 1.3-.9 2.2-1.9 2.6.6-3.4-.2-7-.6-9.8z" fill="currentColor"/><path d="M12 19.5a2.6 2.6 0 01-2.6-2.6c0-1.6 1.3-2.5 2-3.6.3 1 .9 1.6 1.6 1.9.9.4 1.6 1.2 1.6 2.1A2.6 2.6 0 0112 19.5z" fill="#FFD36B"/></svg>';
var FIRE_W = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12.6 2.5c.4 3-1.6 4.6-3 6.2C8 10.4 7 12 7 14.3A5 5 0 0012 19.5a5 5 0 005-5.2c0-2-1-3.6-1.9-4.6-.2 1.3-.9 2.2-1.9 2.6.6-3.4-.2-7-.6-9.8z" fill="#FFE07A"/></svg>';
function esc(t) { return String(t == null ? '' : t).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }
function merge() {
sec.classList.add('gv6');
var mk = sec.querySelector('.g4-mark'); if (mk) { if (window.__gcDefault) mk.remove(); else mk.textContent = '效果稿 V6'; }
var old = document.getElementById('pregTips'); if (old) old.style.display = 'none';
var box = document.createElement('div');
box.className = 'g6-ms';
box.innerHTML =
/* 11-03 用户:孕妈广场下面的「其他孕妈也在搜」改成广场里大家关注的 6 条(同日再改:放笔记标题,不放话题,见 pick6);问题库那份挪去「孕期百宝箱 → 孕期百问」 */
'<div class="g6-mh"><h3 class="g6-mt"><span>大家都在关注</span></h3>' +
'<span class="ms-live" aria-hidden="true">' + FIRE.replace('currentColor', 'currentColor') + '广场热议</span>' +
'</div>' +
'<div class="ms-list g6-list"></div>' +
'<button type="button" class="ms-all g6-all hide"></button>';
var foot = sec.querySelector('.g4-foot');
/* 两个测试:你是什么样的妈妈(已有 topic/ceshi)+ 你家准爸爸是哪种队友(新做 topic/duiyou) */
var QZ = [
{ href: 'topic/ceshi/', k: '妈妈类型', t: '你是什么样的妈妈?', n: '15.6万', img: 'topic/ceshi/img/hero.webp', pos: '42% 22%', who: '测你', c: '#7C5CFC', q1: '#F1ECFF', q2: '#E4DBFF', qs: 'rgba(124,92,252,.6)' },
{ href: 'topic/duiyou/', k: '队友类型', t: '准爸爸是哪种队友?', n: '8.3万', img: 'topic/duiyou/img/hero.webp', pos: '58% 24%', who: '测他', c: '#F07A2E', q1: '#FFF3E6', q2: '#FFE2C8', qs: 'rgba(240,122,46,.6)' }
];
/* 11-02 用户:「测一测出三版让我选」→ 地址 &qz=1/2/3 切换:1 插画白卡(默认)/ 2 小胶囊 / 3 你&他合体卡 */
var QV = (location.search.match(/[?&]qz=([1-4])/) || [])[1] || '4'; /* 11-02 用户定:默认用第 4 版彩色卡 */
var qz = document.createElement('div'), lk = function (q) { return esc(q.href + location.search + location.hash); };
qz.className = 'g6-qz qv' + QV;
/* 11-02 用户:「还有多少份测试」→ 头部右侧放总数入口,进孕妈广场的测一测页(30 份 = guangchang/ceshi/meta.js 条数,加减测试时同步改) */
var hd = '<div class="g6-qh">测一测<small>1 分钟,看看你和他</small><a class="g6-qa" href="' + esc('guangchang/?c=ceshi' + location.search.replace(/^\?/, '&') + location.hash) + '">全部 30 份测试 ›</a></div>';
if (QV === '4') {
/* 第 4 版:用户说「测一测要明显一点,把之前那版(紫/橙底)拿来试试」→ 彩色底 + 类型小标签 + 实心按钮 + 右下圆形插画;标题用短的,避免单字掉行 */
qz.innerHTML = hd + '<div class="g6-qr">' + QZ.map(function (q) {
return '<a class="g6-k ripple" href="' + lk(q) + '" style="--qc:' + q.c + ';--q1:' + q.q1 + ';--q2:' + q.q2 + ';--qs:' + q.qs + '">' +
'<img src="' + esc(q.img) + '" alt="" loading="lazy">' +
'<span class="g6-kk">' + esc(q.k) + '</span><b class="g6-kt">' + esc(q.t) + '</b><span class="g6-kn">' + q.n + ' 人测过</span><span class="g6-kg">去测试 ›</span></a>';
}).join('') + '</div>';
} else if (QV === '1') {
qz.innerHTML = hd + '<div class="g6-qr">' + QZ.map(function (q) {
return '<a class="g6-q ripple" href="' + lk(q) + '">' +
'<img src="' + esc(q.img) + '" alt="" loading="lazy">' +
'<span class="g6-qb"><b class="g6-qt">' + esc(q.t) + '</b><span class="g6-qf"><span>' + q.n + ' 人测过</span><span class="g6-qg">开始测 ›</span></span></span></a>';
}).join('') + '</div>';
} else if (QV === '2') {
qz.innerHTML = hd + '<div class="g6-qr">' + QZ.map(function (q) {
return '<a class="g6-c ripple" href="' + lk(q) + '"><img src="' + esc(q.img) + '" alt="" loading="lazy" style="object-position:' + q.pos + '">' +
'<span class="g6-cb"><b>' + esc(q.t) + '</b><small>' + q.n + ' 人测过</small></span><i>›</i></a>';
}).join('') + '</div>';
} else {
qz.innerHTML = hd + '<div class="g6-v"><div class="g6-vr">' + QZ.map(function (q, i) {
return (i ? '<span class="g6-amp">&amp;</span>' : '') +
'<a class="g6-vc ripple" href="' + lk(q) + '"><img src="' + esc(q.img) + '" alt="" loading="lazy" style="object-position:' + q.pos + '">' +
'<small>' + q.who + '</small><b>' + esc(q.t) + '</b><em>开始测 ›</em></a>';
}).join('') + '</div><p class="g6-vf">两个都测完,看看你们是哪种组合 · 已有 23.9万 人测过</p></div>';
}
/* 11-02 用户:「太多了,只放两个测一测」→ 3 个小列表撤掉(topic/yali、yinshi、zhunbei 页面保留,先不挂入口);
位置从卡堆下面挪到「其他妈妈也在搜」下面 */
sec.insertBefore(box, foot);
/* 11-03 用户:首页「孕期百宝箱」已有「趣味小测试」入口 → 这里两张测一测卡不要了(加 ?qzcard=1 还能看回) */
if (/[?&]qzcard=1(?:&|$)/.test(location.search)) sec.insertBefore(qz, foot);
var list = box.querySelector('.g6-list'), all = box.querySelector('.g6-all');
var tot = (window.__mbPulse && window.__mbPulse.total && +window.__mbPulse.total.value) || 1510000;
/* 11-03 用户:「这 6 条要放文章标题,不是话题;挑 6 篇吸引人的」→ 固定 6 篇笔记(点赞高、标题有画面,婚姻 / 经验 / 家庭 / 职场轮着来),
点了直接打开那篇(guangchang/?n=id)。右边配笔记封面小图(图本身不露人头);feed 里找不到的按点赞高的补位。 */
var PICK = ['m09-4', 'b07-1', 'f02-2', 'w10-1', 'b04-4', 'm09-6'];
function pick6() {
var F = window.GC_FEED || [], by = {};
F.forEach(function (n) { by[n.id] = n; });
var out = PICK.map(function (id) { return by[id]; }).filter(Boolean);
F.slice().sort(function (a, b) { return b.likes - a.likes; }).forEach(function (n) { if (out.length < 6 && out.indexOf(n) < 0) out.push(n); });
return out.slice(0, 6);
}
/* 作者头像:同 guangchang/index.html 的 seed + AV 表(改一边要两边一起改) */
var AU_AV = ['m01','m02','m03','m04','m05','m06','m07','m08','m09','m10','m11','m12','m13','m14','m15','m16','m17','m18','m19','m20','m21','m22',
'p01','p02','p03','p04','p05','p06','p07','p08','p09','p10','p11','p12','p13','p14','s01','s02','s03','s04','s05','s06','s07','s08','s09','s10',
'k01','k02','k03','k04','k05','k06','k07','k08','k09','k10','k11','k12','k13'];
function auAv(k) { var h = 7; k = String(k); for (var j = 0; j < k.length; j++) h = (h * 31 + k.charCodeAt(j)) | 0; return 'assets/img/mom/' + AU_AV[Math.abs(h) % AU_AV.length] + '.jpg'; }
function paintList() {
var l6 = pick6();
if (!l6.length) { box.style.display = 'none'; return; }
list.innerHTML = l6.map(function (x, i) {
/* 11-04 用户:一行放下 作者头像 + 名字 + 点赞头像(仅前 3 条)+ N 点赞;不要小心心、不换行;同日再改:名字后面的孕周删掉 */
var n = x.likes || 0,
au = x.author ? '<span class="g6-au"><img src="' + esc(x.avatar || (window.MB_AVA && MB_AVA.S.author[x.id] ? MB_AVA.src(MB_AVA.S.author[x.id], '') : auAv(x.author))) + '" alt="" loading="lazy" decoding="async" width="36" height="36"><b>' + esc(x.author) + '</b></span>' : '',
heat = '<span class="g6-meta">' + au + '<span class="g6-rt">' + (i < 3 ? avs(i) : '') + '<span class="ms-h"><b>' + (n >= 1e4 ? Math.round(n / 1e3) / 10 + '万' : n) + ' 人点赞</b></span></span></span>'; /* 11-04 用户:作者在左;访客头像 + 点赞数一起靠最右(点赞数在头像右边) */
var q = new URLSearchParams(location.search); q.set('n', x.id);
return '<a class="ms-it ripple g6-nt" href="' + esc('guangchang/?' + q.toString() + location.hash) + '"><i class="ms-no">' + (i + 1) + '</i>' +
'<span class="ms-m"><span class="ms-q">' + esc(x.title) + '</span>' + heat + '</span>' +
(x.photo ? '<img class="g6-ph" src="' + esc(x.photo) + '" alt="" loading="lazy">' : '<i class="ms-go">›</i>') + '</a>';
}).join('');
all.textContent = '去广场看更多 ›';
all.classList.remove('hide');
/* 11-04 用户:点赞数别用红字 → 浅灰小心形 + 灰字;同日二改:前 3 条点赞前加回小头像(每条 6~8 个、更小),后 3 条不带 */
likeTick();
fitMeta(); setTimeout(fitMeta, 600);
}
/* 一行放不下(窄屏)就从点赞头像里一个个减,最少留 2 个;作者名不截断 */
function fitMeta() {
[].forEach.call(list.querySelectorAll('.g6-meta'), function (m) {
var ims = m.querySelectorAll('.g6-avs img'), k = ims.length, nm = m.querySelector('.g6-au b');
function tight() { return nm && nm.scrollWidth > nm.clientWidth + 1; } /* 网格版:作者名被挤出省略号就减一个访客头像 */
while (k > 2 && tight()) ims[--k].remove();
});
}
/* 11-03 用户:「点赞数前面放几个小头像,偶尔换一个,相当于有人新点赞进来」
→ 火苗换成 3~6 个叠放小头像;每 4~7 秒随机挑一行:其中一个头像原地换成别人(点赞数不动)。
头像池用首页滚动动态同一批虚构照片(assets/img/mom/,非真实用户);页面在后台时不换。 */
/* 11-03 用户:「这 6 条的头像一定要都不相同」→ 池子扩到 assets/img/mom/ 全部 59 张,按 宝宝 / 妈妈 / 全身合照 / 风景 交错排,相邻不扎堆近脸;
换头像时只从「当前 6 行都没在显示」的里面挑,任何时刻页面上这些头像都互不重复。 */
/* 11-05 用户:各模块头像不要互相重复 → 点赞头像改用分配表 likers(24 个,只在这里出现);原 mom 池仅作兜底 */
var LIKE_AVA = (window.MB_AVA && MB_AVA.S.likers) || (function () {
var g = { p: 14, k: 13, m: 22, s: 10 }, o = [], i;
for (i = 0; o.length < 59; i++) ['p', 'm', 'k', 'm', 's'].forEach(function (c, j) {
var n = c === 'm' ? i * 2 + (j === 1 ? 1 : 2) : i + 1;
if (n <= g[c]) o.push(c + (n < 10 ? '0' : '') + n);
});
return o;
})();
var avaAt = 0;
function lkSrc(n) { return /:|^\//.test(n) && window.MB_AVA ? MB_AVA.src(n, '') : 'assets/img/mom/' + n + '.jpg'; }
function avaEl(n) { return '<img src="' + lkSrc(n) + '" alt="" loading="lazy" decoding="async" width="40" height="40">'; }
/* 11-03 用户:「头像错落一下,不一定都是 3 个,3、4、5、6 个都有」→ 每行个数打乱(固定表,刷新不跳),头像按顺序不重复取 */
var AV_N = [5, 4, 6]; /* 11-04 三改:作者 + 孕周 + 点赞头像要挤一行,6~8 个放不下 → 4~6 个 */ /* 11-04 二改:只前 3 条带头像,每条 6~8 个、头像缩小 */
function avs(i) {
var h = '', c = AV_N[i] || 3;
if (!i) avaAt = 0;
for (var k = 0; k < c; k++) h += avaEl(LIKE_AVA[avaAt++ % LIKE_AVA.length]);
return '<span class="g6-avs" aria-hidden="true">' + h + '</span>';
}
/* 11-04 用户:前 3 条的小头像各自 2~6 秒随机换一个(每条独立计时);原地换(缩小→换图→弹回),个数、点赞数都不动 */
var likeT = [];
function swapOne(r) {
var ims = r.querySelectorAll('.g6-avs img');
if (!ims.length) return;
var im = ims[Math.floor(Math.random() * ims.length)], on = {}, nx, t = 0;
list.querySelectorAll('.g6-avs img').forEach(function (m) { on[m.getAttribute('src')] = 1; });
do { nx = LIKE_AVA[avaAt++ % LIKE_AVA.length]; } while (on[lkSrc(nx)] && ++t < LIKE_AVA.length);
im.className = 'sw-o';
setTimeout(function () { im.src = lkSrc(nx); im.className = 'sw-i'; }, 220);
}
function likeTick() {
likeT.forEach(clearTimeout); likeT = [];
[0, 1, 2].forEach(function (i) {
(function loop() {
likeT[i] = setTimeout(function () {
var r = list.querySelectorAll('.g6-nt')[i];
if (r && !document.hidden && list.offsetParent) swapOne(r);
loop();
}, 2000 + Math.random() * 4000);
})();
});
}
all.addEventListener('click', function () { location.href = 'guangchang/' + location.search + location.hash; });
paintList();
}
})();