SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点探测任务(手机触摸版)</title>
<style>
  * { margin:0; padding:0; box-sizing:border-box; -webkit-user-select:none; user-select:none; }
  html,body { height:100%; }
  body { font-family:"Microsoft YaHei",sans-serif; background:#f0f0f0; }
  #screen { width:100%; height:100%; display:flex; flex-direction:column;
            align-items:center; justify-content:center; font-size:18px; position:relative; }
  .card { width:140px; height:200px; display:flex; align-items:center; justify-content:center;
          font-size:22px; font-weight:bold; color:#fff; border-radius:10px; }
  .fix  { font-size:60px; font-weight:bold; color:#333; }
  .probe{ font-size:70px; font-weight:bold; color:#e74c3c; }
  .ins  { text-align:left; line-height:1.8; padding:20px; max-width:480px; }
  .ins h1 { text-align:center; margin-bottom:16px; }
  .row  { display:flex; justify-content:center; gap:40px; align-items:center; width:100%; }
  /* 反应按钮区 */
  #btns { position:fixed; left:0; right:0; bottom:0; height:22%; display:flex; z-index:10; }
  .btn  { flex:1; display:flex; align-items:center; justify-content:center;
          font-size:28px; font-weight:bold; color:#fff; }
  .btnL { background:#3498db; border-right:3px solid #fff; }
  .btnR { background:#e67e22; }
  .btn:active{ filter:brightness(0.8); }
  /* 指导语内的开始按钮 */
  .start-btn { display:block; margin:24px auto 0; width:80%; padding:16px;
               background:#2ecc71; color:#fff; font-size:22px; font-weight:bold;
               border:none; border-radius:10px; }
</style>
</head>
<body>
<div id="screen"></div>
<!-- 反应按钮:固定底部,点探测时显示 -->
<div id="btns" style="display:none;">
  <div class="btn btnL" id="btnL">&#9679; 左</div>
  <div class="btn btnR" id="btnR">右 &#9679;</div>
</div>
<script>
var COLORS={fat:'#e67e22',thin:'#3498db',neutral:'#95a5a6'};
var LABELS={fat:'胖体型',thin:'瘦体型',neutral:'中性图'};
var FIX_MS=500, STIM_MS=500, ITI_MS=400;
var PRACTICE_N=10, FORMAL_N=120;

var scr=document.getElementById('screen');
var btns=document.getElementById('btns');
var btnL=document.getElementById('btnL'), btnR=document.getElementById('btnR');
var records=[];
var respCb=null;

function sleep(ms){ return new Promise(function(r){ setTimeout(r,ms); }); }
function showHTML(h){ scr.innerHTML=h; }
function htmlFix(){ return '<div class="fix">+</div>'; }
function htmlStim(tr){
  return '<div class="row">'+
    '<div class="card" style="background:'+COLORS[tr.left]+'">'+LABELS[tr.left]+'</div>'+
    '<div class="card" style="background:'+COLORS[tr.right]+'">'+LABELS[tr.right]+'</div></div>';
}
function htmlProbe(left){
  return '<div class="row" style="justify-content:'+(left?'flex-start':'flex-end')+'">'+
    '<div class="probe">&#9679;</div></div>';
}
// 触摸反应
function pressSide(){
  return new Promise(function(resolve){
    respCb=function(side){ respCb=null; resolve(side); };
    btns.style.display='flex';
  });
}
function hideBtns(){ btns.style.display='none'; }
btnL.addEventListener('touchstart',function(e){ e.preventDefault(); if(respCb){ respCb('left'); } },{passive:false});
btnR.addEventListener('touchstart',function(e){ e.preventDefault(); if(respCb){ respCb('right'); } },{passive:false});

// 开始按钮(指导语里动态生成,绑定事件)
function waitStart(){
  return new Promise(function(resolve){
    var b=document.querySelector('.start-btn');
    b.addEventListener('touchstart',function(e){ e.preventDefault(); resolve(); },{passive:false});
  });
}

// 生成试次
function genTrials(n){
  var t=[], conds=['fat_neutral','thin_neutral','neutral_neutral','filler'];
  var per=Math.floor(n/conds.length);
  for(var c=0;c<conds.length;c++){
    var cd=conds[c];
    var bt=cd==='fat_neutral'?'fat':cd==='thin_neutral'?'thin':'neutral';
    for(var i=0;i<per;i++){
      var bol=Math.random()<0.5, pol=Math.random()<0.5, lt, rt;
      if(cd==='neutral_neutral'||cd==='filler'){ lt='neutral'; rt='neutral'; }
      else if(bol){ lt=bt; rt='neutral'; }
      else { lt='neutral'; rt=bt; }
      t.push({cond:cd,body_type:bt,probe_on_left:pol,left:lt,right:rt});
    }
  }
  for(var j=t.length-1;j>0;j--){ var k=Math.floor(Math.random()*(j+1)); var tmp=t[j]; t[j]=t[k]; t[k]=tmp; }
  return t;
}
var practice=genTrials(PRACTICE_N);
var formal=genTrials(FORMAL_N);

// 单个试次
async function runTrial(tr,isPractice){
  showHTML(htmlFix());
  await sleep(FIX_MS);
  showHTML(htmlStim(tr));
  await sleep(STIM_MS);
  showHTML(htmlProbe(tr.probe_on_left));
  var t0=performance.now();
  var side=await pressSide();
  var rt=performance.now()-t0;
  hideBtns();
  var correct=(side===(tr.probe_on_left?'left':'right'))?1:0;
  if(!isPractice){
    records.push({rt:Math.round(rt),correct:correct,condition:tr.cond,
                  body_type:tr.body_type,probe_on_left:tr.probe_on_left});
  }
  await sleep(ITI_MS);
}

// 主流程
async function main(){
  showHTML(
    '<div class="ins"><h1>点探测任务</h1>'+
    '<p>每个试次流程:</p>'+
    '<p>1. 中央出现注视点 <b>+</b></p>'+
    '<p>2. 左右两侧同时出现两张图片</p>'+
    '<p>3. 图片消失后,一侧出现红色圆点 <span style="color:#e74c3c;font-weight:bold;">&#9679;</span></p>'+
    '<p>4. 又快又准判断圆点在哪一侧,<b>点击屏幕底部对应按钮</b>:</p>'+
    '<p style="text-align:center;color:#3498db;font-weight:bold;">&#9679; 左(蓝色按钮)</p>'+
    '<p style="text-align:center;color:#e67e22;font-weight:bold;">右 &#9679;(橙色按钮)</p>'+
    '<button class="start-btn">点我开始练习(10次)</button></div>');
  await waitStart();

  for(var i=0;i<practice.length;i++){ await runTrial(practice[i],true); }

  showHTML('<div class="ins"><h1>练习结束</h1>'+
    '<p style="text-align:center;">现在进入正式实验(120次,约15分钟)</p>'+
    '<button class="start-btn">点我开始正式实验</button></div>');
  await waitStart();

  for(var j=0;j<formal.length;j++){ await runTrial(formal[j],false); }

  var n=records.length, hit=0, rtSum=0;
  for(var r=0;r<records.length;r++){ hit+=records[r].correct; rtSum+=records[r].rt; }
  showHTML('<div class="ins"><h1>实验完成</h1>'+
    '<p>有效试次:'+n+'</p>'+
    '<p>正确率:'+(hit/n*100).toFixed(1)+'%</p>'+
    '<p>平均反应时:'+(rtSum/n).toFixed(0)+'ms</p>'+
    '<p style="color:#888;font-size:14px;">完整数据已输出到浏览器控制台(F12→Console)</p></div>');
  console.log(JSON.stringify(records));
}

main();
</script>
</body>
</html>