<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>秒算因数个数 - 深度精讲</title>
<style>
/* ================= 3.1 微信/移动端兼容性 (🚨 必须遵守) ================= */
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
html, body {
margin: 0;
padding: 0;
background: #F0F4F8;
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
/* ================= 布局框架 ================= */
#app {
height: 100vh;
width: 100%;
max-width: 480px;
margin: 0 auto;
background: #fff;
display: flex;
flex-direction: column;
position: relative;
box-shadow: 0 0 20px rgba(0,0,0,0.05);
}
.content-area {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding-bottom: 80px;
position: relative;
-webkit-overflow-scrolling: touch;
}
/* ================= 底部导航 ================= */
.bottom-nav {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 480px;
height: 70px;
background: white;
border-top: 1px solid #e0e0e0;
display: flex;
justify-content: space-around;
align-items: center;
z-index: 1000;
box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
}
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 8px;
transition: all 0.3s;
color: #64748B;
}
.nav-item.active {
color: #2563EB; /* 科技蓝 */
}
.nav-icon { font-size: 24px; margin-bottom: 4px; }
.nav-label { font-size: 12px; font-weight: 500; }
/* ================= 通用样式 ================= */
.page-container { padding: 20px; }
.section-title {
font-size: 20px;
font-weight: 800;
color: #0F172A;
margin: 20px 0 15px 0;
display: flex;
align-items: center;
gap: 8px;
}
.card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
border: 1px solid #E2E8F0;
}
.tag {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
margin-bottom: 8px;
}
.tag-blue { background: #E0F2FE; color: #0284C7; }
.tag-purple { background: #F3E8FF; color: #7C3AED; }
.tag-orange { background: #FFEDD5; color: #C2410C; }
.speak-btn {
background: linear-gradient(135deg, #2563EB 0%, #1D4ED8 100%);
color: white;
border: none;
padding: 10px 20px;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
margin-top: 10px;
display: flex;
align-items: center;
gap: 5px;
box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3);
}
/* ================= 演示实验室 (Page 2) ================= */
.anim-stage {
background: #1E293B;
border-radius: 16px;
padding: 20px;
min-height: 450px;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
border: 2px solid #334155;
}
.slot-machine {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
width: 100%;
}
.slot-col {
display: flex;
flex-direction: column;
align-items: center;
background: rgba(255,255,255,0.1);
padding: 10px;
border-radius: 12px;
flex: 1;
}
.slot-title {
color: #94A3B8;
font-size: 12px;
margin-bottom: 10px;
}
.slot-btn {
width: 36px;
height: 36px;
border-radius: 50%;
border: 2px solid white;
background: transparent;
color: white;
font-weight: bold;
margin: 5px 0;
cursor: pointer;
transition: all 0.2s;
font-size: 14px;
}
.slot-btn.active {
background: #FCD34D;
color: #78350F;
border-color: #FCD34D;
transform: scale(1.1);
}
.result-display {
margin-top: 20px;
background: white;
border-radius: 12px;
padding: 15px;
width: 100%;
text-align: center;
min-height: 90px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.result-formula {
font-size: 20px;
font-weight: bold;
color: #0F172A;
margin-bottom: 5px;
}
.result-desc { font-size: 13px; color: #64748B; }
.total-count {
color: #FCD34D;
font-size: 14px;
margin-top: 15px;
font-weight: bold;
border: 1px dashed #FCD34D;
padding: 8px;
border-radius: 8px;
}
/* 难点解析图示 */
.plate-demo {
display: flex;
justify-content: center;
align-items: center;
margin: 20px 0;
background: #F8FAFC;
border-radius: 12px;
padding: 20px;
height: 120px;
}
.plate {
width: 80px;
height: 80px;
border-radius: 50%;
border: 4px solid #CBD5E1;
background: white;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: #94A3B8;
font-size: 14px;
position: relative;
}
.plate::after {
content: "底座=1";
position: absolute;
bottom: -25px;
font-size: 12px;
color: #64748B;
width: 100px;
text-align: center;
}
/* ================= 列表样式 ================= */
.step-list {
list-style: none;
padding: 0;
margin: 0;
}
.step-list li {
position: relative;
padding-left: 20px;
margin-bottom: 10px;
font-size: 14px;
line-height: 1.6;
color: #334155;
}
.step-list li::before {
content: "•";
position: absolute;
left: 0;
color: #2563EB;
font-weight: bold;
}
/* ================= Page 6: 秘籍卡片 (新样式) ================= */
.secret-scroll {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
padding: 20px;
gap: 15px;
height: 100%;
align-items: center;
}
.secret-card {
min-width: 85%;
height: 480px; /* 稍微加高 */
scroll-snap-align: center;
background: linear-gradient(135deg, #2563EB 0%, #1D4ED8 100%); /* 蓝色 */
border-radius: 20px;
padding: 30px;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
box-shadow: 0 10px 25px rgba(37, 99, 235, 0.4);
position: relative;
}
.secret-card.green {
background: linear-gradient(135deg, #10B981 0%, #059669 100%); /* 绿色 */
box-shadow: 0 10px 25px rgba(16, 185, 129, 0.4);
}
.secret-icon {
font-size: 50px;
margin-bottom: 20px;
background: rgba(255,255,255,0.2);
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
}
.secret-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
}
.secret-content {
background: rgba(255,255,255,0.1);
padding: 20px;
border-radius: 15px;
font-size: 16px;
line-height: 1.8;
width: 100%;
}
/* ================= 题目样式 ================= */
.example-item {
border: 1px solid #E2E8F0;
border-radius: 8px;
margin-bottom: 10px;
overflow: hidden;
}
.example-header {
padding: 15px;
background: #F8FAFC;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
.example-content {
padding: 15px;
border-top: 1px solid #E2E8F0;
background: white;
line-height: 1.6;
font-size: 14px;
color: #334155;
display: none;
}
.example-item.active .example-content { display: block; animation: fadeIn 0.3s; }
.question-card {
background: white;
border-radius: 16px;
padding: 25px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
margin-bottom: 20px;
}
.option-btn {
padding: 15px;
border: 2px solid #E2E8F0;
border-radius: 12px;
background: white;
text-align: left;
font-size: 16px;
cursor: pointer;
margin-bottom: 10px;
transition: all 0.2s;
width: 100%;
}
.option-btn.correct { border-color: #10B981; background: #ECFDF5; color: #047857; }
.option-btn.wrong { border-color: #EF4444; background: #FEF2F2; color: #B91C1C; }
.next-btn {
background: #2563EB;
color: white;
border: none;
padding: 12px;
border-radius: 8px;
width: 100%;
font-weight: bold;
font-size: 16px;
cursor: pointer;
margin-top: 10px;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="page-container">
<div class="section-title">⚡ 秒算因数个数</div>
<div class="card">
<div class="tag tag-blue">核心公式</div>
<p style="font-size: 14px; margin-bottom: 10px;">
如果一个数 N 分解质因数后是:<br>
<span style="font-family: serif; font-size: 16px; font-weight: bold; color: #0F172A;">
N = p<sub>1</sub><sup>a</sup> × p<sub>2</sub><sup>b</sup> × ...
</span>
</p>
<div style="background: #F0F9FF; border: 1px solid #2563EB; padding: 15px; border-radius: 8px; text-align: center;">
<div style="font-size: 18px; font-weight: bold; color: #1E40AF; margin-bottom: 5px;">因数个数 = </div>
<div style="font-size: 20px; font-weight: bold; color: #1E40AF;">(a+1) × (b+1) ...</div>
</div>
<div style="text-align: center; margin-top: 10px; color: #64748B; font-size: 13px;">
口诀:<b>指数加一,再相乘</b>
</div>
</div>
<div class="card">
<div class="tag tag-purple">举个栗子</div>
<div style="font-weight: bold; margin-bottom: 5px;">求 72 的因数个数</div>
<ul class="step-list">
<li>第一步分解:72 = 2<sup>3</sup> × 3<sup>2</sup></li>
<li>第二步找指数:a=3, b=2</li>
<li>第三步套公式:(3+1) × (2+1) = 4 × 3 = 12个</li>
</ul>
<button class="speak-btn" @click="speakIntro">🔊 听老师讲原理</button>
</div>
</div>
<div v-show="currentPage === 2" class="page-container">
<div class="section-title">🎬 原理大揭秘:为什么要+1?</div>
<div style="font-size: 13px; color: #64748B; margin-bottom: 10px;">
找因数就像“点菜”。72 = 2<sup>3</sup> × 3<sup>2</sup><br>
你可以选几个2?选几个3?来试着搭配一下!
</div>
<div class="anim-stage">
<div class="slot-machine">
<div class="slot-col">
<div class="slot-title">选几个 2?</div>
<button v-for="n in 4" :key="'2-'+(n-1)"
class="slot-btn"
:class="{active: selected2 === n-1}"
@click="select2(n-1)">
{{ n-1 }}
</button>
<div style="font-size:10px; color:#94A3B8; margin-top:5px;">共4种选法</div>
</div>
<div style="display:flex; align-items:center; color:white; font-size:20px;">×</div>
<div class="slot-col">
<div class="slot-title">选几个 3?</div>
<button v-for="n in 3" :key="'3-'+(n-1)"
class="slot-btn"
:class="{active: selected3 === n-1}"
@click="select3(n-1)">
{{ n-1 }}
</button>
<div style="font-size:10px; color:#94A3B8; margin-top:5px;">共3种选法</div>
</div>
</div>
<div class="result-display" id="result-box">
<div class="result-formula">
2<sup>{{selected2}}</sup> × 3<sup>{{selected3}}</sup> = {{ currentResult }}
</div>
<div class="result-desc">
这是 72 的一个因数
</div>
</div>
<div class="total-count">
总搭配数 = 4 × 3 = 12 种
</div>
</div>
<div class="card" style="margin-top: 15px;">
<div class="tag tag-orange">原理解析</div>
<ul class="step-list">
<li><b>2的指数是3:</b>可以选0个,1个,2个,3个,共 <b>3+1=4</b> 种选法。</li>
<li><b>3的指数是2:</b>可以选0个,1个,2个,共 <b>2+1=3</b> 种选法。</li>
<li><b>分步相乘:</b>4 × 3 = 12,这就是公式的由来!</li>
</ul>
</div>
</div>
<div v-show="currentPage === 3" class="page-container">
<div class="section-title">🧠 难点:为什么“都不选”是1?</div>
<div class="card">
<div style="font-weight: bold; margin-bottom: 10px;">直觉误区纠正</div>
<p style="font-size: 14px; color: #475569;">
很多同学觉得“选0个”应该是0。但在乘法世界里,<b>起点不是0,而是1</b>。
</p>
<div class="plate-demo">
<div class="plate">
<span v-if="showPlateContent" style="color: #2563EB; font-size: 20px;">1</span>
<span v-else>空盘子</span>
</div>
</div>
<button class="speak-btn" @click="togglePlate" style="width:100%; justify-content:center;">
{{ showPlateContent ? '还原为空' : '揭示真相' }}
</button>
<p style="font-size: 13px; color: #64748B; margin-top: 10px; text-align: center;">
点击按钮查看盘子里的秘密
</p>
</div>
<div class="card">
<div class="tag tag-blue">数学原理</div>
<ul class="step-list">
<li><b>选0个 = 不乘:</b>数学上“不乘以任何数”等于“乘以1”(保持原样)。</li>
<li><b>计算验证:</b><br>
2选0个 → 1<br>
3选0个 → 1<br>
结果:1 × 1 = 1。
</li>
<li><b>结论:</b>1 也是 72 的因数,必须算进去!</li>
</ul>
</div>
</div>
<div v-show="currentPage === 4" class="page-container" style="height: 100%;">
<div v-if="!basicDone" class="quiz-container">
<div class="question-card">
<div class="tag tag-blue">基础 {{ currentBasicIndex + 1 }}/10</div>
<div style="font-size: 18px; font-weight: bold; margin-bottom: 20px;">{{ basicQuestions[currentBasicIndex].text }}</div>
<div v-for="(opt, idx) in basicQuestions[currentBasicIndex].options"
:key="idx"
class="option-btn"
:class="{
'correct': basicAnswered && opt.correct,
'wrong': basicAnswered && selectedBasicOpt === idx && !opt.correct
}"
@click="handleBasicAnswer(idx, opt.correct)">
{{ opt.text }}
</div>
<div v-if="basicAnswered" style="margin-top: 15px; padding: 10px; background: #F1F5F9; border-radius: 8px; font-size: 13px;">
<div v-if="isBasicCorrect" style="color: #10B981; font-weight: bold;">🎉 正确!</div>
<div v-else style="color: #EF4444; font-weight: bold;">💡 解析:</div>
<div style="margin-top: 5px;" v-html="basicQuestions[currentBasicIndex].expl"></div>
</div>
<button v-if="basicAnswered" class="next-btn" @click="nextBasic">
{{ currentBasicIndex < 9 ? '下一题 →' : '完成练习' }}
</button>
</div>
</div>
<div v-else class="card" style="height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;">
<div style="font-size: 60px;">🏆</div>
<h2>基础训练完成</h2>
<button class="next-btn" @click="switchPage(5)">进阶挑战奥数题 →</button>
</div>
</div>
<div v-show="currentPage === 5" class="page-container" style="height: 100%;">
<div v-if="!olympiadDone" class="quiz-container">
<div class="question-card" style="border: 2px solid #F59E0B;">
<div class="tag tag-purple">🏆 杯赛真题 {{ currentOlympiadIndex + 1 }}/10</div>
<div style="font-size: 18px; font-weight: bold; margin-bottom: 20px;">{{ olympiadQuestions[currentOlympiadIndex].text }}</div>
<div v-for="(opt, idx) in olympiadQuestions[currentOlympiadIndex].options"
:key="idx"
class="option-btn"
:class="{
'correct': olympiadAnswered && opt.correct,
'wrong': olympiadAnswered && selectedOlympiadOpt === idx && !opt.correct
}"
@click="handleOlympiadAnswer(idx, opt.correct)">
{{ opt.text }}
</div>
<div v-if="olympiadAnswered" style="margin-top: 15px; padding: 10px; background: #FFFBEB; border-radius: 8px; font-size: 13px;">
<strong>深度解析:</strong><br>
<span v-html="olympiadQuestions[currentOlympiadIndex].expl"></span>
</div>
<button v-if="olympiadAnswered" class="next-btn" style="background: #D97706;" @click="nextOlympiad">
{{ currentOlympiadIndex < 9 ? '下一题 →' : '查看总结' }}
</button>
</div>
</div>
<div v-else class="card" style="height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;">
<div style="font-size: 60px;">🥇</div>
<h2>奥数挑战通关</h2>
<p>得分: {{ olympiadScore }}/100</p>
<button class="next-btn" @click="switchPage(6)">查看知识点总结 →</button>
</div>
</div>
<div v-show="currentPage === 6" class="secret-scroll">
<div class="secret-card">
<div class="secret-icon">📜</div>
<div class="secret-title">公式回顾</div>
<div class="secret-content">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 10px;">因数个数 = </div>
<div style="font-size: 20px; font-weight: bold;">(指数+1) 的连乘积</div>
</div>
</div>
<div class="secret-card green">
<div class="secret-icon">⚠️</div>
<div class="secret-title">注意事项</div>
<div class="secret-content" style="text-align: left;">
<ul style="margin:0; padding-left:20px;">
<li style="margin-bottom:8px;">必须先<b>分解质因数</b>,底数必须是质数。</li>
<li style="margin-bottom:8px;">不要忘了<b>+1</b>(代表选0个的情况)。</li>
<li>乘法世界的起点是 <b>1</b>,不是 0。</li>
</ul>
</div>
</div>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item" :class="{active: currentPage === 1}" @click="switchPage(1)">
<div class="nav-icon">⚡</div>
<div class="nav-label">公式</div>
</div>
<div class="nav-item" :class="{active: currentPage === 2}" @click="switchPage(2)">
<div class="nav-icon">🎬</div>
<div class="nav-label">演示</div>
</div>
<div class="nav-item" :class="{active: currentPage === 3}" @click="switchPage(3)">
<div class="nav-icon">🧠</div>
<div class="nav-label">难点</div>
</div>
<div class="nav-item" :class="{active: currentPage === 4}" @click="switchPage(4)">
<div class="nav-icon">✏️</div>
<div class="nav-label">练习</div>
</div>
<div class="nav-item" :class="{active: currentPage === 5}" @click="switchPage(5)">
<div class="nav-icon">🏆</div>
<div class="nav-label">奥数</div>
</div>
<div class="nav-item" :class="{active: currentPage === 6}" @click="switchPage(6)">
<div class="nav-icon">📚</div>
<div class="nav-label">总结</div>
</div>
</div>
</div>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/vue.global.prod.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/gsap.min.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/confetti.browser.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
// 演示状态
selected2: 0,
selected3: 0,
showPlateContent: false,
// 练习数据 (Page 4)
currentBasicIndex: 0,
basicScore: 0,
basicAnswered: false,
isBasicCorrect: false,
selectedBasicOpt: null,
basicDone: false,
basicQuestions: [
{ text: '求 100 的因数个数?(100=10^2=2^2×5^2)', options: [{text:'9个',correct:true}, {text:'4个',correct:false}, {text:'6个',correct:false}], expl: '(2+1)×(2+1) = 3×3 = 9。' },
{ text: '求 72 的因数个数?(72=2^3×3^2)', options: [{text:'12个',correct:true}, {text:'6个',correct:false}, {text:'8个',correct:false}], expl: '(3+1)×(2+1) = 4×3 = 12。' },
{ text: '求 200 的因数个数?(200=2^3×5^2)', options: [{text:'12个',correct:true}, {text:'10个',correct:false}, {text:'15个',correct:false}], expl: '(3+1)×(2+1) = 12。' },
{ text: '求 2^5 × 7 的因数个数?', options: [{text:'12个',correct:true}, {text:'35个',correct:false}, {text:'6个',correct:false}], expl: '7是7^1。个数=(5+1)×(1+1) = 6×2 = 12。' },
{ text: '求 12^2 的因数个数?', options: [{text:'15个',correct:true}, {text:'6个',correct:false}, {text:'9个',correct:false}], expl: '12^2 = (2^2×3)^2 = 2^4×3^2。个数=5×3=15。' },
{ text: '求 540 的因数个数?(540=2^2×3^3×5)', options: [{text:'24个',correct:true}, {text:'18个',correct:false}, {text:'12个',correct:false}], expl: '(2+1)×(3+1)×(1+1) = 3×4×2 = 24。' },
{ text: 'N=2^4×3^2,求N因数个数?', options: [{text:'15个',correct:true}, {text:'8个',correct:false}, {text:'14个',correct:false}], expl: '5×3=15。' },
{ text: '质数 19 有几个因数?', options: [{text:'2个',correct:true}, {text:'1个',correct:false}, {text:'3个',correct:false}], expl: '质数只有1和它本身,共2个。公式:1+1=2。' },
{ text: '求 1000 的因数个数?(1000=10^3=2^3×5^3)', options: [{text:'16个',correct:true}, {text:'9个',correct:false}, {text:'12个',correct:false}], expl: '(3+1)×(3+1)=16。' },
{ text: '判断:45的因数比50的因数多?', options: [{text:'错误(一样多)',correct:true}, {text:'正确',correct:false}], expl: '45=3^2×5 (6个), 50=2×5^2 (6个)。一样多。' }
],
// 奥数题 (Page 5)
currentOlympiadIndex: 0,
olympiadScore: 0,
olympiadAnswered: false,
selectedOlympiadOpt: null,
olympiadDone: false,
olympiadQuestions: [
{ text: '求 2016 的因数个数?(2016=2^5×3^2×7)', options: [{text:'36个',correct:true}, {text:'30个',correct:false}], expl: '(5+1)×(2+1)×(1+1) = 6×3×2 = 36。' },
{ text: '一个数只有2个因数,且在10到20之间,它是?', options: [{text:'11,13,17,19',correct:true}, {text:'12,15,18',correct:false}], expl: '只有2个因数说明是质数。' },
{ text: 'A=2^3×5^2×7,求A的因数个数?', options: [{text:'24个',correct:true}, {text:'12个',correct:false}], expl: '(3+1)×(2+1)×(1+1) = 24。' },
{ text: '恰好有3个因数的最小三位数是?', options: [{text:'121',correct:true}, {text:'100',correct:false}], expl: '必须是质数平方。100=10^2(10非质)。11^2=121(11是质)。' },
{ text: '求 360 × 45 的因数个数?', options: [{text:'60个',correct:true}, {text:'48个',correct:false}], expl: '360=2^3×3^2×5, 45=3^2×5。积=2^3×3^4×5^2。个数=4×5×3=60。' },
{ text: '某数最小因数1,最大24,它一共有几个因数?', options: [{text:'8个',correct:true}, {text:'6个',correct:false}], expl: '这数就是24。24=2^3×3。个数=4×2=8。' },
{ text: 'N=2^a×3^2 有12个因数,N是多少?', options: [{text:'72',correct:true}, {text:'36',correct:false}], expl: '3^2提供3个。总12个,则2^a需提供4个,即a=3。N=2^3×3^2=72。' },
{ text: '10! 分解后2的指数是多少?', options: [{text:'8',correct:true}, {text:'7',correct:false}], expl: '10÷2=5, 5÷2=2, 2÷2=1。5+2+1=8。' },
{ text: '100盏灯拉100次,最后亮着的是?', options: [{text:'完全平方数',correct:true}, {text:'质数',correct:false}], expl: '因数个数为奇数的灯最后亮。只有完全平方数因数是奇数个。' },
{ text: '最小的具有6个因数的数是?', options: [{text:'12',correct:true}, {text:'18',correct:false}], expl: '6=6或2×3。2^5=32; 2^2×3^1=12。最小12。' }
]
}
},
computed: {
currentResult() {
return Math.pow(2, this.selected2) * Math.pow(3, this.selected3);
}
},
methods: {
speak(text) {
if (window.speechSynthesis) window.speechSynthesis.cancel();
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
let audio = document.getElementById('tts-audio');
if (!audio) {
audio = document.createElement('audio'); audio.id = 'tts-audio'; audio.style.display = 'none';
document.body.appendChild(audio);
}
const url = `https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(e => { if(window.WeixinJSBridge) window.WeixinJSBridge.invoke('getNetworkType',{},()=>audio.play()); });
} else {
if (window.speechSynthesis) {
const u = new SpeechSynthesisUtterance(text); u.lang = 'zh-CN'; u.rate = 0.9;
window.speechSynthesis.speak(u);
}
}
},
speakIntro() {
this.speak("找因数就像点菜。对于每一个质因数,你都有选或不选的权利。指数加一,就是加上不选的情况。");
},
switchPage(page) {
if(window.speechSynthesis) window.speechSynthesis.cancel();
const audio = document.getElementById('tts-audio');
if(audio) audio.pause();
this.currentPage = page;
window.scrollTo(0,0);
},
// 演示逻辑
select2(n) { this.selected2 = n; this.animResult(); },
select3(n) { this.selected3 = n; this.animResult(); },
animResult() { if(typeof gsap !== 'undefined') gsap.fromTo("#result-box", {scale: 0.9}, {scale: 1, duration: 0.3, ease: "back.out"}); },
togglePlate() {
this.showPlateContent = !this.showPlateContent;
if(this.showPlateContent) this.speak("空盘子其实有一个底座,就是数字1。");
},
// 练习逻辑
handleBasicAnswer(i, c) {
if(this.basicAnswered) return;
this.basicAnswered = true; this.isBasicCorrect = c; this.selectedBasicOpt = i;
if(c) { this.basicScore += 10; if(typeof confetti !== 'undefined') confetti({particleCount: 100, spread: 70, origin: {y: 0.6}});}
},
nextBasic() { if(this.currentBasicIndex<9){this.currentBasicIndex++; this.basicAnswered=false; this.selectedBasicOpt=null;}else{this.basicDone=true;} },
handleOlympiadAnswer(i, c) {
if(this.olympiadAnswered) return;
this.olympiadAnswered = true; this.selectedOlympiadOpt = i;
if(c) { this.olympiadScore += 10; if(typeof confetti !== 'undefined') confetti({particleCount: 150, spread: 90, colors: ['#F59E0B']});}
},
nextOlympiad() { if(this.currentOlympiadIndex<9){this.currentOlympiadIndex++; this.olympiadAnswered=false; this.selectedOlympiadOpt=null;}else{this.olympiadDone=true;} }
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码