初始提交
This commit is contained in:
531
rg-09112127/js/courseHomeStyle.js
Normal file
531
rg-09112127/js/courseHomeStyle.js
Normal file
@@ -0,0 +1,531 @@
|
||||
(function (win) {
|
||||
// 初始化样式和方法
|
||||
|
||||
console.log("courseHomeStyle init", win, win.location.href,);
|
||||
|
||||
if (win.location.href.indexOf("courseHome.html") !== -1) {
|
||||
// 1、导航条切换
|
||||
initNav();
|
||||
|
||||
// 2、左 侧边栏
|
||||
initSidebar();
|
||||
|
||||
// 3、按钮样式
|
||||
// 初始化增强的按钮效果
|
||||
initEnhancedButtonEffects();
|
||||
|
||||
// 简化问题文本动画
|
||||
simplifyQuestionAnimation();
|
||||
} else if (win.location.href.indexOf("courseHomeBarrierFree.html") !== -1) {
|
||||
// 1、导航条切换
|
||||
initNav();
|
||||
|
||||
// 2、左 侧边栏
|
||||
initSidebarBarrier();
|
||||
}
|
||||
|
||||
})(window);
|
||||
|
||||
// 1、导航条切换
|
||||
function initNav() {
|
||||
$(".container-header-nav > div").each(function (index) {
|
||||
$(this).on("click", function () {
|
||||
$(".container-header-nav > div").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
window.open(`./${$(this).data("url")}.html`);
|
||||
|
||||
// console.log("this", this, $(this));
|
||||
// $(".container-header-nav > div").eq(index).addClass("active");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 2、侧边栏
|
||||
function initSidebar() {
|
||||
if (
|
||||
window &&
|
||||
window.GLOBAL_CONFIG &&
|
||||
window.GLOBAL_CONFIG.courseList
|
||||
) {
|
||||
// 从路由获取当前课程信息 courseHome.html?id=l01
|
||||
const id = window.location.search.replace("?id=", "") || "m2x04";
|
||||
const type = {
|
||||
l: "live",
|
||||
c: "language",
|
||||
m: "math",
|
||||
}[id[0]];
|
||||
const courseList = window.GLOBAL_CONFIG.courseList[type];
|
||||
|
||||
const iconList = {
|
||||
"course": "📺",
|
||||
"video": "🤼♂️",
|
||||
"play": "🎮",
|
||||
};
|
||||
|
||||
// console.log("initSidebar", id, type, courseList);
|
||||
|
||||
$(".container-main-sidebar .directory-list").empty();
|
||||
let dom = `<ul class="directory-list">`;
|
||||
|
||||
courseList.map((grade, gradeI) => {
|
||||
grade.map((progress, progressI) => {
|
||||
dom = `${dom}
|
||||
<li class="grade-item">
|
||||
<div class="grade-title">
|
||||
<span>${gradeI + 1}年级 <span>${"上下"[progressI]}册</span></span>
|
||||
<span class="arrow">▶</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (progress) {
|
||||
dom = `${dom} <ul class="chapter-list">`;
|
||||
|
||||
progress.map((chapter, chapterI) => {
|
||||
|
||||
dom = `${dom}
|
||||
<li class="chapter-item">
|
||||
<div class="chapter-title" data-id="${chapter.id}" >
|
||||
<span>第${chapterI + 1}章 ${chapter.name}</span>
|
||||
<span class="arrow">▶</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (chapter.list) {
|
||||
dom = `${dom} <ul class="section-list">`;
|
||||
|
||||
chapter.list.map((section, sectionI) => {
|
||||
|
||||
if (sectionI == 0) {
|
||||
dom = `${dom}
|
||||
<div>- 课堂教学 -</div>
|
||||
`;
|
||||
}
|
||||
else if (
|
||||
sectionI > 0 &&
|
||||
chapter.list[sectionI - 1].type == "course" &&
|
||||
section.type == "video"
|
||||
) {
|
||||
dom = `${dom}
|
||||
<div>- 课堂互动 -</div>
|
||||
`;
|
||||
}
|
||||
else if (
|
||||
sectionI > 0 &&
|
||||
(chapter.list[sectionI - 1].type == "video" || sectionI == 1) &&
|
||||
section.type == "play"
|
||||
) {
|
||||
dom = `${dom}
|
||||
<div>- 趣味游戏 -</div>
|
||||
`;
|
||||
}
|
||||
|
||||
dom = `${dom}
|
||||
<li class="section-item">
|
||||
<div
|
||||
class="section-title"
|
||||
onclick="sectionClick(event)"
|
||||
data-info='${JSON.stringify(section)}'
|
||||
>
|
||||
<span>${iconList[section.type]}</span>
|
||||
${section.title}
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
});
|
||||
|
||||
dom = `${dom} </ul>`;
|
||||
};
|
||||
|
||||
dom = `${dom} </li>`;
|
||||
});
|
||||
|
||||
dom = `${dom} </ul>`;
|
||||
}
|
||||
|
||||
dom = `${dom} </li>`;
|
||||
})
|
||||
});
|
||||
|
||||
dom = `${dom} </ul>`;
|
||||
$(".container-main-sidebar .directory-list").append(dom);
|
||||
|
||||
initSidebarEvent();
|
||||
}
|
||||
}
|
||||
|
||||
// 2、侧边栏 无障碍版本
|
||||
function initSidebarBarrier() {
|
||||
if (
|
||||
window &&
|
||||
window.GLOBAL_CONFIG &&
|
||||
window.GLOBAL_CONFIG.playList
|
||||
) {
|
||||
let playList = window.GLOBAL_CONFIG.playList;
|
||||
|
||||
const typeName = {
|
||||
"live": "生活",
|
||||
"language": "语文",
|
||||
"math": "数学",
|
||||
};
|
||||
|
||||
$(".container-main-sidebar .directory-list").empty();
|
||||
let dom = `<ul class="directory-list">`;
|
||||
|
||||
Object.entries(playList).map((value, valueI) => {
|
||||
// console.log("initSidebarBarrier", value);
|
||||
|
||||
dom = `${dom}
|
||||
<div
|
||||
class="type-item"
|
||||
aria-label="${typeName[value[0]]}课程"
|
||||
onmouseenter="debouncedSpeechDomTextBarrier(event)"
|
||||
onmouseout="debouncedSpeechDomTextBarrier(event)"
|
||||
>
|
||||
- ${typeName[value[0]]} -
|
||||
</div>`;
|
||||
|
||||
value[1].map((play, playI) => {
|
||||
dom = `${dom}
|
||||
<li class="grade-item">
|
||||
<div
|
||||
class="grade-title"
|
||||
aria-label="${typeName[value[0]]}课程中的${play.title}游戏"
|
||||
onmouseenter="debouncedSpeechDomTextBarrierGame(event)"
|
||||
onmouseout="debouncedSpeechDomTextBarrierGame(event)"
|
||||
data-info='${JSON.stringify(play)}'
|
||||
>
|
||||
${play.title}
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
});
|
||||
});
|
||||
|
||||
dom = `${dom} </ul>`;
|
||||
$(".container-main-sidebar .directory-list").append(dom);
|
||||
|
||||
// 年级点击事件
|
||||
$(".container-main-sidebar .grade-title").click(function (event) {
|
||||
|
||||
// console.log(".container-main-sidebar .grade-title click", this, event);
|
||||
|
||||
if (
|
||||
event &&
|
||||
event.target &&
|
||||
event.target.dataset &&
|
||||
event.target.dataset.info
|
||||
) {
|
||||
const info = JSON.parse(event.target.dataset.info);
|
||||
let mainPlay = document.getElementById("mainPlay");
|
||||
mainPlay.src = info.url;
|
||||
}
|
||||
|
||||
// 移除所有active类
|
||||
$(".container-main-sidebar .grade-title").removeClass("active");
|
||||
|
||||
// 为当前点击的添加active类
|
||||
$(this).addClass("active");
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2、侧边栏 事件
|
||||
function initSidebarEvent() {
|
||||
// 年级点击事件
|
||||
$(".container-main-sidebar .grade-title").click(function () {
|
||||
$(this).parent().toggleClass("active");
|
||||
});
|
||||
|
||||
// 章节点击事件
|
||||
$(".container-main-sidebar .chapter-title").click(function (e) {
|
||||
e.stopPropagation(); // 阻止事件冒泡到年级标题
|
||||
$(this).parent().toggleClass("active");
|
||||
});
|
||||
|
||||
// 小节点击事件
|
||||
$(".container-main-sidebar .section-title").click(function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// 移除所有active类
|
||||
$(".container-main-sidebar .section-title").removeClass("active");
|
||||
|
||||
// 为当前点击的添加active类
|
||||
$(this).addClass("active");
|
||||
});
|
||||
|
||||
$(".container-main .sidebar-circle").click(function (e) {
|
||||
// 是否隐藏了
|
||||
const isShow = !$(".container-main-sidebar").hasClass("hidden");
|
||||
// console.log(".sidebar-circle", e, this, isShow);
|
||||
$(".container-main-sidebar").toggleClass("hidden");
|
||||
|
||||
if (isShow) {
|
||||
$(".container-main-sidebar").css("width", "0px");
|
||||
$(this).css("left", "0px");
|
||||
$(this).text("▶");
|
||||
$(".container-main-course").css("width", "100%");
|
||||
} else {
|
||||
$(".container-main-sidebar").css("width", "var(--sidebar-width)");
|
||||
$(this).css("left", "var(--sidebar-width)");
|
||||
$(this).text("◀");
|
||||
$(".container-main-course").css("width", "calc(100vw - var(--sidebar-width) - 30px)");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 控制功能按钮的展示隐藏 course-operation
|
||||
function showOperationDom() {
|
||||
$(".course-operation").toggleClass("show");
|
||||
}
|
||||
|
||||
// 初始化所有增强的按钮效果
|
||||
function initEnhancedButtonEffects() {
|
||||
// 首先解除所有现有的事件绑定,避免重复
|
||||
$('.box-btn-left, .box-btn-right').off();
|
||||
|
||||
// 按钮悬停基本效果
|
||||
$('.box-btn-left, .box-btn-right').hover(
|
||||
function () {
|
||||
const button = $(this);
|
||||
|
||||
// 添加文字缩放动画
|
||||
button.find('.btn-text').css({
|
||||
'animation': 'text-pop 0.8s ease infinite alternate'
|
||||
});
|
||||
|
||||
// 添加粒子效果
|
||||
addButtonParticles(button);
|
||||
|
||||
// 添加3D变换效果
|
||||
button.addClass('btn-hover-active');
|
||||
},
|
||||
function () {
|
||||
const button = $(this);
|
||||
|
||||
// 移除文字动画
|
||||
button.find('.btn-text').css({
|
||||
'animation': 'none'
|
||||
});
|
||||
|
||||
// 移除粒子
|
||||
removeButtonParticles();
|
||||
|
||||
// 移除3D效果
|
||||
button.removeClass('btn-hover-active');
|
||||
}
|
||||
);
|
||||
|
||||
// 添加3D移动效果
|
||||
$('.box-btn-left, .box-btn-right').on('mousemove', function (e) {
|
||||
const button = $(this);
|
||||
|
||||
// 只有在悬停状态才应用3D效果
|
||||
if (button.hasClass('btn-hover-active')) {
|
||||
const buttonRect = button[0].getBoundingClientRect();
|
||||
|
||||
// 计算鼠标在按钮上的相对位置 (-1 到 1 的范围)
|
||||
const x = ((e.clientX - buttonRect.left) / buttonRect.width) * 2 - 1;
|
||||
const y = ((e.clientY - buttonRect.top) / buttonRect.height) * 2 - 1;
|
||||
|
||||
// 根据鼠标位置应用3D旋转
|
||||
button.css({
|
||||
'transform': `translateY(-50%) scale(1.15) rotateX(${-y * 15}deg) rotateY(${x * 15}deg)`,
|
||||
'transition': 'transform 0.1s ease'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 鼠标离开时恢复原始状态
|
||||
$('.box-btn-left, .box-btn-right').on('mouseleave', function () {
|
||||
$(this).css({
|
||||
'transform': 'translateY(-50%)',
|
||||
'transition': 'transform 0.5s ease'
|
||||
});
|
||||
});
|
||||
|
||||
// 添加按钮动画样式
|
||||
addButtonAnimationStyles();
|
||||
}
|
||||
|
||||
// 简化问题文本动画
|
||||
function simplifyQuestionAnimation() {
|
||||
// DOMSubtreeModified MutationObserver
|
||||
$('.box-btn-question').on('MutationObserver', function () {
|
||||
const question = $(this);
|
||||
const text = question.text().trim();
|
||||
|
||||
if (text.length > 0 && !question.hasClass('animated-question')) {
|
||||
question.addClass('animated-question');
|
||||
question.css('opacity', '0');
|
||||
|
||||
setTimeout(function () {
|
||||
// 添加有趣的表情符号
|
||||
if (!text.includes('🤔')) {
|
||||
question.html('🤔 ' + text);
|
||||
}
|
||||
|
||||
question.css({
|
||||
'opacity': '1',
|
||||
'transform': 'translate(-50%, -65%) scale(1.1)',
|
||||
'transition': 'all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)'
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
question.css({
|
||||
'transform': 'translate(-50%, -50%) scale(1)',
|
||||
'transition': 'all 0.4s ease'
|
||||
});
|
||||
}, 500);
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加按钮动画样式
|
||||
function addButtonAnimationStyles() {
|
||||
// 移除现有的样式元素,避免重复
|
||||
$('#button-animation-styles').remove();
|
||||
|
||||
// 创建新的样式元素
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.id = 'button-animation-styles';
|
||||
styleElement.innerHTML = `
|
||||
@keyframes text-pop {
|
||||
0% { transform: scale(1); }
|
||||
100% { transform: scale(1.1); color: #ff6b6b; }
|
||||
}
|
||||
|
||||
@keyframes shadow-dance {
|
||||
0% { box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); }
|
||||
50% { box-shadow: 0 20px 45px rgba(74, 223, 218, 0.4); }
|
||||
100% { box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); }
|
||||
}
|
||||
|
||||
@keyframes particle-float {
|
||||
0% { transform: translate(-50%, -50%) translateY(0) rotate(0deg); opacity: 0.7; }
|
||||
100% { transform: translate(-50%, -50%) translateY(-50px) rotate(360deg); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes sparkle-float {
|
||||
0% { transform: scale(0); opacity: 0; }
|
||||
50% { transform: scale(1); opacity: 0.8; }
|
||||
100% { transform: scale(0); opacity: 0; }
|
||||
}
|
||||
|
||||
/* 按钮颜色变化动画 */
|
||||
@keyframes color-shift-left {
|
||||
0% { background: linear-gradient(145deg, #4adfda, #1bb5ad); }
|
||||
50% { background: linear-gradient(145deg, #ffa3b7, #ff6b93); }
|
||||
100% { background: linear-gradient(145deg, #a694ff, #7e64ff); }
|
||||
}
|
||||
|
||||
@keyframes color-shift-right {
|
||||
0% { background: linear-gradient(145deg, #9bea72, #5cc332); }
|
||||
50% { background: linear-gradient(145deg, #ffb347, #ffcc33); }
|
||||
100% { background: linear-gradient(145deg, #66a6ff, #3d7edb); }
|
||||
}
|
||||
|
||||
/* 应用颜色变化动画 */
|
||||
.box-btn-left.btn-hover-active {
|
||||
animation: border-dance 3s ease infinite, color-shift-left 6s infinite alternate !important;
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35) !important;
|
||||
}
|
||||
|
||||
.box-btn-right.btn-hover-active {
|
||||
animation: border-dance 3s ease infinite, color-shift-right 6s infinite alternate !important;
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35) !important;
|
||||
}
|
||||
|
||||
/* 3D文本效果 */
|
||||
.btn-text {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-hover-active .btn-text {
|
||||
text-shadow: 2px 2px 0 #ff6b93, 4px 4px 0 rgba(0, 0, 0, 0.2);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* 修复冲突 */
|
||||
.box-btn-left:hover, .box-btn-right:hover {
|
||||
animation: none !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
|
||||
// 添加按钮粒子效果
|
||||
function addButtonParticles(button) {
|
||||
// 移除已有粒子
|
||||
removeButtonParticles();
|
||||
|
||||
// 获取按钮位置
|
||||
const buttonPos = button.offset();
|
||||
const buttonWidth = button.outerWidth();
|
||||
const buttonHeight = button.outerHeight();
|
||||
|
||||
// 创建粒子容器
|
||||
const particleContainer = $('<div class="button-particles"></div>');
|
||||
particleContainer.css({
|
||||
'position': 'absolute',
|
||||
'left': buttonPos.left + 'px',
|
||||
'top': buttonPos.top + 'px',
|
||||
'width': buttonWidth + 'px',
|
||||
'height': buttonHeight + 'px',
|
||||
'pointer-events': 'none',
|
||||
'z-index': 1000
|
||||
});
|
||||
|
||||
// 添加粒子
|
||||
const colors = ['#ffde59', '#ff914d', '#ff66c4', '#5ce1e6'];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const particle = $('<div class="particle"></div>');
|
||||
const size = Math.random() * 8 + 4;
|
||||
const color = colors[Math.floor(Math.random() * colors.length)];
|
||||
|
||||
particle.css({
|
||||
'position': 'absolute',
|
||||
'width': size + 'px',
|
||||
'height': size + 'px',
|
||||
'background-color': color,
|
||||
'border-radius': '50%',
|
||||
'left': (Math.random() * 100) + '%',
|
||||
'top': (Math.random() * 100) + '%',
|
||||
'opacity': 0.7,
|
||||
'animation': `particle-float ${Math.random() * 2 + 1}s ease-out infinite`,
|
||||
'transform': 'translate(-50%, -50%)'
|
||||
});
|
||||
|
||||
particleContainer.append(particle);
|
||||
}
|
||||
|
||||
// 添加闪烁效果
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const sparkle = $('<div class="sparkle"></div>');
|
||||
const size = Math.random() * 6 + 2;
|
||||
|
||||
sparkle.css({
|
||||
'position': 'absolute',
|
||||
'width': size + 'px',
|
||||
'height': size + 'px',
|
||||
'background-color': '#fff',
|
||||
'border-radius': '50%',
|
||||
'left': (Math.random() * 100) + '%',
|
||||
'top': (Math.random() * 100) + '%',
|
||||
'box-shadow': '0 0 10px 2px rgba(255, 255, 255, 0.8)',
|
||||
'opacity': 0.8,
|
||||
'animation': `sparkle-float ${Math.random() * 1.5 + 0.5}s ease-out infinite`
|
||||
});
|
||||
|
||||
particleContainer.append(sparkle);
|
||||
}
|
||||
|
||||
// 添加粒子容器到body
|
||||
$('body').append(particleContainer);
|
||||
}
|
||||
|
||||
// 移除按钮粒子效果
|
||||
function removeButtonParticles() {
|
||||
$('.button-particles').remove();
|
||||
}
|
||||
Reference in New Issue
Block a user