前端 | MYTED单篇TED词汇学习功能优化

文章目录

📚实现效果

🐇before

  • 点击TED单篇词汇表按钮,选择对应TED打卡号,返回对应TED单篇词汇,点击列表单词查询详情。


  • 单篇抽查按钮,点击后先选中抽查TED号

  • 在抽查状态下,再次点击抽查按钮,则继续在该篇下抽查。
  • 抽查结束后自动弹出重选按钮,在抽查中途希望重选则点击重选按钮
  • 抽查单词点击后同样可弹出iframe框查询。

🐇after

  • 左侧框直接显示已经学习的TED列表,并可选择TED类别返回对应TED。单击左侧TED标题,右侧显示该篇对应的单词列表,被选中的TED标粉。默认选中第一篇并在右侧返回相关单词。
  • 学习右侧单词,点击单词,可查看详情。点击✔️,对应单词标绿表明已学会;点击❌,对应单词标红表明不熟悉。

📚模块实现解析

🐇html

html 复制代码
<div id="categorycontainer">
     <div id="categorySelectContainer">
         <select id="categorySelect" onchange="showTED()">
             <option value="">ALL</option>
             <option value="个人成长">个人成长</option>
             <option value="心理调节">心理调节</option>
             <option value="生活方式与习惯">生活习惯</option>
             <option value="健康与健身">健康与健身</option>
             <option value="社交与关系">社交与关系</option>
         </select>
     </div>
     <div id="contentContainer">
         <ul id="TEDList"></ul>
         <div id="wordsList"></div>
     </div>
 </div>

🐇css

css 复制代码
.page-main-content {
    background-image: url("../images/bg3.svg");
}
#categorySelectContainer select {
    font-family: serif;
    position: absolute;
    top: 0.5%;
    left: 20%;
    height: 30px;
    padding: 3px;
    text-align: center;
    font-size: 16px;
    background-color: azure;
    border: 2px solid #1e80b8bb;
    border-radius: 14px;
}

#contentContainer .tedtext {
    font-family: serif;
    font-size: 15px;
    font-weight: normal;
    color: #333;
}

#contentContainer .tednum {
    font-family: serif;
    font-size: 16px;
    color: #2966cf;
}

#contentContainer {
    font-family: serif;
    display: flex;
    justify-content: center;
    width: 100%;
}

#TEDList, #wordsList {
    font-family: serif;
    width: 50%;
    max-height: 480px;
    overflow-y: auto;
    border: 1px solid #ccc;
    padding: 10px;
    box-sizing: border-box;
    margin: 0 15px;
    border-radius: 8px;
    background: var(--content-background-color);
    box-shadow: 0 0 8px var(--shadow-color);
}

#TEDList:hover, #wordsList:hover {
    box-shadow: 0 0 12px var(--shadow-hover-color);
}

#TEDList li, #wordsList li {
    font-family: serif;
    margin-bottom: 5px;
    padding: 5px;
    padding-left: 35px;
    font-size: 16px;
    border-bottom: 1px solid #eee;
    border-radius: 8px;
}

#TEDList li:hover,#wordsList li:hover{
    box-shadow: 0 0 8px var(--shadow-color);
}

.selectedli{
    box-shadow: 0 0 8px var(--shadow-color);
    background-color: #fde9ea;
}

.tednum {
    font-weight: bold;
}

.tedtext {
    display: block;
    margin-left: 10px;
}

@media (max-width: 800px) {
    #TEDList, #wordsList {
        width: 100%;
        max-height: none;
    }
}

🐇javascript

js 复制代码
const mapData1 = [
    { "name": 1, "value": "20岁,光阴不再来", "category": "个人成长" },
    { "name": 2, "value": "帮你省钱的三个心理技巧", "category": "生活方式与习惯" },
    ...
];

function getWordsData() {
    return fetch('output_word.json')
        .then(response => response.json())
        .catch(error => console.error('Error loading the words data:', error));
}

// 显示TED演讲列表的函数
function showTED() {
    const category = document.getElementById("categorySelect").value;
    const TED1 = mapData1.filter(data => category ? data.category === category : true);
    TED1.sort((a, b) => a.name - b.name);
    displayTED(TED1);
}

function displayTED(TED) {
    const TEDList = document.getElementById("TEDList");
    TEDList.innerHTML = "";
    TED.forEach(ted => {
        const listItem = document.createElement("li");
        listItem.innerHTML = `<span class='tednum'>打卡号</span>-<span class='tednum'>${ted.name}</span>:<span class='tedtext'>${ted.value}</span>`;
        listItem.addEventListener('click', function() {
            // 先移除其他所有li的选中状态
            TEDList.querySelectorAll('li').forEach(item => {
                item.classList.remove('selectedli');
            });
            // 给当前点击的li添加选中状态
            this.classList.add('selectedli');
            showWordsForTED(ted.name);
        });
        TEDList.appendChild(listItem);
    });
}

// 显示对应TED号的单词
function showWordsForTED(inputNumber) {
    getWordsData().then(words => {
        let resultWords = words.filter(word => word.numbers.includes(parseInt(inputNumber)));
        displayWords(resultWords);
    });
}

// 显示单词的函数
function displayWords(words) {
    const wordsList = document.getElementById("wordsList");
    wordsList.innerHTML = "";
    words.forEach(word => {
        // 创建列表项
        const listItem = document.createElement("li");
        listItem.style.position = 'relative'; 

        // 创建单词文本节点
        const textNode = document.createTextNode(word.word);
        listItem.appendChild(textNode);

        // 创建按钮容器
        const buttonsContainer = document.createElement("span");
        buttonsContainer.style.position = 'absolute'; // 绝对定位
        buttonsContainer.style.right = '50px'; // 靠右浮动
        buttonsContainer.style.top = '5px'; // 顶部对齐
        // buttonsContainer.style.backgroundColor = 'pink';

        // 创建×按钮
        const uncheckButton = document.createElement("button");
        uncheckButton.textContent = "❌";
        uncheckButton.style.border = "none"; 
        uncheckButton.style.backgroundColor = "transparent"; 
        
        
        // 创建√按钮
        const checkButton = document.createElement("button");
        checkButton.textContent = "✔️";
        checkButton.style.marginRight = "10px"; 
        checkButton.style.border = "none"; 
        checkButton.style.backgroundColor = "transparent"; 

        // 为按钮添加点击事件
        checkButton.addEventListener('click', function(event) {
            event.stopPropagation(); 
            // listItem.style.backgroundColor = "#E7E593";
            listItem.style.backgroundColor = "#def9dc";
            listItem.style.boxShadow = "0 0 3px var(--shadow-color)";
        });
        uncheckButton.addEventListener('click', function(event) {
            event.stopPropagation();
            // listItem.style.backgroundColor = "#F0686C";
            listItem.style.backgroundColor = "#fdd2ae";
            listItem.style.boxShadow = "0 0 3px var(--shadow-color)";
        });

        // 将按钮添加到容器中
        buttonsContainer.appendChild(checkButton);
        buttonsContainer.appendChild(uncheckButton);
        listItem.appendChild(buttonsContainer);

        listItem.addEventListener('click', function(event) {
            if (event.target !== buttonsContainer && event.target !== checkButton && event.target !== uncheckButton) {
                openSouGouSearch(word.word);
            }
        });
        wordsList.appendChild(listItem);
    });
}

function openSouGouSearch(word) {
    const existingIframe = document.querySelector('iframe');
    const existingCloseButton = document.querySelector('.close-button');

    if (existingIframe) {
        document.body.removeChild(existingIframe);
    }
    if (existingCloseButton) {
        document.body.removeChild(existingCloseButton);
    }

    const iframe = document.createElement('iframe');
    iframe.src = `https://fanyi.sogou.com/text?keyword=${encodeURIComponent(word)}`;
    iframe.style.position = 'fixed';
    iframe.style.top = '10.5%';
    iframe.style.left = '1%';
    iframe.style.width = '50%';
    iframe.style.height = '88%';
    iframe.style.border = '2px solid #bfc1a9';
    iframe.style.zIndex = '9999';
    iframe.style.borderRadius = '10px'; 
    document.body.appendChild(iframe);

    // 添加关闭按钮
    const closeButton = document.createElement('button');
    closeButton.textContent = '×';
    closeButton.classList.add('close-button');
    closeButton.style.position = 'fixed';
    closeButton.style.width = '20px';
    closeButton.style.height = '20px';
    closeButton.style.top = '12.8%';
    closeButton.style.right = '50.5%';
    closeButton.style.zIndex = '10000';
    closeButton.style.border = '1.2px solid #bfc1a9';
    closeButton.style.borderRadius = '50%'; 
    closeButton.style.fontFamily = 'serif';
    closeButton.style.fontSize = '15px';
    closeButton.style.color = 'white';
    closeButton.style.fontWeight = 'bold';
    closeButton.style.padding = '2px';
    closeButton.style.backgroundColor = '#d24735';
    closeButton.addEventListener('click', () => {
        document.body.removeChild(iframe);
        document.body.removeChild(closeButton);
    });
    document.body.appendChild(closeButton);
}

// 在页面加载完成后显示TED演讲列表
window.onload = function() {
    showTED();
    const wordsList = document.getElementById("wordsList");
    if (wordsList) {
        wordsList.innerHTML = "点击TED号查看相关单词";
    }
    const firstTEDItem = TEDList.querySelector('li'); 
    if (firstTEDItem) {
        firstTEDItem.click();
    }
}

  1. 获取单词数据 (getWordsData 函数)

  2. 显示TED演讲列表 (showTED 函数):

    • 根据用户在下拉菜单中选择的类别筛选TED演讲数据。
    • 对筛选后的TED演讲数据按TED打卡号排序。
    • 调用 displayTED 函数显示TED演讲列表。
  3. 显示TED演讲列表项 (displayTED 函数):

    • 清空当前的TED演讲列表,并为每个TED创建一个列表项。
    • 为每个列表项添加点击事件,当点击时,移除其他所有列表项的选中状态,并给当前点击的列表项添加选中状态。
    • 调用 showWordsForTED 函数显示对应TED打卡号的单词。
  4. 显示对应TED演讲号的单词 (showWordsForTED 函数):

    • 调用 getWordsData 函数获取单词数据。
    • 筛选出与当前TED打卡号相关的单词。
    • 调用 displayWords 函数显示这些单词。
  5. 显示单词 (displayWords 函数):

    • 清空当前的单词列表,并为每个单词创建一个列表项。
    • 为每个单词列表项创建一个按钮容器,包含"❌"和"✔️"两个按钮,分别用于标记单词的未学习和已学习状态。
    • 为按钮添加点击事件,改变列表项的背景色以反映单词的学习状态。
    • 为单词列表项添加点击事件,当点击单词文本时,调用 openSouGouSearch 函数打开搜狗翻译页面。
  6. 打开搜狗翻译页面 (openSouGouSearch 函数):

    • 如果页面上已经存在iframe或关闭按钮,则先移除它们。
    • 创建一个新的iframe,设置其源为搜狗翻译的URL,并添加到页面上。
    • 创建一个关闭按钮,并添加到页面上。点击关闭按钮会移除iframe和关闭按钮。
  7. 页面加载完成后的操作 (window.onload 事件处理器):

    • 显示TED演讲列表。
    • 如果存在第一个TED演讲项,则自动触发其点击事件。
相关推荐
学不会•1 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
朝九晚五ฺ5 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
沉默璇年6 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder6 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript