347 lines
22 KiB
HTML
347 lines
22 KiB
HTML
<!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">
|
|
<title>孕妈广场</title>
|
|
<!-- 效果稿 V4 · 聊天广场:每个话题是一个「聊天室」,直接露出 2~3 条气泡;分类 = 顶部频道胶囊;投稿 = 底部输入条。演示页,不接后端。 -->
|
|
<style>
|
|
:root{
|
|
--brand:#F4593C;--bg:#F5F6F8;--card:#fff;--ink:#1F2329;--ink2:#5B6170;--ink3:#9AA0AC;--line:#ECEDF1;
|
|
--bub:#F3F4F7;--safe-t:env(safe-area-inset-top);--safe-b:env(safe-area-inset-bottom);
|
|
}
|
|
.k-family{--kf:#E0566F;--kl:#FDECEF}
|
|
.k-work{--kf:#3A72B8;--kl:#E9F0FA}
|
|
.k-baby{--kf:#2E8A7C;--kl:#E4F3F0}
|
|
.k-all{--kf:#F4593C;--kl:#FEEDE8}
|
|
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
|
|
html,body{height:100%;overflow:hidden;background:var(--bg)}
|
|
body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Segoe UI",Roboto,sans-serif;color:var(--ink);font-size:14px;-webkit-font-smoothing:antialiased}
|
|
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
|
|
img{display:block}
|
|
#sc{position:fixed;inset:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}
|
|
|
|
/* ---------- 顶部 ---------- */
|
|
.top{position:sticky;top:0;z-index:20;padding-top:var(--safe-t);background:rgba(255,255,255,.88);-webkit-backdrop-filter:blur(16px) saturate(170%);backdrop-filter:blur(16px) saturate(170%);transition:box-shadow .2s}
|
|
.top.on{box-shadow:0 1px 0 var(--line),0 6px 18px rgba(30,35,45,.05)}
|
|
.nav{height:46px;display:flex;align-items:center;padding:0 12px 0 6px;position:relative}
|
|
.back{width:38px;height:38px;display:flex;align-items:center;justify-content:center;border-radius:50%}
|
|
.back:active{background:rgba(0,0,0,.05)}
|
|
.nav h1{font-size:17px;font-weight:700;margin-left:2px;letter-spacing:.5px}
|
|
.nav .ver{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:11px;color:#B5BAC4;letter-spacing:.3px}
|
|
/* 频道胶囊 */
|
|
.chs{display:flex;gap:8px;padding:2px 14px 10px;overflow-x:auto;scrollbar-width:none}
|
|
.chs::-webkit-scrollbar{display:none}
|
|
.ch{flex:none;height:32px;padding:0 14px 0 11px;border-radius:16px;background:#F1F2F5;color:var(--ink2);font-size:14px;font-weight:600;display:flex;align-items:center;gap:3px;transition:background .2s,color .2s}
|
|
.ch i{font-style:normal;font-weight:800;color:var(--kf);opacity:.85}
|
|
.ch small{font-size:11px;font-weight:500;color:var(--ink3);margin-left:3px}
|
|
.ch.on{background:var(--kf);color:#fff;box-shadow:0 4px 12px -4px var(--kf)}
|
|
.ch.on i,.ch.on small{color:rgba(255,255,255,.85);opacity:1}
|
|
|
|
/* ---------- 此刻在线 ---------- */
|
|
.live{margin:12px 14px 4px;padding:14px 14px 13px;border-radius:18px;background:#fff;position:relative;overflow:hidden}
|
|
.live::before{content:"";position:absolute;right:-30px;top:-40px;width:150px;height:150px;border-radius:50%;background:radial-gradient(circle,rgba(244,89,60,.10),rgba(244,89,60,0) 70%)}
|
|
.lv-h{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--ink2);position:relative}
|
|
.dot{width:8px;height:8px;border-radius:50%;background:#2BC266;position:relative;flex:none}
|
|
.dot::after{content:"";position:absolute;inset:-4px;border-radius:50%;background:#2BC266;opacity:.35;animation:pulse 1.8s ease-out infinite}
|
|
@keyframes pulse{0%{transform:scale(.4);opacity:.5}100%{transform:scale(1.4);opacity:0}}
|
|
.lv-h b{font-size:20px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:.3px}
|
|
.lv-h .u{color:var(--ink)}
|
|
.lv-row{display:flex;align-items:flex-end;gap:6px;justify-content:space-between;margin-top:12px;overflow:hidden;position:relative}
|
|
.sp{flex:none;width:48px;display:flex;flex-direction:column;align-items:center;gap:5px}
|
|
.sp .av{width:44px;height:44px;border-radius:50%;object-fit:cover;background:#eee;border:2px solid #fff;box-shadow:0 0 0 2px #EFEFF2}
|
|
.sp.talk .av{box-shadow:0 0 0 2px #2BC266}
|
|
.sp span{font-size:11px;color:var(--ink3);max-width:52px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
.sp .wv{position:absolute;margin:30px 0 0 30px;width:18px;height:18px;border-radius:50%;background:#2BC266;border:2px solid #fff;display:flex;align-items:center;justify-content:center;gap:1.5px}
|
|
.sp .wv i{width:2px;height:6px;border-radius:1px;background:#fff;animation:wv .9s ease-in-out infinite}
|
|
.sp .wv i:nth-child(2){animation-delay:.15s}.sp .wv i:nth-child(3){animation-delay:.3s}
|
|
@keyframes wv{0%,100%{transform:scaleY(.45)}50%{transform:scaleY(1.15)}}
|
|
.sp{position:relative}
|
|
.lv-tk{margin-top:12px;height:20px;overflow:hidden;font-size:12px;color:var(--ink3);position:relative}
|
|
.lv-tk div{height:20px;line-height:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:transform .5s}
|
|
.lv-tk b{color:var(--ink2);font-weight:600}
|
|
|
|
/* ---------- 分区标题 ---------- */
|
|
.sec{display:flex;align-items:baseline;justify-content:space-between;padding:16px 18px 8px}
|
|
.sec h2{font-size:16px;font-weight:700}
|
|
.sec span{font-size:12px;color:var(--ink3)}
|
|
|
|
/* ---------- 聊天室卡片 ---------- */
|
|
.feed{padding:0 12px}
|
|
.room{background:#fff;border-radius:20px;margin-bottom:12px;padding:14px 14px 0;position:relative;overflow:hidden}
|
|
.room:active{transform:scale(.995)}
|
|
.rh{display:flex;gap:10px;align-items:flex-start;padding-bottom:12px;border-bottom:1px solid var(--line)}
|
|
.rh .ic{flex:none;width:40px;height:40px;border-radius:13px;background:var(--kl);color:var(--kf);display:flex;align-items:center;justify-content:center;font-size:19px;font-weight:800;position:relative}
|
|
.rh .ic em{position:absolute;right:-3px;top:-3px;font-style:normal;font-size:10px;line-height:15px;height:15px;padding:0 4px;border-radius:8px;background:var(--brand);color:#fff;font-weight:700;border:1.5px solid #fff}
|
|
.rh .tt{flex:1;min-width:0}
|
|
.rh h3{font-size:15px;font-weight:700;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
|
.rh .mt{margin-top:3px;font-size:12px;color:var(--ink3);display:flex;align-items:center;gap:6px;white-space:nowrap}
|
|
.rh .mt .chn{color:var(--kf);font-weight:600}
|
|
.rh .mt .on{display:inline-flex;align-items:center;gap:4px}
|
|
.rh .mt .on::before{content:"";width:6px;height:6px;border-radius:50%;background:#2BC266}
|
|
|
|
.msgs{padding:12px 0 4px}
|
|
.m{display:flex;gap:9px;margin-bottom:12px}
|
|
.m .av{flex:none;width:34px;height:34px;border-radius:50%;object-fit:cover;background:#eee}
|
|
.m .bd{min-width:0;flex:1;display:flex;flex-direction:column;align-items:flex-start}
|
|
.m .who{font-size:12px;color:var(--ink3);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
|
|
.m .who b{color:var(--ink2);font-weight:600;margin-right:6px}
|
|
.m .who .wk{display:inline-block;font-size:11px;line-height:16px;padding:0 6px;border-radius:8px;background:var(--kl);color:var(--kf);font-weight:600}
|
|
.bb{position:relative;max-width:92%;background:var(--bub);border-radius:4px 16px 16px 16px;padding:9px 12px;font-size:14px;line-height:1.55;color:var(--ink)}
|
|
.bb .q{font-weight:700;display:block;margin-bottom:2px}
|
|
.bb .s{color:var(--ink2);display:-webkit-box;-webkit-line-clamp:var(--cl,2);-webkit-box-orient:vertical;overflow:hidden}
|
|
.bb.rp{font-size:14px}
|
|
.bb.rp .at{color:var(--kf);font-weight:600;margin-right:3px}
|
|
.pic{position:relative;margin-top:6px;width:108px;height:144px;border-radius:4px 14px 14px 14px;overflow:hidden;background:#EDEEF1}
|
|
.pic img{width:100%;height:100%;object-fit:cover}
|
|
.pic::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 0 0 1px rgba(0,0,0,.04)}
|
|
.lk{margin-top:5px;font-size:11px;color:var(--ink3);display:flex;align-items:center;gap:3px}
|
|
.lk svg{width:12px;height:12px}
|
|
|
|
.rf{display:flex;align-items:center;justify-content:space-between;padding:10px 0 13px;border-top:1px dashed var(--line)}
|
|
.typing{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink3);min-width:0}
|
|
.stack{display:flex;flex:none}
|
|
.stack img{width:20px;height:20px;border-radius:50%;object-fit:cover;border:1.5px solid #fff;margin-left:-6px;background:#eee}
|
|
.stack img:first-child{margin-left:0}
|
|
.typing .tx{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
.typing .tx b{color:var(--ink2);font-weight:600}
|
|
.dots{display:inline-flex;gap:2px;margin-left:2px;vertical-align:middle}
|
|
.dots i{width:3px;height:3px;border-radius:50%;background:var(--ink3);animation:db 1.2s infinite}
|
|
.dots i:nth-child(2){animation-delay:.2s}.dots i:nth-child(3){animation-delay:.4s}
|
|
@keyframes db{0%,60%,100%{opacity:.25}30%{opacity:1}}
|
|
.go{flex:none;height:30px;padding:0 12px;border-radius:15px;background:var(--kl);color:var(--kf);font-size:13px;font-weight:700;display:flex;align-items:center;gap:2px}
|
|
.go svg{width:12px;height:12px}
|
|
|
|
.foot{padding:6px 0 20px;text-align:center;font-size:11px;color:#B5BAC4}
|
|
.pad{height:calc(84px + var(--safe-b))}
|
|
|
|
/* ---------- 底部输入条 ---------- */
|
|
.bar{position:fixed;left:0;right:0;bottom:0;z-index:30;padding:8px 12px calc(8px + var(--safe-b));background:rgba(255,255,255,.92);-webkit-backdrop-filter:blur(16px) saturate(170%);backdrop-filter:blur(16px) saturate(170%);box-shadow:0 -1px 0 var(--line)}
|
|
.ipt{display:flex;align-items:center;gap:8px;height:44px}
|
|
.ipt .me{flex:none;width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,#FFD9CF,#FFB8A6);display:flex;align-items:center;justify-content:center;color:#fff}
|
|
.ipt .me svg{width:18px;height:18px}
|
|
.field{flex:1;min-width:0;height:40px;border-radius:20px;background:#F1F2F5;display:flex;align-items:center;padding:0 6px 0 14px;gap:6px;text-align:left}
|
|
.field .ph{flex:1;min-width:0;font-size:13.5px;color:var(--ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
.field .ph em{font-style:normal;color:var(--brand);font-weight:700}
|
|
.field .cur{width:1.5px;height:16px;background:var(--brand);animation:blink 1s steps(1) infinite;flex:none;margin-right:-2px}
|
|
@keyframes blink{50%{opacity:0}}
|
|
.send{flex:none;height:30px;padding:0 13px;border-radius:15px;background:var(--brand);color:#fff;font-size:13px;font-weight:700;display:flex;align-items:center}
|
|
|
|
/* ---------- 弹层 ---------- */
|
|
.mask{position:fixed;inset:0;z-index:50;background:rgba(20,22,28,.42);opacity:0;pointer-events:none;transition:opacity .25s}
|
|
.mask.on{opacity:1;pointer-events:auto}
|
|
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:51;background:#fff;border-radius:22px 22px 0 0;padding:10px 18px calc(18px + var(--safe-b));transform:translateY(105%);transition:transform .3s cubic-bezier(.2,.8,.2,1)}
|
|
.sheet.on{transform:none}
|
|
.sheet .gb{width:36px;height:4px;border-radius:2px;background:#E1E3E8;margin:0 auto 14px}
|
|
.sheet h3{font-size:17px;font-weight:700;text-align:center}
|
|
.rw{margin:14px 0;padding:14px;border-radius:16px;background:#FFF3EF;display:flex;align-items:center;gap:12px}
|
|
.rw b{font-size:24px;color:var(--brand);font-weight:800;white-space:nowrap}
|
|
.rw b small{font-size:14px;font-weight:700;margin:0 2px}
|
|
.rw span{font-size:12px;color:var(--ink2);line-height:1.5}
|
|
.sheet ol{padding-left:18px;font-size:13px;color:var(--ink2);line-height:1.8}
|
|
.sheet .btn{margin-top:16px;width:100%;height:46px;border-radius:23px;background:var(--brand);color:#fff;font-size:15px;font-weight:700}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="sc">
|
|
<header class="top" id="top">
|
|
<div class="nav">
|
|
<button class="back" id="back" type="button" aria-label="返回"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#1F2329" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 5l-7 7 7 7"/></svg></button>
|
|
<h1>孕妈广场</h1>
|
|
<span class="ver">效果稿 V4 · 聊天广场</span>
|
|
</div>
|
|
<nav class="chs" id="chs"></nav>
|
|
</header>
|
|
|
|
<section class="live">
|
|
<div class="lv-h"><span class="dot"></span>此刻在线 <b id="onl">12,486</b> <span class="u">位孕妈</span></div>
|
|
<div class="lv-row" id="spk"></div>
|
|
<div class="lv-tk" id="tk"></div>
|
|
</section>
|
|
|
|
<div class="sec"><h2 id="secT">大家正在聊</h2><span id="secN"></span></div>
|
|
<main class="feed" id="feed"></main>
|
|
<div class="foot">话题与内容为示例占位</div>
|
|
<div class="pad"></div>
|
|
</div>
|
|
|
|
<div class="bar">
|
|
<div class="ipt">
|
|
<button class="field" id="post" type="button"><span class="cur"></span><span class="ph">说说你的故事,被选中 <em>¥30+500 兜豆</em></span><span class="send">投稿</span></button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mask" id="mask"></div>
|
|
<div class="sheet" id="sheet">
|
|
<div class="gb"></div>
|
|
<h3>说说你的故事</h3>
|
|
<div class="rw"><b>¥<small></small>30<small>+</small>500</b><span>投稿被选中,每篇奖励 30 元现金 + 500 兜豆</span></div>
|
|
<ol>
|
|
<li>挑一个话题,写下你自己的真实经历</li>
|
|
<li>提交后进入审核,通过即展示在广场</li>
|
|
<li>被选中的稿件,工作人员会尽快发放奖励</li>
|
|
</ol>
|
|
<button class="btn" id="goPost" type="button">去投稿</button>
|
|
</div>
|
|
|
|
<script src="../../guangchang/topics.js"></script>
|
|
<script src="../../guangchang/data.js"></script>
|
|
<script>
|
|
(function () {
|
|
var T = window.GC_TOPICS || [], D = window.GC_DATA || {};
|
|
var $ = function (s) { return document.querySelector(s); };
|
|
var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); };
|
|
var hs = function (s) { var x = 7; s = String(s); for (var i = 0; i < s.length; i++) x = (x * 31 + s.charCodeAt(i)) | 0; return Math.abs(x); };
|
|
var POOL = [];
|
|
for (var i = 1; i <= 22; i++) POOL.push('m' + (i < 10 ? '0' : '') + i);
|
|
for (i = 1; i <= 14; i++) POOL.push('p' + (i < 10 ? '0' : '') + i);
|
|
var av = function (name) { return '../../assets/img/mom/' + POOL[hs(name) % POOL.length] + '.jpg'; };
|
|
var fmt = function (n) { return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ','); };
|
|
var first = function (b) { var s = String(b || '').split('\n')[0]; var m = s.match(/^[^。!?!?]*[。!?!?]/); s = m ? m[0] : s; return s.length > 60 ? s.slice(0, 58) + '…' : s; };
|
|
var CH = [['all', '全部'], ['family', '家庭婚姻'], ['work', '职场'], ['baby', '经验']];
|
|
var CHN = { family: '家庭婚姻', work: '职场', baby: '经验' };
|
|
var cur = 'all';
|
|
var heart = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-7.5-4.6-9.6-9.2C.9 8.4 3 4.5 6.7 4.5c2.1 0 3.6 1.1 4.3 2.4h2c.7-1.3 2.2-2.4 4.3-2.4 3.7 0 5.8 3.9 4.3 7.3C19.5 16.4 12 21 12 21z"/></svg>';
|
|
var arrow = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5l7 7-7 7"/></svg>';
|
|
|
|
var detail = function (tid, idx) { return '../../guangchang/?t=' + tid + (idx ? '&n=' + tid + '-' + idx : '') + location.hash; };
|
|
|
|
/* 频道 */
|
|
function renderCh() {
|
|
$('#chs').innerHTML = CH.map(function (c) {
|
|
return '<button type="button" class="ch k-' + c[0] + (cur === c[0] ? ' on' : '') + '" data-c="' + c[0] + '"><i>#</i>' + c[1] + '</button>';
|
|
}).join('');
|
|
}
|
|
$('#chs').addEventListener('click', function (e) {
|
|
var b = e.target.closest('.ch'); if (!b || b.dataset.c === cur) return;
|
|
cur = b.dataset.c; renderCh(); renderFeed(); renderLive();
|
|
var top = $('.sec').offsetTop - $('#top').offsetHeight;
|
|
if ($('#sc').scrollTop > top) $('#sc').scrollTop = top;
|
|
});
|
|
|
|
/* 列表:全部 = 三块轮流排、热门在前 */
|
|
function list() {
|
|
var by = { family: [], work: [], baby: [] };
|
|
T.forEach(function (t) { (by[t.cat] = by[t.cat] || []).push(t); });
|
|
Object.keys(by).forEach(function (k) { by[k].sort(function (a, b) { return b.hot - a.hot || b.talk - a.talk; }); });
|
|
if (cur !== 'all') return by[cur] || [];
|
|
var out = [], ks = ['family', 'work', 'baby'], mx = Math.max(by.family.length, by.work.length, by.baby.length);
|
|
for (var i = 0; i < mx; i++) ks.forEach(function (k) { if (by[k][i]) out.push(by[k][i]); });
|
|
return out;
|
|
}
|
|
|
|
function msg(name, stage, inner, tid, idx) {
|
|
return '<div class="m" data-t="' + tid + '"' + (idx ? ' data-n="' + idx + '"' : '') + '>' +
|
|
'<img class="av" loading="lazy" src="' + av(name) + '" alt="">' +
|
|
'<div class="bd"><div class="who"><b>' + esc(name) + '</b>' + (stage ? '<span class="wk">' + esc(stage.replace(/\s+/g, '')) + '</span>' : '') + '</div>' + inner + '</div></div>';
|
|
}
|
|
|
|
function room(t) {
|
|
var d = D[t.id] || { notes: [], comments: [] }, ns = d.notes || [], h = '';
|
|
/* 第一条:带照片的笔记优先,文字气泡 + 图片消息 */
|
|
var order = ns.map(function (n, i) { return i; }).sort(function (a, b) { return (ns[b].photo ? 1 : 0) - (ns[a].photo ? 1 : 0); });
|
|
var a = order[0], b = order[1];
|
|
if (ns[a]) {
|
|
var n = ns[a];
|
|
h += msg(n.author, n.stage,
|
|
'<div class="bb"><span class="q">' + esc(n.title) + '</span><span class="s">' + esc(first(n.body)) + '</span></div>' +
|
|
(n.photo ? '<div class="pic"><img loading="lazy" src="../../guangchang/' + n.photo + '" alt=""></div>' : '') +
|
|
'<div class="lk">' + heart + fmt(n.likes) + ' 人抱抱</div>', t.id, a + 1);
|
|
}
|
|
/* 第二条:一句评论回复,像群里接话 */
|
|
var cm = (d.comments || [])[hs(t.id) % Math.max(1, (d.comments || []).length)];
|
|
if (cm && ns[a]) {
|
|
h += msg(cm.n, cm.s, '<div class="bb rp"><span class="at">@' + esc(ns[a].author) + '</span>' + esc(cm.t) + '</div>', t.id, a + 1);
|
|
}
|
|
/* 第三条:另一篇笔记 */
|
|
if (ns[b]) {
|
|
var m = ns[b];
|
|
h += msg(m.author, m.stage, '<div class="bb" style="--cl:1"><span class="q">' + esc(m.title) + '</span><span class="s">' + esc(first(m.body)) + '</span></div>', t.id, b + 1);
|
|
}
|
|
var tp = (d.comments || []).slice(0, 3).map(function (c) { return c.n; });
|
|
var who = tp[(hs(t.id) >> 3) % Math.max(1, tp.length)] || '有人';
|
|
return '<article class="room k-' + t.cat + '" data-t="' + t.id + '">' +
|
|
'<div class="rh"><span class="ic">' + esc(t.g) + (t.hot ? '<em>热</em>' : '') + '</span>' +
|
|
'<div class="tt"><h3>' + esc(t.name) + '</h3><div class="mt"><span class="chn"># ' + CHN[t.cat] + '</span><span class="on">' + fmt(Math.round(t.talk / 9)) + ' 人在线</span><span>' + fmt(t.n) + ' 篇</span></div></div></div>' +
|
|
'<div class="msgs">' + h + '</div>' +
|
|
'<div class="rf"><div class="typing"><span class="stack">' + tp.map(function (n) { return '<img loading="lazy" src="' + av(n) + '" alt="">'; }).join('') + '</span>' +
|
|
'<span class="tx">还有 <b>' + fmt(t.talk) + '</b> 人在聊<span class="dots"><i></i><i></i><i></i></span></span></div>' +
|
|
'<span class="go">进去听听' + arrow + '</span></div></article>';
|
|
}
|
|
|
|
function renderFeed() {
|
|
var L = list();
|
|
$('#feed').innerHTML = L.map(room).join('');
|
|
$('#secT').textContent = cur === 'all' ? '大家正在聊' : '# ' + CHN[cur] + ' 频道';
|
|
$('#secN').textContent = L.length + ' 个聊天室';
|
|
}
|
|
$('#feed').addEventListener('click', function (e) {
|
|
var r = e.target.closest('.room'); if (!r) return;
|
|
var m = e.target.closest('.m');
|
|
location.href = detail(r.dataset.t, m && m.dataset.n);
|
|
});
|
|
|
|
/* 此刻在线:正在说话的头像 + 滚动播报 */
|
|
var tkTimer = null;
|
|
function renderLive() {
|
|
var L = list(), seen = {}, sp = [];
|
|
L.forEach(function (t) { (D[t.id] && D[t.id].notes || []).forEach(function (n) { if (!seen[n.author] && sp.length < 7) { seen[n.author] = 1; sp.push({ n: n.author, t: t }); } }); });
|
|
sp = sp.slice(0, 6);
|
|
$('#spk').innerHTML = sp.map(function (s, i) {
|
|
return '<button type="button" class="sp' + (i < 3 ? ' talk' : '') + '" data-t="' + s.t.id + '"><img class="av" src="' + av(s.n) + '" alt="">' +
|
|
(i < 3 ? '<span class="wv"><i></i><i></i><i></i></span>' : '') + '<span>' + esc(s.n) + '</span></button>';
|
|
}).join('');
|
|
var base = cur === 'all' ? 12486 : { family: 5210, work: 3874, baby: 3402 }[cur];
|
|
$('#onl').textContent = fmt(base);
|
|
var lines = [];
|
|
L.slice(0, 8).forEach(function (t) { var c = (D[t.id] && D[t.id].comments || [])[0]; if (c) lines.push('<b>' + esc(c.n) + '</b> 在「' + esc(t.name) + '」里说:' + esc(c.t)); });
|
|
var tk = $('#tk'), k = 0;
|
|
tk.innerHTML = '<div>' + (lines[0] || '') + '</div>';
|
|
clearInterval(tkTimer);
|
|
tkTimer = setInterval(function () {
|
|
k = (k + 1) % lines.length;
|
|
var d = document.createElement('div'); d.innerHTML = lines[k];
|
|
tk.appendChild(d);
|
|
[].forEach.call(tk.children, function (c) { c.style.transform = 'translateY(-20px)'; });
|
|
setTimeout(function () { if (tk.children.length > 1) tk.removeChild(tk.children[0]); [].forEach.call(tk.children, function (c) { c.style.transition = 'none'; c.style.transform = 'none'; c.offsetHeight; c.style.transition = ''; }); }, 520);
|
|
}, 3200);
|
|
}
|
|
$('#spk').addEventListener('click', function (e) { var b = e.target.closest('.sp'); if (b) location.href = detail(b.dataset.t); });
|
|
|
|
/* 投稿 */
|
|
var openS = function (on) { $('#mask').classList.toggle('on', on); $('#sheet').classList.toggle('on', on); };
|
|
$('#post').addEventListener('click', function () { openS(true); });
|
|
$('#mask').addEventListener('click', function () { openS(false); });
|
|
$('#goPost').addEventListener('click', function () { location.href = '../../guangchang/' + location.hash; });
|
|
|
|
$('#back').addEventListener('click', function () { history.length > 1 ? history.back() : location.href = '../../' + location.hash; });
|
|
var sc = $('#sc');
|
|
sc.addEventListener('scroll', function () { $('#top').classList.toggle('on', sc.scrollTop > 4); }, { passive: true });
|
|
|
|
/* 禁止下拉回弹:从手指下往上找还能朝该方向滚的容器,找不到才拦 */
|
|
var sx = 0, sy = 0;
|
|
document.addEventListener('touchstart', function (e) { if (e.touches.length !== 1) return; sx = e.touches[0].clientX; sy = e.touches[0].clientY; }, { passive: true });
|
|
document.addEventListener('touchmove', function (e) {
|
|
if (e.touches.length !== 1) { if (e.cancelable) e.preventDefault(); return; }
|
|
var dx = e.touches[0].clientX - sx, dy = e.touches[0].clientY - sy;
|
|
if (Math.abs(dy) <= Math.abs(dx)) return;
|
|
var el = e.target;
|
|
while (el && el !== document.body && el !== document.documentElement) {
|
|
if (el.nodeType === 1) {
|
|
var oy = getComputedStyle(el).overflowY;
|
|
if ((oy === 'auto' || oy === 'scroll') && el.scrollHeight > el.clientHeight + 1) {
|
|
if (dy > 0 && el.scrollTop > 0) return;
|
|
if (dy < 0 && el.scrollTop + el.clientHeight < el.scrollHeight - 1) return;
|
|
}
|
|
}
|
|
el = el.parentNode;
|
|
}
|
|
if (e.cancelable) e.preventDefault();
|
|
}, { passive: false });
|
|
|
|
renderCh(); renderFeed(); renderLive();
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|