把大致框架搭好1
This commit is contained in:
190
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css
Normal file
190
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css
Normal file
@@ -0,0 +1,190 @@
|
||||
/* 背景样式文件 */
|
||||
|
||||
/* 主体背景 */
|
||||
body {
|
||||
background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 50%, #a5d6a7 100%);
|
||||
background-attachment: fixed;
|
||||
background-size: 400% 400%;
|
||||
animation: gradientShift 15s ease infinite;
|
||||
}
|
||||
|
||||
/* 背景动画 */
|
||||
@keyframes gradientShift {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 装饰性背景元素 */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 20%, rgba(129, 199, 132, 0.1) 0%, transparent 50%),
|
||||
radial-gradient(circle at 40% 40%, rgba(165, 214, 167, 0.08) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* 浮动装饰圆点 */
|
||||
body::after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent),
|
||||
radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent),
|
||||
radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent),
|
||||
radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent),
|
||||
radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent);
|
||||
background-repeat: repeat;
|
||||
background-size: 200px 100px;
|
||||
animation: float 20s linear infinite;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
/* 题目容器背景增强 */
|
||||
.question-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(26, 77, 26, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* 错误容器背景 */
|
||||
.error-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 结果容器背景 */
|
||||
.result-container {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
/* 代码块背景 */
|
||||
.code-block {
|
||||
background: rgba(248, 249, 250, 0.9);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
/* 选项背景 */
|
||||
.option {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: rgba(76, 175, 80, 0.05);
|
||||
}
|
||||
|
||||
.option.selected {
|
||||
background: linear-gradient(135deg, rgba(76, 175, 80, 0.15), rgba(76, 175, 80, 0.08));
|
||||
}
|
||||
|
||||
/* 按钮背景增强 */
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #4caf50, #45a049);
|
||||
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2);
|
||||
}
|
||||
|
||||
.show-answer-btn {
|
||||
background: linear-gradient(135deg, #2196f3, #1976d2);
|
||||
box-shadow: 0 4px 15px rgba(33, 150, 243, 0.2);
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
background: linear-gradient(135deg, #ff9800, #f57c00);
|
||||
box-shadow: 0 4px 15px rgba(255, 152, 0, 0.2);
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: linear-gradient(135deg, #4caf50, #45a049);
|
||||
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2);
|
||||
}
|
||||
|
||||
/* 移动端背景优化 */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
body::after {
|
||||
opacity: 0.4;
|
||||
background-size: 150px 75px;
|
||||
}
|
||||
|
||||
.question-container {
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
}
|
||||
}
|
||||
|
||||
/* 高对比度模式支持 */
|
||||
@media (prefers-contrast: high) {
|
||||
body {
|
||||
background: #f0f8f0;
|
||||
}
|
||||
|
||||
body::before,
|
||||
body::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.question-container {
|
||||
background: #ffffff;
|
||||
border: 2px solid #4caf50;
|
||||
}
|
||||
}
|
||||
|
||||
/* 减少动画模式支持 */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
body {
|
||||
animation: none;
|
||||
background: #e8f5e8;
|
||||
}
|
||||
|
||||
body::after {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.refresh-btn:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
597
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css
Normal file
597
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css
Normal file
@@ -0,0 +1,597 @@
|
||||
/* 基础样式重置 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #2d5a27;
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 容器布局 */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5rem;
|
||||
color: #1a4d1a;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 2px 4px rgba(26, 77, 26, 0.1);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 1.1rem;
|
||||
color: #4a7c59;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* 主内容区域 */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 4px solid #e8f5e8;
|
||||
border-top: 4px solid #4caf50;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading p {
|
||||
color: #4a7c59;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* 题目容器 */
|
||||
.question-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 10px 30px rgba(26, 77, 26, 0.1);
|
||||
border: 2px solid rgba(76, 175, 80, 0.2);
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 题目头部 */
|
||||
.question-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 2px solid #e8f5e8;
|
||||
}
|
||||
|
||||
.question-id {
|
||||
font-size: 1.1rem;
|
||||
color: #4caf50;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(135deg, #e8f5e8, #c8e6c9);
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: linear-gradient(135deg, #4caf50, #45a049);
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.refresh-btn:hover {
|
||||
transform: rotate(180deg) scale(1.1);
|
||||
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
/* 题目文本 */
|
||||
.question-text h2 {
|
||||
font-size: 1.5rem;
|
||||
color: #1a4d1a;
|
||||
margin-bottom: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 代码块 */
|
||||
.code-block {
|
||||
background: #f8f9fa;
|
||||
border: 2px solid #e8f5e8;
|
||||
border-radius: 12px;
|
||||
margin: 25px 0;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.code-block pre {
|
||||
margin: 0;
|
||||
padding: 25px;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
color: #2d5a27;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.code-block code {
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* 代码高亮自定义样式 - 丰富的语法高亮 */
|
||||
.code-block .hljs {
|
||||
background: transparent !important;
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
/* JavaScript 关键字 - 蓝色 */
|
||||
.code-block .hljs-keyword {
|
||||
color: #0066cc !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 字符串 - 绿色 */
|
||||
.code-block .hljs-string {
|
||||
color: #22aa22 !important;
|
||||
}
|
||||
|
||||
/* 数字 - 橙色 */
|
||||
.code-block .hljs-number {
|
||||
color: #ff6600 !important;
|
||||
}
|
||||
|
||||
/* 函数名 - 紫色 */
|
||||
.code-block .hljs-function,
|
||||
.code-block .hljs-title.function_ {
|
||||
color: #9933cc !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 变量名 - 深蓝色 */
|
||||
.code-block .hljs-variable,
|
||||
.code-block .hljs-name {
|
||||
color: #0066aa !important;
|
||||
}
|
||||
|
||||
/* 注释 - 灰色 */
|
||||
.code-block .hljs-comment {
|
||||
color: #888888 !important;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* 内置对象和方法 - 深紫色 */
|
||||
.code-block .hljs-built_in {
|
||||
color: #663399 !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 字面量 (true, false, null) - 红色 */
|
||||
.code-block .hljs-literal {
|
||||
color: #cc0000 !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 操作符 - 深灰色 */
|
||||
.code-block .hljs-operator {
|
||||
color: #666666 !important;
|
||||
}
|
||||
|
||||
/* 标点符号 - 深灰色 */
|
||||
.code-block .hljs-punctuation {
|
||||
color: #666666 !important;
|
||||
}
|
||||
|
||||
/* 属性名 - 深蓝色 */
|
||||
.code-block .hljs-property,
|
||||
.code-block .hljs-attr {
|
||||
color: #0066aa !important;
|
||||
}
|
||||
|
||||
/* 类名和构造函数 - 深绿色 */
|
||||
.code-block .hljs-title.class_,
|
||||
.code-block .hljs-title {
|
||||
color: #228833 !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 参数 - 深蓝色 */
|
||||
.code-block .hljs-params {
|
||||
color: #0066aa !important;
|
||||
}
|
||||
|
||||
/* 正则表达式 - 深红色 */
|
||||
.code-block .hljs-regexp {
|
||||
color: #aa0066 !important;
|
||||
}
|
||||
|
||||
/* 模板字符串 - 深绿色 */
|
||||
.code-block .hljs-template-variable,
|
||||
.code-block .hljs-template-tag {
|
||||
color: #228833 !important;
|
||||
}
|
||||
|
||||
/* 选项容器 */
|
||||
.options-container {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.option {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border: 2px solid #e8f5e8;
|
||||
border-radius: 12px;
|
||||
padding: 15px 20px;
|
||||
margin: 12px 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
border-color: #4caf50;
|
||||
background: rgba(76, 175, 80, 0.05);
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.option.selected {
|
||||
border-color: #4caf50;
|
||||
background: linear-gradient(135deg, rgba(76, 175, 80, 0.1), rgba(76, 175, 80, 0.05));
|
||||
color: #1a4d1a;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.option.correct {
|
||||
border-color: #4caf50;
|
||||
background: linear-gradient(135deg, rgba(76, 175, 80, 0.2), rgba(76, 175, 80, 0.1));
|
||||
color: #1a4d1a;
|
||||
}
|
||||
|
||||
.option.incorrect {
|
||||
border-color: #f44336;
|
||||
background: linear-gradient(135deg, rgba(244, 67, 54, 0.1), rgba(244, 67, 54, 0.05));
|
||||
color: #c62828;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin: 30px 0;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.submit-btn, .show-answer-btn, .retry-btn, .export-btn {
|
||||
padding: 12px 30px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
min-width: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #4caf50, #45a049);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit-btn:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.submit-btn:disabled {
|
||||
background: #cccccc;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.show-answer-btn {
|
||||
background: linear-gradient(135deg, #2196f3, #1976d2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.show-answer-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(33, 150, 243, 0.3);
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
background: linear-gradient(135deg, #ff9800, #f57c00);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.retry-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(255, 152, 0, 0.3);
|
||||
}
|
||||
|
||||
.export-btn {
|
||||
background: linear-gradient(135deg, #9c27b0, #7b1fa2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.export-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(156, 39, 176, 0.3);
|
||||
}
|
||||
|
||||
.export-btn svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* 结果容器 */
|
||||
.result-container {
|
||||
margin-top: 30px;
|
||||
padding: 25px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 15px;
|
||||
border: 2px solid #e8f5e8;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #e8f5e8;
|
||||
}
|
||||
|
||||
.result-status {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.result-status.correct {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.result-status.incorrect {
|
||||
color: #f44336;
|
||||
}
|
||||
|
||||
.correct-answer {
|
||||
font-weight: 600;
|
||||
color: #4caf50;
|
||||
background: rgba(76, 175, 80, 0.1);
|
||||
padding: 5px 12px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.explanation {
|
||||
color: #2d5a27;
|
||||
line-height: 1.7;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.explanation pre {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e8f5e8;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
overflow-x: auto;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
}
|
||||
|
||||
/* 错误容器 */
|
||||
.error-container {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20px;
|
||||
border: 2px solid rgba(244, 67, 54, 0.2);
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.error-container h3 {
|
||||
color: #f44336;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.error-container p {
|
||||
color: #666;
|
||||
margin-bottom: 25px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* 底部 */
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 30px 0;
|
||||
margin-top: 40px;
|
||||
color: #4a7c59;
|
||||
opacity: 0.7;
|
||||
border-top: 1px solid rgba(76, 175, 80, 0.2);
|
||||
}
|
||||
|
||||
/* 平板端适配 (768px - 1024px) */
|
||||
@media (max-width: 1024px) and (min-width: 768px) {
|
||||
.container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.question-container {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
/* 手机端适配 (最大768px) */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 25px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.question-container {
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.question-header {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.question-text h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.code-block pre {
|
||||
padding: 15px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.option {
|
||||
padding: 12px 15px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.submit-btn, .show-answer-btn, .retry-btn {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.explanation {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.explanation pre {
|
||||
padding: 10px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小屏手机适配 (最大480px) */
|
||||
@media (max-width: 480px) {
|
||||
.container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.question-container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.question-id {
|
||||
font-size: 1rem;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.code-block pre {
|
||||
font-size: 0.8rem;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.option {
|
||||
padding: 10px 12px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.submit-btn, .show-answer-btn, .retry-btn {
|
||||
padding: 10px 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
}
|
||||
89
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/index.html
Normal file
89
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/index.html
Normal file
@@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>随机JavaScript趣味题</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="css/background.css">
|
||||
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<h1>JavaScript趣味题</h1>
|
||||
<p class="subtitle">测试你的JavaScript知识</p>
|
||||
</header>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="loading" id="loading">
|
||||
<div class="spinner"></div>
|
||||
<p>正在加载题目...</p>
|
||||
</div>
|
||||
|
||||
<div class="question-container" id="questionContainer" style="display: none;">
|
||||
<div class="question-header">
|
||||
<span class="question-id" id="questionId">题目 #1</span>
|
||||
<button class="refresh-btn" id="refreshBtn" title="获取新题目">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="23 4 23 10 17 10"></polyline>
|
||||
<polyline points="1 20 1 14 7 14"></polyline>
|
||||
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="question-text" id="questionText">
|
||||
<h2>输出是什么?</h2>
|
||||
</div>
|
||||
|
||||
<div class="code-block" id="codeBlock">
|
||||
<pre><code id="codeContent" class="language-javascript"></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="options-container" id="optionsContainer">
|
||||
<!-- 选项将通过JavaScript动态生成 -->
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="submit-btn" id="submitBtn" disabled>提交答案</button>
|
||||
<button class="show-answer-btn" id="showAnswerBtn">查看答案</button>
|
||||
<button class="export-btn" id="exportBtn" title="导出为Markdown文件">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
||||
<polyline points="7 10 12 15 17 10"></polyline>
|
||||
<line x1="12" y1="15" x2="12" y2="3"></line>
|
||||
</svg>
|
||||
导出MD
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="result-container" id="resultContainer" style="display: none;">
|
||||
<div class="result-header">
|
||||
<span class="result-status" id="resultStatus"></span>
|
||||
<span class="correct-answer" id="correctAnswer"></span>
|
||||
</div>
|
||||
<div class="explanation" id="explanation">
|
||||
<!-- 解析内容 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="error-container" id="errorContainer" style="display: none;">
|
||||
<div class="error-icon">⚠️</div>
|
||||
<h3>加载失败</h3>
|
||||
<p id="errorMessage">网络连接异常,请稍后重试</p>
|
||||
<button class="retry-btn" id="retryBtn">重新加载</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<p>JavaScript趣味题集合</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
565
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js
Normal file
565
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js
Normal file
@@ -0,0 +1,565 @@
|
||||
// JavaScript趣味题应用
|
||||
class JSQuizApp {
|
||||
constructor() {
|
||||
this.apiEndpoints = [
|
||||
'https://60s-cf.viki.moe',
|
||||
'https://60s.viki.moe',
|
||||
'https://60s.b23.run',
|
||||
'https://60s.114128.xyz',
|
||||
'https://60s-cf.114128.xyz'
|
||||
];
|
||||
this.currentApiIndex = 0;
|
||||
this.currentQuestion = null;
|
||||
this.selectedOption = null;
|
||||
this.isAnswered = false;
|
||||
|
||||
this.initElements();
|
||||
this.bindEvents();
|
||||
this.loadQuestion();
|
||||
}
|
||||
|
||||
// 初始化DOM元素
|
||||
initElements() {
|
||||
this.elements = {
|
||||
loading: document.getElementById('loading'),
|
||||
questionContainer: document.getElementById('questionContainer'),
|
||||
errorContainer: document.getElementById('errorContainer'),
|
||||
questionId: document.getElementById('questionId'),
|
||||
questionText: document.getElementById('questionText'),
|
||||
codeContent: document.getElementById('codeContent'),
|
||||
optionsContainer: document.getElementById('optionsContainer'),
|
||||
submitBtn: document.getElementById('submitBtn'),
|
||||
showAnswerBtn: document.getElementById('showAnswerBtn'),
|
||||
refreshBtn: document.getElementById('refreshBtn'),
|
||||
retryBtn: document.getElementById('retryBtn'),
|
||||
exportBtn: document.getElementById('exportBtn'),
|
||||
resultContainer: document.getElementById('resultContainer'),
|
||||
resultStatus: document.getElementById('resultStatus'),
|
||||
correctAnswer: document.getElementById('correctAnswer'),
|
||||
explanation: document.getElementById('explanation'),
|
||||
errorMessage: document.getElementById('errorMessage')
|
||||
};
|
||||
}
|
||||
|
||||
// 绑定事件
|
||||
bindEvents() {
|
||||
this.elements.submitBtn.addEventListener('click', () => this.submitAnswer());
|
||||
this.elements.showAnswerBtn.addEventListener('click', () => this.showAnswer());
|
||||
this.elements.refreshBtn.addEventListener('click', () => this.loadQuestion());
|
||||
this.elements.retryBtn.addEventListener('click', () => this.loadQuestion());
|
||||
this.elements.exportBtn.addEventListener('click', () => this.exportToMarkdown());
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
showLoading() {
|
||||
this.elements.loading.style.display = 'block';
|
||||
this.elements.questionContainer.style.display = 'none';
|
||||
this.elements.errorContainer.style.display = 'none';
|
||||
}
|
||||
|
||||
// 显示题目
|
||||
showQuestion() {
|
||||
this.elements.loading.style.display = 'none';
|
||||
this.elements.questionContainer.style.display = 'block';
|
||||
this.elements.errorContainer.style.display = 'none';
|
||||
}
|
||||
|
||||
// 显示错误
|
||||
showError(message) {
|
||||
this.elements.loading.style.display = 'none';
|
||||
this.elements.questionContainer.style.display = 'none';
|
||||
this.elements.errorContainer.style.display = 'block';
|
||||
this.elements.errorMessage.textContent = message;
|
||||
}
|
||||
|
||||
// 获取当前API地址
|
||||
getCurrentApiUrl() {
|
||||
return `${this.apiEndpoints[this.currentApiIndex]}/v2/awesome-js`;
|
||||
}
|
||||
|
||||
// 切换到下一个API
|
||||
switchToNextApi() {
|
||||
this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length;
|
||||
}
|
||||
|
||||
// 加载题目
|
||||
async loadQuestion() {
|
||||
this.showLoading();
|
||||
this.resetQuestion();
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = this.apiEndpoints.length;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
try {
|
||||
const response = await fetch(this.getCurrentApiUrl(), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.code === 200 && data.data) {
|
||||
this.currentQuestion = data.data;
|
||||
this.displayQuestion();
|
||||
return;
|
||||
} else {
|
||||
throw new Error(data.message || '数据格式错误');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.warn(`API ${this.getCurrentApiUrl()} 请求失败:`, error.message);
|
||||
attempts++;
|
||||
|
||||
if (attempts < maxAttempts) {
|
||||
this.switchToNextApi();
|
||||
console.log(`切换到备用API: ${this.getCurrentApiUrl()}`);
|
||||
} else {
|
||||
this.showError(`所有API接口都无法访问,请检查网络连接后重试。\n最后尝试的错误: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置题目状态
|
||||
resetQuestion() {
|
||||
this.selectedOption = null;
|
||||
this.isAnswered = false;
|
||||
this.elements.resultContainer.style.display = 'none';
|
||||
this.elements.submitBtn.disabled = true;
|
||||
this.elements.submitBtn.textContent = '提交答案';
|
||||
this.elements.showAnswerBtn.style.display = 'inline-block';
|
||||
|
||||
// 清空选项容器,防止重复显示
|
||||
this.elements.optionsContainer.innerHTML = '';
|
||||
|
||||
// 移除所有选项的事件监听器
|
||||
const existingOptions = document.querySelectorAll('.option');
|
||||
existingOptions.forEach(option => {
|
||||
option.removeEventListener('click', this.selectOption);
|
||||
});
|
||||
}
|
||||
|
||||
// 显示题目内容
|
||||
displayQuestion() {
|
||||
const question = this.currentQuestion;
|
||||
|
||||
console.log('显示题目:', question);
|
||||
|
||||
// 设置题目ID
|
||||
this.elements.questionId.textContent = `题目 #${question.id}`;
|
||||
|
||||
// 设置题目文本
|
||||
this.elements.questionText.innerHTML = `<h2>${this.escapeHtml(question.question)}</h2>`;
|
||||
|
||||
// 设置代码内容并应用语法高亮
|
||||
this.elements.codeContent.textContent = question.code;
|
||||
|
||||
// 应用语法高亮
|
||||
if (typeof hljs !== 'undefined') {
|
||||
hljs.highlightElement(this.elements.codeContent);
|
||||
}
|
||||
|
||||
// 确保选项容器已清空
|
||||
this.elements.optionsContainer.innerHTML = '';
|
||||
|
||||
// 生成选项
|
||||
this.generateOptions(question.options);
|
||||
|
||||
this.showQuestion();
|
||||
}
|
||||
|
||||
// 生成选项
|
||||
generateOptions(options) {
|
||||
// 确保清空容器
|
||||
this.elements.optionsContainer.innerHTML = '';
|
||||
|
||||
// 验证选项数据
|
||||
if (!Array.isArray(options) || options.length === 0) {
|
||||
console.error('选项数据无效:', options);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除可能存在的重复选项
|
||||
const uniqueOptions = [...new Set(options)];
|
||||
|
||||
uniqueOptions.forEach((option, index) => {
|
||||
const optionElement = document.createElement('div');
|
||||
optionElement.className = 'option';
|
||||
optionElement.textContent = option;
|
||||
optionElement.dataset.index = index;
|
||||
optionElement.dataset.value = option.charAt(0); // A, B, C, D
|
||||
|
||||
optionElement.addEventListener('click', () => this.selectOption(optionElement));
|
||||
|
||||
this.elements.optionsContainer.appendChild(optionElement);
|
||||
});
|
||||
|
||||
console.log('生成选项:', uniqueOptions);
|
||||
}
|
||||
|
||||
// 选择选项
|
||||
selectOption(optionElement) {
|
||||
if (this.isAnswered) return;
|
||||
|
||||
// 移除之前的选中状态
|
||||
document.querySelectorAll('.option.selected').forEach(el => {
|
||||
el.classList.remove('selected');
|
||||
});
|
||||
|
||||
// 设置当前选中
|
||||
optionElement.classList.add('selected');
|
||||
this.selectedOption = optionElement.dataset.value;
|
||||
|
||||
// 启用提交按钮
|
||||
this.elements.submitBtn.disabled = false;
|
||||
}
|
||||
|
||||
// 提交答案
|
||||
submitAnswer() {
|
||||
if (!this.selectedOption || this.isAnswered) return;
|
||||
|
||||
this.isAnswered = true;
|
||||
this.elements.submitBtn.disabled = true;
|
||||
this.elements.submitBtn.textContent = '已提交';
|
||||
this.elements.showAnswerBtn.style.display = 'none';
|
||||
|
||||
const isCorrect = this.selectedOption === this.currentQuestion.answer;
|
||||
|
||||
// 显示结果
|
||||
this.showResult(isCorrect);
|
||||
|
||||
// 标记选项
|
||||
this.markOptions();
|
||||
}
|
||||
|
||||
// 显示答案
|
||||
showAnswer() {
|
||||
this.isAnswered = true;
|
||||
this.elements.submitBtn.disabled = true;
|
||||
this.elements.submitBtn.textContent = '已显示答案';
|
||||
this.elements.showAnswerBtn.style.display = 'none';
|
||||
|
||||
// 显示结果(不判断对错)
|
||||
this.showResult(null);
|
||||
|
||||
// 标记正确答案
|
||||
this.markCorrectAnswer();
|
||||
}
|
||||
|
||||
// 显示结果
|
||||
showResult(isCorrect) {
|
||||
const resultContainer = this.elements.resultContainer;
|
||||
const resultStatus = this.elements.resultStatus;
|
||||
const correctAnswer = this.elements.correctAnswer;
|
||||
const explanation = this.elements.explanation;
|
||||
|
||||
// 设置结果状态
|
||||
if (isCorrect === true) {
|
||||
resultStatus.textContent = '✅ 回答正确!';
|
||||
resultStatus.className = 'result-status correct';
|
||||
} else if (isCorrect === false) {
|
||||
resultStatus.textContent = '❌ 回答错误';
|
||||
resultStatus.className = 'result-status incorrect';
|
||||
} else {
|
||||
resultStatus.textContent = '💡 答案解析';
|
||||
resultStatus.className = 'result-status';
|
||||
}
|
||||
|
||||
// 设置正确答案
|
||||
correctAnswer.textContent = `正确答案: ${this.currentQuestion.answer}`;
|
||||
|
||||
// 设置解析内容
|
||||
explanation.innerHTML = this.formatExplanation(this.currentQuestion.explanation);
|
||||
|
||||
// 显示结果容器
|
||||
resultContainer.style.display = 'block';
|
||||
|
||||
// 滚动到结果区域
|
||||
setTimeout(() => {
|
||||
resultContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 标记选项
|
||||
markOptions() {
|
||||
const options = document.querySelectorAll('.option');
|
||||
const correctAnswer = this.currentQuestion.answer;
|
||||
|
||||
options.forEach(option => {
|
||||
const optionValue = option.dataset.value;
|
||||
|
||||
if (optionValue === correctAnswer) {
|
||||
option.classList.add('correct');
|
||||
} else if (option.classList.contains('selected')) {
|
||||
option.classList.add('incorrect');
|
||||
}
|
||||
|
||||
// 禁用点击
|
||||
option.style.pointerEvents = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// 标记正确答案
|
||||
markCorrectAnswer() {
|
||||
const options = document.querySelectorAll('.option');
|
||||
const correctAnswer = this.currentQuestion.answer;
|
||||
|
||||
options.forEach(option => {
|
||||
const optionValue = option.dataset.value;
|
||||
|
||||
if (optionValue === correctAnswer) {
|
||||
option.classList.add('correct');
|
||||
}
|
||||
|
||||
// 禁用点击
|
||||
option.style.pointerEvents = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// 格式化解析内容
|
||||
formatExplanation(explanation) {
|
||||
// 转义HTML
|
||||
let formatted = this.escapeHtml(explanation);
|
||||
|
||||
// 处理代码块
|
||||
formatted = formatted.replace(/```js\n([\s\S]*?)\n```/g, '<pre><code>$1</code></pre>');
|
||||
formatted = formatted.replace(/```javascript\n([\s\S]*?)\n```/g, '<pre><code>$1</code></pre>');
|
||||
formatted = formatted.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
|
||||
|
||||
// 处理行内代码
|
||||
formatted = formatted.replace(/`([^`]+)`/g, '<code style="background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace;">$1</code>');
|
||||
|
||||
// 处理换行
|
||||
formatted = formatted.replace(/\n\n/g, '</p><p>');
|
||||
formatted = formatted.replace(/\n/g, '<br>');
|
||||
|
||||
// 包装段落
|
||||
if (!formatted.includes('<p>')) {
|
||||
formatted = '<p>' + formatted + '</p>';
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
// HTML转义
|
||||
escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// 导出为Markdown
|
||||
exportToMarkdown() {
|
||||
if (!this.currentQuestion) {
|
||||
alert('请先加载题目后再导出!');
|
||||
return;
|
||||
}
|
||||
|
||||
const question = this.currentQuestion;
|
||||
const timestamp = new Date().toLocaleString('zh-CN');
|
||||
|
||||
// 构建Markdown内容
|
||||
let markdown = `# JavaScript趣味题 #${question.id}\n\n`;
|
||||
markdown += `> 导出时间: ${timestamp}\n\n`;
|
||||
|
||||
// 题目部分
|
||||
markdown += `## 题目\n\n`;
|
||||
markdown += `${question.question}\n\n`;
|
||||
|
||||
// 代码部分
|
||||
markdown += `## 代码\n\n`;
|
||||
markdown += `\`\`\`javascript\n${question.code}\n\`\`\`\n\n`;
|
||||
|
||||
// 选项部分
|
||||
markdown += `## 选项\n\n`;
|
||||
question.options.forEach((option, index) => {
|
||||
const letter = String.fromCharCode(65 + index); // A, B, C, D
|
||||
const isCorrect = letter === question.answer;
|
||||
markdown += `${letter}. ${option}${isCorrect ? ' ✅' : ''}\n`;
|
||||
});
|
||||
markdown += `\n`;
|
||||
|
||||
// 答案部分
|
||||
markdown += `## 正确答案\n\n`;
|
||||
markdown += `**${question.answer}**\n\n`;
|
||||
|
||||
// 解析部分
|
||||
markdown += `## 答案解析\n\n`;
|
||||
// 清理解析内容中的HTML标签,转换为Markdown格式
|
||||
let explanation = question.explanation;
|
||||
explanation = explanation.replace(/<br\s*\/?>/gi, '\n');
|
||||
explanation = explanation.replace(/<p>/gi, '\n');
|
||||
explanation = explanation.replace(/<\/p>/gi, '\n');
|
||||
explanation = explanation.replace(/<code[^>]*>/gi, '`');
|
||||
explanation = explanation.replace(/<\/code>/gi, '`');
|
||||
explanation = explanation.replace(/<pre><code>/gi, '\n```javascript\n');
|
||||
explanation = explanation.replace(/<\/code><\/pre>/gi, '\n```\n');
|
||||
explanation = explanation.replace(/<[^>]*>/g, ''); // 移除其他HTML标签
|
||||
explanation = explanation.replace(/\n\s*\n/g, '\n\n'); // 清理多余空行
|
||||
markdown += explanation.trim() + '\n\n';
|
||||
|
||||
// 添加页脚
|
||||
markdown += `---\n\n`;
|
||||
markdown += `*本题目来源于JavaScript趣味题集合*\n`;
|
||||
markdown += `*导出工具: JavaScript趣味题网页版*\n`;
|
||||
|
||||
// 创建下载
|
||||
this.downloadMarkdown(markdown, `JavaScript趣味题_${question.id}_${new Date().getTime()}.md`);
|
||||
}
|
||||
|
||||
// 下载Markdown文件
|
||||
downloadMarkdown(content, filename) {
|
||||
const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
link.style.display = 'none';
|
||||
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// 清理URL对象
|
||||
setTimeout(() => {
|
||||
URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
|
||||
// 显示成功提示
|
||||
this.showExportSuccess(filename);
|
||||
}
|
||||
|
||||
// 显示导出成功提示
|
||||
showExportSuccess(filename) {
|
||||
// 创建临时提示元素
|
||||
const toast = document.createElement('div');
|
||||
toast.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background: linear-gradient(135deg, #4caf50, #45a049);
|
||||
color: white;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||||
z-index: 10000;
|
||||
font-size: 14px;
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
animation: slideInRight 0.3s ease-out;
|
||||
`;
|
||||
|
||||
toast.innerHTML = `
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="20 6 9 17 4 12"></polyline>
|
||||
</svg>
|
||||
<div>
|
||||
<div style="font-weight: 600;">导出成功!</div>
|
||||
<div style="font-size: 12px; opacity: 0.9; margin-top: 2px;">${filename}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 添加动画样式
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes slideOutRight {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
// 3秒后自动消失
|
||||
setTimeout(() => {
|
||||
toast.style.animation = 'slideOutRight 0.3s ease-in';
|
||||
setTimeout(() => {
|
||||
if (toast.parentNode) {
|
||||
document.body.removeChild(toast);
|
||||
}
|
||||
if (style.parentNode) {
|
||||
document.head.removeChild(style);
|
||||
}
|
||||
}, 300);
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化应用
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new JSQuizApp();
|
||||
});
|
||||
|
||||
// 添加键盘快捷键支持
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// 按R键刷新题目
|
||||
if (e.key.toLowerCase() === 'r' && !e.ctrlKey && !e.metaKey) {
|
||||
const refreshBtn = document.getElementById('refreshBtn');
|
||||
if (refreshBtn && !document.querySelector('.loading').style.display !== 'none') {
|
||||
refreshBtn.click();
|
||||
}
|
||||
}
|
||||
|
||||
// 按数字键1-4选择选项
|
||||
if (['1', '2', '3', '4'].includes(e.key)) {
|
||||
const options = document.querySelectorAll('.option');
|
||||
const index = parseInt(e.key) - 1;
|
||||
if (options[index] && !options[index].style.pointerEvents) {
|
||||
options[index].click();
|
||||
}
|
||||
}
|
||||
|
||||
// 按Enter键提交答案
|
||||
if (e.key === 'Enter') {
|
||||
const submitBtn = document.getElementById('submitBtn');
|
||||
if (submitBtn && !submitBtn.disabled) {
|
||||
submitBtn.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 添加触摸设备支持
|
||||
if ('ontouchstart' in window) {
|
||||
document.addEventListener('touchstart', () => {}, { passive: true });
|
||||
}
|
||||
|
||||
// 添加网络状态监听
|
||||
if ('navigator' in window && 'onLine' in navigator) {
|
||||
window.addEventListener('online', () => {
|
||||
console.log('网络连接已恢复');
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
console.log('网络连接已断开');
|
||||
});
|
||||
}
|
||||
7
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json
Normal file
7
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
"https://60s-cf.viki.moe",
|
||||
"https://60s.viki.moe",
|
||||
"https://60s.b23.run",
|
||||
"https://60s.114128.xyz",
|
||||
"https://60s-cf.114128.xyz"
|
||||
]
|
||||
17
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json
Normal file
17
frontend/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841",
|
||||
"data": {
|
||||
"id": 11,
|
||||
"question": "输出是什么?",
|
||||
"code": "function Person(firstName, lastName) {\n this.firstName = firstName;\n this.lastName = lastName;\n}\n\nconst member = new Person(\"Lydia\", \"Hallie\");\nPerson.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n\nconsole.log(member.getFullName());",
|
||||
"options": [
|
||||
"A: `TypeError`",
|
||||
"B: `SyntaxError`",
|
||||
"C: `Lydia Hallie`",
|
||||
"D: `undefined` `undefined`"
|
||||
],
|
||||
"answer": "A",
|
||||
"explanation": "你不能像常规对象那样,给构造函数添加属性。如果你想一次性给所有实例添加特性,你应该使用原型。因此本例中,使用如下方式:\n\n```js\nPerson.prototype.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n```\n\n这才会使 `member.getFullName()` 起作用。为什么这么做有益的?假设我们将这个方法添加到构造函数本身里。也许不是每个 `Person` 实例都需要这个方法。这将浪费大量内存空间,因为它们仍然具有该属性,这将占用每个实例的内存空间。相反,如果我们只将它添加到原型中,那么它只存在于内存中的一个位置,但是所有实例都可以访问它!"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user