js如何实现快递信息动态显示?

99ANYc3cd6
预计阅读时长 52 分钟
位置: 首页 业务流程 正文

最简单的静态页面实现 (适合演示)

这个方案不涉及网络请求,数据直接写在 HTML 中,适合快速理解如何将数据渲染到页面上。

HTML 结构

我们创建一个容器来包裹所有的物流信息,并为每一条信息创建一个列表项。

js快递信息显示
(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">快递信息查询</title>
    <style>
        /* 一些简单的样式 */
        body { font-family: Arial, sans-serif; padding: 20px; }
        .logistics-container { border: 1px solid #ccc; padding: 15px; border-radius: 8px; }
        .logistics-item { padding: 10px; border-bottom: 1px solid #eee; position: relative; }
        .logistics-item:last-child { border-bottom: none; }
        .time { color: #888; font-size: 0.9em; }
        .content { margin-top: 5px; }
        /* 左侧时间轴样式 */
        .logistics-item::before {
            content: '';
            position: absolute;
            left: -10px;
            top: 20px;
            width: 12px;
            height: 12px;
            background-color: #007bff;
            border-radius: 50%;
        }
        .logistics-item::after {
            content: '';
            position: absolute;
            left: -4px;
            top: 32px;
            width: 1px;
            height: calc(100% + 12px);
            background-color: #ccc;
        }
        .logistics-item:last-child::after {
            display: none;
        }
    </style>
</head>
<body>
    <h1>快递单号: SF1234567890</h1>
    <div id="logistics-list" class="logistics-container">
        <!-- 物流信息将通过 JavaScript 动态插入这里 -->
        <!-- 示例数据,稍后会被 JS 覆盖 -->
        <div class="logistics-item">
            <div class="time">2025-10-27 10:30:00</div>
            <div class="content">【深圳市】 快件已由 [快递员姓名] 送达,感谢使用顺丰速运,期待再次为您服务。</div>
        </div>
    </div>
    <script src="app.js"></script>
</body>
</html>

JavaScript 逻辑 (app.js)

我们定义一个包含物流信息的数组,然后遍历这个数组,为每个信息创建一个 HTML 元素,并添加到页面上。

// 1. 模拟从服务器获取的物流数据
// 在真实应用中,这些数据通常来自 API 请求
const logisticsData = [
    {
        time: '2025-10-27 15:22:00',
        content: '【深圳市】 快件已由 [快递员姓名] 送达,感谢使用顺丰速运,期待再次为您服务。'
    },
    {
        time: '2025-10-27 10:30:00',
        content: '【深圳市】 快件已派送完毕,快件已由 [快递员姓名] 派送。'
    },
    {
        time: '2025-10-27 08:15:00',
        content: '【深圳市】 快件到达 【深圳南山营业点】,快件将由快递员 [快递员姓名] 进行下一步派送。'
    },
    {
        time: '2025-10-26 22:45:00',
        content: '【深圳市】 快件已到达 【深圳转运中心】,下一站 【深圳南山营业点】'
    },
    {
        time: '2025-10-26 20:10:00',
        content: '【广州市】 快件已离开 【广州转运中心】,下一站 【深圳转运中心】'
    }
];
// 2. 获取页面上的容器元素
const logisticsListContainer = document.getElementById('logistics-list');
// 3. 清空容器(如果里面有默认的示例内容)
// logisticsListContainer.innerHTML = ''; 
// 4. 遍历数据,动态生成 HTML 并插入到容器中
logisticsData.forEach(item => {
    // 创建一个列表项 div
    const listItem = document.createElement('div');
    listItem.className = 'logistics-item';
    // 创建时间 div
    const timeDiv = document.createElement('div');
    timeDiv.className = 'time';
    timeDiv.textContent = item.time;
    // 创建内容 div
    const contentDiv = document.createElement('div');
    contentDiv.className = 'content';
    contentDiv.textContent = item.content;
    // 将时间和内容添加到列表项中
    listItem.appendChild(timeDiv);
    listItem.appendChild(contentDiv);
    // 将列表项添加到容器中
    // 使用 prepend 可以让最新的物流信息显示在最上面
    logisticsListContainer.prepend(listItem);
});

原理总结:

  1. 数据准备:定义一个数据结构(通常是数组),每个元素代表一条物流信息。
  2. 获取容器:用 document.getElementById 找到 HTML 中用于显示信息的“空盒子”。
  3. 遍历与创建:用 forEach 循环遍历数据数组,在循环内部,用 document.createElement 为每条信息创建对应的 HTML 元素(<div>)。
  4. :用 element.textContentelement.innerHTML 将数据填充到新创建的元素中。
  5. 添加到页面:用 container.appendChild()container.prepend() 将创建好的元素添加到容器中,从而显示在页面上。

使用 Fetch API 从服务器获取真实数据 (实际应用)

在实际项目中,物流信息存储在服务器上,我们需要通过 API (应用程序接口) 来获取。

修改 HTML (index.html)

HTML 结构基本不变,但我们会增加一个“查询”按钮,让用户主动触发数据获取。

js快递信息显示
(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <!-- 样式与方案一相同 -->
    <style>
        /* ... (方案一的 CSS) ... */
    </style>
</head>
<body>
    <h1>快递信息查询</h1>
    <div>
        <input type="text" id="tracking-number" placeholder="请输入快递单号" value="SF1234567890">
        <button id="query-btn">查询</button>
    </div>
    <div id="logistics-list" class="logistics-container">
        <!-- 物流信息将通过 JavaScript 动态插入这里 -->
        <p style="color: #888;">等待查询...</p>
    </div>
    <script src="app.js"></script>
</body>
</html>

JavaScript 逻辑 (app.js)

核心变化是使用 fetch 函数来发起网络请求。

// 获取页面元素
const trackingNumberInput = document.getElementById('tracking-number');
const queryBtn = document.getElementById('query-btn');
const logisticsListContainer = document.getElementById('logistics-list');
// 模拟一个 API 接口地址
// 在真实项目中,这里是一个真实的 URL, 'https://api.example.com/logistics'
const API_URL = 'https://mockapi.example.com/logistics'; 
// 封装一个获取物流信息的函数
async function fetchLogisticsInfo(trackingNumber) {
    try {
        // 在真实请求中,你可能需要将单号作为参数或请求体发送
        // const response = await fetch(`${API_URL}?trackingNumber=${trackingNumber}`);
        // 为了演示,我们使用一个假的 API,它会延迟 1 秒后返回我们的模拟数据
        // 注意:这是一个模拟,真实 API 的行为取决于后端服务
        const mockApiResponse = new Promise((resolve) => {
            setTimeout(() => {
                resolve({
                    code: 200,
                    message: 'success',
                    data: [
                        { time: '2025-10-27 15:22:00', content: '【深圳市】 快件已由 [快递员姓名] 送达,感谢使用顺丰速运,期待再次为您服务。' },
                        { time: '2025-10-27 10:30:00', content: '【深圳市】 快件已派送完毕,快件已由 [快递员姓名] 派送。' },
                        { time: '2025-10-27 08:15:00', content: '【深圳市】 快件到达 【深圳南山营业点】,快件将由快递员 [快递员姓名] 进行下一步派送。' },
                        { time: '2025-10-26 22:45:00', content: '【深圳市】 快件已到达 【深圳转运中心】,下一站 【深圳南山营业点】' },
                        { time: '2025-10-26 20:10:00', content: '【广州市】 快件已离开 【广州转运中心】,下一站 【深圳转运中心】' }
                    ]
                });
            }, 1000);
        });
        const result = await mockApiResponse;
        if (result.code === 200) {
            return result.data;
        } else {
            throw new Error(result.message || '获取物流信息失败');
        }
    } catch (error) {
        console.error('请求出错:', error);
        // 可以在这里显示一个错误提示给用户
        alert('查询失败: ' + error.message);
        return null;
    }
}
// 渲染物流信息的函数 (与方案一中的逻辑类似)
function renderLogisticsList(data) {
    // 清空容器
    logisticsListContainer.innerHTML = ''; 
    if (!data || data.length === 0) {
        logisticsListContainer.innerHTML = '<p style="color: #888;">暂无物流信息。</p>';
        return;
    }
    data.forEach(item => {
        const listItem = document.createElement('div');
        listItem.className = 'logistics-item';
        listItem.innerHTML = `
            <div class="time">${item.time}</div>
            <div class="content">${item.content}</div>
        `;
        logisticsListContainer.prepend(listItem);
    });
}
// 为查询按钮添加点击事件监听器
queryBtn.addEventListener('click', async () => {
    const trackingNumber = trackingNumberInput.value.trim();
    if (!trackingNumber) {
        alert('请输入快递单号');
        return;
    }
    // 在查询开始时,可以显示一个加载动画
    logisticsListContainer.innerHTML = '<p style="color: #888;">正在查询中...</p>';
    // 调用函数获取数据
    const logisticsData = await fetchLogisticsInfo(trackingNumber);
    // 获取到数据后,渲染到页面上
    if (logisticsData) {
        renderLogisticsList(logisticsData);
    }
});
// 页面加载时,可以默认查询一次
window.addEventListener('DOMContentLoaded', () => {
    queryBtn.click();
});

原理解释:

  1. async/awaitfetchfetch 是现代浏览器提供的用于发起网络请求的 API,它返回一个 Promise。async/await 语法让异步代码看起来像同步代码,更容易理解和维护。
  2. 错误处理 (try...catch):网络请求可能会失败(比如服务器宕机、网络断开)。try...catch 块可以捕获这些错误,并执行相应的错误处理逻辑(提示用户“查询失败”)。
  3. 事件监听 (addEventListener):我们将查询逻辑绑定在按钮的 click 事件上,只有当用户点击按钮时,才会触发数据获取和渲染。
  4. 用户体验:在请求开始时,我们显示“正在查询中...”,在请求结束后,根据结果显示成功信息或错误信息,这提供了更好的用户体验。

使用现代前端框架 (如 Vue 或 React)

对于大型或复杂的应用,手动操作 DOM (如方案一和二) 会变得繁琐且难以维护,现代前端框架通过“声明式”的编程方式,让你只需关心数据的状态,框架会自动帮你更新视图。

这里以 Vue.js 为例,因为它更轻量且易于上手。

安装 Vue

你可以通过 CDN 引入 Vue,无需复杂的环境搭建。

<!-- 在你的 HTML 文件头部添加 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

HTML 和 Vue 模板 (index.html)

Vue 使用特殊的模板语法,如 来插值,v-for 来循环。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">Vue 快递信息查询</title>
    <style>
        /* 样式与方案一相同 */
        body { font-family: Arial, sans-serif; padding: 20px; }
        .logistics-container { border: 1px solid #ccc; padding: 15px; border-radius: 8px; }
        .logistics-item { padding: 10px; border-bottom: 1px solid #eee; position: relative; }
        .logistics-item:last-child { border-bottom: none; }
        .time { color: #888; font-size: 0.9em; }
        .content { margin-top: 5px; }
        .logistics-item::before, .logistics-item::after { /* 与方案一相同 */ }
    </style>
</head>
<body>
    <div id="app">
        <h1>快递单号: {{ trackingNumber }}</h1>
        <div>
            <input type="text" v-model="trackingNumberInput" placeholder="请输入快递单号">
            <button @click="queryLogistics">查询</button>
        </div>
        <!-- 使用 v-if 和 v-else 进行条件渲染 -->
        <div v-ifisLoading" class="logistics-container">
            <p style="color: #888;">正在查询中...</p>
        </div>
        <div v-else class="logistics-container">
            <!-- 使用 v-for 指令循环渲染物流列表 -->
            <!-- :key 是必须的,帮助 Vue 高效地更新列表 -->
            <div v-for="(item, index) in logisticsList" :key="index" class="logistics-item">
                <div class="time">{{ item.time }}</div>
                <div class="content">{{ item.content }}</div>
            </div>
            <p v-if="logisticsList.length === 0" style="color: #888;">暂无物流信息。</p>
        </div>
    </div>
    <script src="app.js"></script>
</body>
</html>

Vue 应用逻辑 (app.js)

Vue 的核心是创建一个“应用实例”,并管理其数据和方法。

// 从全局 Vue 对象中获取 createApp
const { createApp } = Vue;
// 创建 Vue 应用实例
const app = createApp({
    // data() 函数返回所有需要在模板中使用的数据
    data() {
        return {
            trackingNumberInput: 'SF1234567890', // 输入框绑定的数据
            trackingNumber: 'SF1234567890',      // 页面标题显示的数据
            logisticsList: [],                   // 存储物流信息的数组
            isLoading: false                     // 控制加载状态的标志
        }
    },
    // methods 对象中定义所有方法(事件处理函数等)
    methods: {
        async queryLogistics() {
            // 更新页面显示的单号
            this.trackingNumber = this.trackingNumberInput;
            // 显示加载状态
            this.isLoading = true;
            // 清空旧列表
            this.logisticsList = [];
            try {
                // 模拟 API 请求
                const mockApiResponse = new Promise((resolve) => {
                    setTimeout(() => {
                        resolve([
                            { time: '2025-10-27 15:22:00', content: '【深圳市】 快件已由 [快递员姓名] 送达,感谢使用顺丰速运,期待再次为您服务。' },
                            { time: '2025-10-27 10:30:00', content: '【深圳市】 快件已派送完毕,快件已由 [快递员姓名] 派送。' },
                            { time: '2025-10-27 08:15:00', content: '【深圳市】 快件到达 【深圳南山营业点】,快件将由快递员 [快递员姓名] 进行下一步派送。' },
                            { time: '2025-10-26 22:45:00', content: '【深圳市】 快件已到达 【深圳转运中心】,下一站 【深圳南山营业点】' },
                            { time: '2025-10-26 20:10:00', content: '【广州市】 快件已离开 【广州转运中心】,下一站 【深圳转运中心】' }
                        ]);
                    }, 1000);
                });
                const data = await mockApiResponse;
                // 请求成功,将数据赋值给 logisticsList
                // Vue 会检测到数据变化,并自动重新渲染视图
                this.logisticsList = data;
            } catch (error) {
                console.error('查询失败:', error);
                alert('查询失败,请稍后重试。');
            } finally {
                // 无论成功或失败,最后都关闭加载状态
                this.isLoading = false;
            }
        }
    },
    // 生命周期钩子,在实例创建完成后调用
    mounted() {
        // 页面加载时,自动执行一次查询
        this.queryLogistics();
    }
});
// 挂载应用,将 Vue 实例关联到 id 为 'app' 的 DOM 元素上
app.mount('#app');

Vue 的优势:

  • 数据驱动视图:你只需要修改 data 中的数据(如 this.logisticsList = newData),Vue 会自动、高效地更新对应的 DOM,无需手动 createElementappendChild
  • 声明式渲染:模板 (<template>) 清晰地描述了视图应该是什么样子,而不是如何操作 DOM 来变成那个样子。
  • 组件化:可以将快递信息列表、查询框等拆分成可复用的组件,使代码结构更清晰。
  • 响应式系统:Vue 的响应式系统能精确追踪数据变化,只更新变化的部分,性能优异。

总结与选择

方案 优点 缺点 适用场景
静态页面 简单直观,无依赖 无法获取实时数据,硬编码 学习入门、静态演示、数据固定不变的页面
原生 JS + Fetch 轻量,无需框架,掌握核心概念 手动操作 DOM,复杂应用中代码冗余 小型项目、快速原型、对性能要求极高的场景
现代框架 (Vue/React) 开发效率高,代码可维护性强,组件化 需要学习框架概念,有打包/构建步骤(Vue CLI, Vite) 中大型单页应用(SPA)、需要长期维护和迭代的复杂项目

对于初学者,建议从 方案一 开始理解 DOM 操作,然后学习 方案二 掌握异步请求和事件处理,当你需要开发更复杂的应用时,再学习 方案三 这样的现代框架。

-- 展开阅读全文 --
头像
天喜物流货单号怎么查?
« 上一篇 01-31
海门正余招聘信息有哪些岗位和要求?
下一篇 » 01-31

相关文章

取消
微信二维码
支付宝二维码

最近发表

网站分类

动态快讯

标签列表

目录[+]