Web 前端技术 第 6 周

交互逻辑与数据获取

本章介绍JavaScript核心语法、事件处理与DOM操作,并引入异步编程概念,旨在为新闻页面添加动态交互与数据更新功能。

2026-04-07 第 6 周

学习要点

  • 掌握JavaScript变量、数据类型及条件与循环控制结构的基本用法
  • 理解函数定义与作用域规则,能够封装可复用的交互逻辑
  • 运用事件监听与DOM操作方法,实现页面元素的动态更新
  • 了解异步编程概念,能够使用fetch API获取并展示外部数据

正文

变量与数据类型

变量是用于存储信息的容器,是程序操作数据的基本单元。JavaScript中的变量使用letconst或已弃用的var关键字声明。数据类型定义了变量所存储值的种类,主要包括字符串(String)、数字(Number)、布尔值(Boolean)、对象(Object)等基本类型。

在新闻传播场景中,可以将变量理解为新闻稿件中的“信息单元”。例如,一篇报道的“标题”、“记者姓名”、“发布时间”和“阅读量”都是独立的信息单元,它们的数据类型可能分别是字符串、字符串、字符串和数字。程序通过变量名来引用这些信息,如同通过关键词来定位稿件中的特定内容。声明变量就是为这些信息单元分配一个临时的存储位置和标识符。理解数据类型至关重要,因为它决定了可以对数据进行何种操作,例如,可以对“阅读量”(数字)进行加减运算,但无法对“记者姓名”(字符串)进行数学计算。

1
2
3
4
5
6
// 声明变量,存储一篇新闻稿件的核心信息
let newsTitle = "全球气候峰会达成历史性协议"; // 字符串类型,存储标题
const reporterName = "王记者"; // 常量字符串,记者姓名通常不变
let publishTime = "2023-11-15 10:00"; // 字符串,发布日期时间
let viewCount = 125430; // 数字类型,阅读量,可进行算术运算
let isFeatured = true; // 布尔类型,标识是否为头条新闻

控制结构

控制结构是程序流程的“决策者”和“组织者”,它通过条件判断和循环重复来控制代码的执行路径。条件结构(如if...else)根据特定条件的真假选择执行不同的代码块;循环结构(如forwhile)则用于重复执行某段代码,直到满足退出条件。

这类似于新闻编辑室的稿件处理流程。编辑拿到一篇稿件(数据)后,需要根据其“新闻价值”(条件判断)来决定是“直接发布”(执行A分支)、“退回修改”(执行B分支)还是“存档备用”(执行C分支)。循环结构则像是一个自动化的新闻推送系统,它遍历一个“待推送用户列表”(数据集合),为列表中的每一位用户(每次循环)执行一次“发送新闻简报”的操作,直到列表中的所有用户都处理完毕。控制结构使程序具备了处理复杂、多变情况的能力。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 模拟新闻排序逻辑:根据阅读量和是否头条决定显示位置
let viewCount = 85000;
let isFeatured = true;
let displayPosition;

// 条件判断:决定稿件在页面的显示位置
if (isFeatured) {
    displayPosition = "头条轮播图";
} else if (viewCount > 100000) {
    displayPosition = "热门推荐区";
} else {
    displayPosition = "普通列表区";
}
console.log(`这篇稿件应放置在:${displayPosition}`);

// 循环:批量处理一个新闻标题数组,为每个标题添加序号
let headlines = ["经济复苏信号显现", "新体育场馆落成", "本地艺术展本周开幕"];
for (let i = 0; i < headlines.length; i++) {
    console.log(`${i + 1}. ${headlines[i]}`); // 输出:1. 经济复苏信号显现 ...
}

函数与作用域

函数是一段被封装、可重复调用的代码块,用于执行特定任务。它通过接收输入(参数)、处理内部逻辑、并可能返回输出结果来工作。作用域规定了变量和函数的可访问范围,主要分为全局作用域和局部(函数)作用域。

在新闻生产中,一个“事实核查”团队可以类比为一个函数。编辑部(主程序)将一篇待发布的稿件(参数)交给这个团队。团队在其内部(函数作用域内)按照一套固定的核查流程(函数体)进行工作,期间可能产生一些仅供内部使用的笔记(局部变量)。核查完成后,团队向编辑部返回一个结果:“通过”、“需修改”或“不通过”(返回值)。这个“事实核查”函数可以被反复调用,处理不同的稿件,而每次调用时其内部的笔记都是独立的,不会互相干扰。这体现了函数的封装性与作用域的隔离性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 定义一个函数,用于格式化新闻发布时间
function formatPublishTime(rawTimeString) {
    // rawTimeString 是参数,其作用域仅限于本函数内部
    let formattedTime; // 局部变量,外部无法访问
    // 模拟简单的格式化逻辑:将“2023-11-15 10:00”转换为“11月15日 10:00”
    const parts = rawTimeString.split(' ');
    const datePart = parts[0].split('-');
    formattedTime = `${parseInt(datePart[1])}${parseInt(datePart[2])}${parts[1]}`;
    return formattedTime; // 返回格式化后的字符串
}

// 调用函数,并接收其返回值
let originalTime = "2023-11-15 10:00";
let displayTime = formatPublishTime(originalTime); // 传递参数,调用函数
console.log(`发布时间:${displayTime}`); // 输出:发布时间:11月15日 10:00

事件处理与DOM操作

事件处理是指为网页元素绑定JavaScript代码,以响应特定的用户交互(如点击、鼠标移动、键盘输入)或浏览器行为(如页面加载)。DOM(文档对象模型)操作则是通过JavaScript访问、修改、添加或删除HTML文档中的元素、属性和内容,从而动态改变网页的呈现。

这个过程如同一个智能的新闻播报控制台。网页上的一个“点击加载更多”按钮就是一个事件源(Event Source)。当用户点击(触发click事件)这个按钮时,相当于向控制台发出了一个指令。我们预先编写好的JavaScript函数(事件处理器,Event Handler)就像控制台里预设的程序,会被立即启动。这个程序会执行一系列DOM操作:它首先找到存放新闻列表的容器(document.getElementById),然后向服务器请求新的数据(或从本地模拟),最后创建新的列表项元素(document.createElement),填充内容(.textContent),并将其追加到容器末尾(.appendChild)。于是,页面内容在没有刷新的情况下得到了更新,实现了动态交互。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 假设HTML中有一个按钮 <button id="loadMoreBtn">加载更多新闻</button>
// 和一个新闻列表容器 <ul id="newsList"></ul>

// 1. 获取DOM元素
const loadButton = document.getElementById('loadMoreBtn');
const newsListContainer = document.getElementById('newsList');

// 2. 定义事件处理函数
function handleLoadMoreClick() {
    // 模拟获取到一条新新闻
    const newHeadline = "快讯:本市地铁新线路今日试运行";
    
    // 3. DOM操作:创建新的列表项元素并添加到页面
    const newListItem = document.createElement('li'); // 创建<li>元素
    newListItem.textContent = newHeadline; // 设置其文本内容
    newListItem.className = 'news-item'; // 为其添加CSS类名
    newsListContainer.appendChild(newListItem); // 将其追加为容器的最后一个子元素
    
    console.log('一条新新闻已添加到列表。');
}

// 4. 为按钮元素绑定(监听)点击事件
loadButton.addEventListener('click', handleLoadMoreClick);

异步编程与数据获取

异步编程是一种编程模式,允许程序在等待一个耗时操作(如从网络请求数据)完成的同时,继续执行后续代码,而不被阻塞。Promise对象和async/await语法是现代JavaScript处理异步操作的核心。fetch API是基于Promise的、用于发起网络请求以获取资源(如JSON数据)的工具。

在新闻直播场景中,主播(主线程)在播报一条突发新闻(执行主任务)时,后台的编辑团队(异步任务)正在同时核实来自现场记者(服务器)的最新消息。主播不会停下来等待编辑团队核实完毕,而是继续播报已确认的内容。当编辑团队拿到核实后的消息(异步操作完成),他们会通过提词器(回调函数或Promisethen方法)立即将更新后的信息传递给主播,主播随即将其插播出去(更新DOM)。fetch API就是派去联系现场记者的那个“通信员”,它带回一个Promise,承诺将来会提供数据。使用async/await可以让异步代码的写法更接近同步逻辑,易于理解。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 使用fetch API从模拟的新闻数据接口获取数据
async function fetchLatestNews() {
    const apiUrl = 'https://api.example.com/latest-news'; // 模拟新闻API地址
    
    try {
        // 发起异步网络请求,await会暂停本函数执行,直到Promise完成
        const response = await fetch(apiUrl);
        
        // 检查响应是否成功
        if (!response.ok) {
            throw new Error(`网络响应异常: ${response.status}`);
        }
        
        // 将响应体解析为JSON格式,这也是一个异步操作
        const newsData = await response.json();
        
        // 假设newsData是一个包含新闻标题的数组
        console.log('获取到最新新闻:', newsData);
        // 此处可以继续调用DOM操作函数,将newsData渲染到页面上
        // renderNewsToPage(newsData);
        
    } catch (error) {
        // 捕获并处理请求或解析过程中可能发生的错误
        console.error('获取新闻数据失败:', error);
        // 可以在页面上显示错误提示信息
    }
}

// 调用异步函数
fetchLatestNews();

实践示例

场景:一个新闻网站的头条新闻区,需要实现一个“定时切换”功能,让多条重要新闻标题能够自动轮播展示。

目标:编写JavaScript代码,使一个包含多条新闻标题的列表能够每隔3秒自动切换到下一条,并在切换时伴有简单的淡入淡出视觉效果(通过改变CSS类实现)。

实现步骤

  1. 准备HTML结构:在页面中创建一个用于显示当前新闻标题的容器。
    1
    2
    3
    4
    
    <!-- 这是HTML部分 -->
    <div id="headlineBanner">
        <h2 id="currentHeadline">这里是第一条新闻标题</h2>
    </div>
    
  2. 准备数据与样式:定义一个新闻标题数组,并编写用于切换效果的CSS类。
    1
    2
    3
    4
    5
    6
    7
    
    // 新闻标题数据
    const headlines = [
        "突破性研究:人工智能助力早期疾病诊断",
        "国际电影节开幕,多部华语影片入围",
        "央行发布最新货币政策,稳定市场预期",
        "社区体育设施升级,居民健身更便利"
    ];
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /* 这是CSS部分 */
    .fade-out {
        opacity: 0;
        transition: opacity 0.5s ease-in-out;
    }
    .fade-in {
        opacity: 1;
        transition: opacity 0.5s ease-in-out;
    }
    
  3. 初始化变量与DOM元素:获取显示标题的元素,并设置当前显示索引。
    1
    2
    
    let currentIndex = 0; // 当前显示新闻的索引
    const headlineElement = document.getElementById('currentHeadline');
    
  4. 编写切换标题的核心函数:该函数负责更新索引、修改元素文本内容并触发视觉过渡效果。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    function switchHeadline() {
        // 1. 添加淡出类,触发透明度变为0的过渡动画
        headlineElement.classList.add('fade-out');
    
        // 2. 等待淡出动画完成(约0.5秒),然后更新标题并淡入
        setTimeout(() => {
            // 更新索引,循环往复
            currentIndex = (currentIndex + 1) % headlines.length;
            // 更新DOM元素的文本内容
            headlineElement.textContent = headlines[currentIndex];
            // 移除淡出类,添加淡入类,触发透明度从0到1的动画
            headlineElement.classList.remove('fade-out');
            headlineElement.classList.add('fade-in');
        }, 500); // 等待时间与CSS过渡时间一致
    }
    
  5. 设置定时器,启动自动轮播:使用setInterval函数,每隔3秒调用一次切换函数。
    1
    2
    3
    
    // 页面加载后,立即设置一个间隔定时器
    // 每3000毫秒(3秒)执行一次switchHeadline函数
    setInterval(switchHeadline, 3000);
    

效果说明:页面加载后,头条新闻区会显示“突破性研究:人工智能助力早期疾病诊断”。等待3秒后,该标题会平滑地淡出消失,紧接着“国际电影节开幕,多部华语影片入围”这条标题会淡入显示。此后,每过3秒,新闻标题都会按照预定义的顺序自动切换一次,形成连续的轮播效果。整个过程无需用户任何操作,实现了内容的动态自动展示。

练习

  1. 基础练习:仿照“实践示例”,创建一个简单的图片轮播。准备一个包含3张图片URL的数组,修改代码,使<img id="newsImage">元素的src属性每隔4秒自动更新,实现图片新闻的轮播。
  2. 进阶练习:为上述头条新闻轮播添加交互控制。在页面中添加“上一个”和“下一个”按钮。点击“下一个”按钮立即切换到下一条新闻并重置自动轮播计时器;点击“上一个”按钮则切换到上一条新闻并同样重置计时器。你需要使用clearInterval和重新setInterval来控制定时器。
  3. 综合练习:构建一个“新闻关键词过滤”页面。页面上有一个输入框和一个新闻列表(列表项初始包含5条不同主题的新闻标题)。要求实现:当用户在输入框中输入文字时(监听input事件),程序能实时过滤新闻列表,只显示标题中包含输入关键词的新闻。请考虑用户输入为空时,应显示所有新闻。

本章小结

  • 变量与数据类型:程序存储与操作信息的基本单元,类型决定了数据的性质和可执行的操作。
  • 控制结构:通过条件判断和循环重复来控制程序执行的逻辑流程,实现动态决策与批量处理。
  • 函数与作用域:封装特定功能的可复用代码块,作用域规则确保了变量访问的清晰性与隔离性。
  • 事件处理与DOM操作:通过监听用户或浏览器事件,并动态修改网页内容与结构,是实现前端交互的核心。
  • 异步编程与数据获取:使用Promiseasync/awaitfetch API处理非阻塞操作,是从网络动态获取并呈现数据的关键。

延伸阅读