页面分双屏滑动: 第一屏看板/第二屏候选人列表, 左右箭头+键盘方向键+触屏滑动, 圆点指示器
This commit is contained in:
+48
-9
@@ -51,6 +51,15 @@ tr:hover td{background:#f8fafc;cursor:pointer}
|
||||
.hidden{display:none}
|
||||
.chartRow{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:12px;margin-bottom:16px}
|
||||
.chartRow .panel{margin-bottom:0}
|
||||
.slider{position:relative;overflow:hidden;margin-bottom:4px}
|
||||
.sliderTrack{display:flex;transition:transform .35s ease;width:100%}
|
||||
.pane{flex:0 0 100%;min-width:100%;padding:2px 14px 2px 2px}
|
||||
.navArrow{position:absolute;top:46%;transform:translateY(-50%);z-index:5;width:34px;height:58px;border-radius:10px;background:rgba(255,255,255,.92);border:1px solid var(--line);font-size:26px;line-height:1;color:var(--txt);cursor:pointer;box-shadow:0 2px 10px rgba(0,0,0,.1)}
|
||||
.navArrow:hover{background:#fff;color:var(--pri)}
|
||||
.navArrow.left{left:-4px}.navArrow.right{right:6px}
|
||||
.dots{text-align:center;margin:2px 0 14px}
|
||||
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#cbd5e1;margin:0 5px;cursor:pointer;transition:all .2s}
|
||||
.dot.on{background:var(--pri);width:22px;border-radius:5px}
|
||||
#toast{position:fixed;top:60px;left:50%;transform:translateX(-50%);background:#1e293b;color:#fff;padding:8px 18px;border-radius:8px;z-index:9;opacity:.95}
|
||||
#detailModal{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:8;display:flex;align-items:center;justify-content:center}
|
||||
#detailModal.hidden{display:none}
|
||||
@@ -79,15 +88,20 @@ tr:hover td{background:#f8fafc;cursor:pointer}
|
||||
</div>
|
||||
</div>
|
||||
<div id="main" class="hidden">
|
||||
<div class="cards" id="statCards"></div>
|
||||
<div class="panel"><h3>近30天趋势</h3><div id="chTrend" style="height:300px"></div></div>
|
||||
<div class="chartRow">
|
||||
<div class="panel"><h3>评分级别分布</h3><div id="chLevel" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>学历分布</h3><div id="chEdu" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>期望城市 TOP8</h3><div id="chCity" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>筛选漏斗</h3><div id="chFunnel" style="height:280px"></div></div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="slider" id="slider">
|
||||
<div class="sliderTrack" id="sliderTrack">
|
||||
<section class="pane">
|
||||
<div class="cards" id="statCards"></div>
|
||||
<div class="panel"><h3>近30天趋势</h3><div id="chTrend" style="height:300px"></div></div>
|
||||
<div class="chartRow">
|
||||
<div class="panel"><h3>评分级别分布</h3><div id="chLevel" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>学历分布</h3><div id="chEdu" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>期望城市 TOP8</h3><div id="chCity" style="height:280px"></div></div>
|
||||
<div class="panel"><h3>筛选漏斗</h3><div id="chFunnel" style="height:280px"></div></div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="pane">
|
||||
<div class="panel">
|
||||
<h3>候选人</h3>
|
||||
<div class="filters">
|
||||
<select id="q_level"><option value="">全部级别</option><option>推荐</option><option>待定</option><option>不推荐</option><option>不相关</option></select>
|
||||
@@ -110,7 +124,13 @@ tr:hover td{background:#f8fafc;cursor:pointer}
|
||||
<span id="pageNo">1</span>
|
||||
<button class="btn sub small" onclick="page(1)">下一页</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<button class="navArrow left" onclick="slide(-1)">‹</button>
|
||||
<button class="navArrow right" onclick="slide(1)">›</button>
|
||||
</div>
|
||||
<div class="dots"><span class="dot on" onclick="setPane(0)"></span><span class="dot" onclick="setPane(1)"></span></div>
|
||||
<div class="panel hidden" id="userPanel"></div>
|
||||
<div id="userModal" onclick="if(event.target===this)this.classList.add('hidden')" class="hidden">
|
||||
<div class="panel" style="width:780px;max-width:94vw;max-height:88vh;overflow:auto">
|
||||
@@ -134,6 +154,25 @@ tr:hover td{background:#f8fafc;cursor:pointer}
|
||||
let me=null,pageCur=1,pageTotal=1;
|
||||
const $=id=>document.getElementById(id);
|
||||
const esc=s=>String(s??'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
|
||||
// ---------- 左右滑动双屏(0=看板 1=列表) ----------
|
||||
let curPane=0;
|
||||
function slide(d){setPane(curPane+d)}
|
||||
function setPane(n){
|
||||
n=Math.max(0,Math.min(1,n));curPane=n;
|
||||
$('sliderTrack').style.transform=`translateX(-${n*100}%)`;
|
||||
document.querySelectorAll('.dot').forEach((el,i)=>el.classList.toggle('on',i===n));
|
||||
document.querySelector('.navArrow.left').style.visibility=n===0?'hidden':'visible';
|
||||
document.querySelector('.navArrow.right').style.visibility=n===1?'hidden':'visible';
|
||||
setTimeout(()=>charts.forEach(c=>c.resize()),400);
|
||||
}
|
||||
document.addEventListener('keydown',e=>{
|
||||
if(!me||e.target.tagName==='INPUT'||e.target.tagName==='TEXTAREA')return;
|
||||
if(e.key==='ArrowLeft')slide(-1);if(e.key==='ArrowRight')slide(1);
|
||||
});
|
||||
(()=>{let x0=null;const sl=$('slider');
|
||||
sl.addEventListener('touchstart',e=>x0=e.touches[0].clientX,{passive:true});
|
||||
sl.addEventListener('touchend',e=>{if(x0===null)return;const dx=e.changedTouches[0].clientX-x0;if(Math.abs(dx)>40)slide(dx<0?1:-1);x0=null},{passive:true});
|
||||
})();
|
||||
const tagCls={'推荐':'rec','待定':'maybe','不推荐':'no','不相关':'irr'};
|
||||
function toast(t){const d=document.createElement('div');d.id='toast';d.textContent=t;document.body.appendChild(d);setTimeout(()=>d.remove(),1800)}
|
||||
|
||||
|
||||
+4
-2
@@ -45,8 +45,10 @@ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
||||
const canvasN = await p.evaluate(() => document.querySelectorAll('#main canvas').length);
|
||||
ok(`图表已渲染(canvas=${canvasN},≥5)`, canvasN >= 5);
|
||||
|
||||
console.log('== 4. 候选人列表与筛选 ==');
|
||||
await sleep(500);
|
||||
console.log('== 4. 候选人列表与筛选(滑动到第二屏) ==');
|
||||
await p.evaluate(() => setPane(1)); await sleep(500);
|
||||
ok('滑到列表屏(箭头状态)', await p.evaluate(() => document.querySelector('.navArrow.left').style.visibility === 'visible'));
|
||||
await sleep(300);
|
||||
const rows1 = await p.evaluate(() => document.querySelectorAll('#tbody tr').length);
|
||||
ok(`默认列表有数据(${rows1}行)`, rows1 > 0);
|
||||
await p.selectOption('#q_level', '推荐');
|
||||
|
||||
Reference in New Issue
Block a user