前端 | 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演讲项,则自动触发其点击事件。
相关推荐
alikami2 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
虾球xz6 分钟前
游戏引擎学习第55天
学习·游戏引擎
oneouto23 分钟前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh3227 分钟前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
吃杠碰小鸡36 分钟前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
炭烤玛卡巴卡1 小时前
学习postman工具使用
学习·测试工具·postman
一个处女座的程序猿O(∩_∩)O1 小时前
vue3 如何使用 mounted
前端·javascript·vue.js