突破编程_前端_JS编程实例(网站标题栏TAB组件)

news2024/12/27 10:24:26

1 开发目标

实现如下网站标题栏 TAB 组件:
在这里插入图片描述

在点击"页面2"选项卡后,TAB 组件会切换对应的面板:
在这里插入图片描述

2 详细需求

网站标题栏 TAB 组件该组件需根据客户端提供的参数创建,具备动态构建 TAB 区域、选项卡切换及自定义内容显示等功能。

2.1 组件创建与初始化

类似于 echarts 等知名商业组件的创建与初始化方式,本组件需要根据客户端提供的参数 container 以及 para 进行创建和初始化。
container 是一个已存在的 DOM 元素(一般是 DIV),组件将在此元素内部构建 TAB 区域,包含选项卡以及 TAB 面板。
para 是本组件的配置参数,该对象应包含以下属性:

  • title:标题字符串,将显示在选项卡区域的最右侧。
  • titleFontProp:标题字符串的字体属性,包括字体大小、颜色等。
  • titleOffset:标题字符串两边的空白宽度,单位为像素。
  • height:选项卡的高度,单位为像素。
  • tabItemActiveColor:选项卡标题激活时下边框的颜色。
  • tabItemTitleFontProp:选项卡标题字符串的字体属性,包括字体大小、颜色等。
  • tabItemTitleOffset:选项卡标题字符串两边的空白宽度,单位为像素。
  • tabItems:一个包含选项卡对象的数组,每个对象应包含以下属性:
    • id:选项卡的唯一标识。
    • title:选项卡标题字符串。

2.2 TAB 区域构建

组件在初始化时,应在传入的 div 元素内部构建TAB区域。TAB 区域应包含标题栏和选项卡内容区。标题栏应显示 title 字符串和所有 TAB 选项卡标题。选项卡内容区应初始化为隐藏状态。

2.3 TAB 选项卡创建与切换

对于 tabs 数组中的每个对象,组件应创建一个对应的选项卡。每个选项卡应包含一个标题和一个面板 DIV。标题应显示 TAB 标题对象的 title 和 titleIcon 属性,并可根据 activeColor 属性改变下边框的颜色。对应的 TAB 面板在选项卡激活时应显示,否则隐藏。

初始状态下,应激活第一个 TAB 选项卡。客户端可以通过某种方式(如点击事件)切换激活的 TAB 选项卡。

2.4 自定义内容显示

客户端应能够获取到 TAB 选项卡面板容器,以便在其中添加自定义内容。组件提供了根据 id 获取选项卡面板容器的方法,使客户端能够方便地获取和操作选项卡面板内容。

3 代码实现

首先创建一个 neat_headertab.js 文件,该文件用于本组件的工具类、窗体部件基类以及各个实现类的代码构建。

在具体的业务代码编写之前,先实现一个工具类以及一些工具方法,方便后面调用:

class CommonUtil {

    // 设置 DIV 中的文字为水平与垂直居中
    static centerTextInDiv(container) {
        container.style.display = 'flex';
        container.style.textAlign = 'center';
        container.style.justifyContent = 'center';
        container.style.flexDirection = 'column';
    }
}

该工具类中包含一个可以将 DIV 中的文字设置为水平与垂直居中的静态方法。

接下来,定义一个通用的显示窗体的基类:

class NeatBaseWid {
    constructor(container, para) {
        this.container = container;	// 接收调用者传入的 DOM 元素(一般是 DIV)
        this.para = para;	// 保存调用者传入的 para 对象
    }
}

然后开始定义选项卡类型:

class NeatHeaderTabItem extends NeatBaseWid {

    static TITLE_OFFSET = "20px";     // 默认标题字符串两边的空白宽度
    static TITLE_FONTSIZE = "18px";     // 默认标题字符串的字体大小
    static TITLE_COLOR = "#000";     // 默认标题字符串字体颜色
    static ACTIVE_COLOR = "#000";     // 默认选项卡标题激活时下边框的颜色

    constructor(container, panelContainer, para) {
        super(container, para);
        this.panelContainer = panelContainer;   // 面板容器,用于显示调用者定义的界面
        this.render();
    }

上面代码定义了 NeatHeaderTabItem 的一些默认属性,并且创建构造函数,该函数接收调用者传入的 DIV 容器,并且调用 render 方法。
render 方法如下:

	render() {
        this.container.innerHTML = '';  // 清空容器
        this.container.style.cursor = 'pointer';
        let titleOffset = this.para.titleOffset ?? NeatHeaderTabItem.TITLE_OFFSET;
        this.container.style.paddingLeft = titleOffset;
        this.container.style.paddingRight = titleOffset;
        this.container.style.fontSize = (this.para.titleFontProp && this.para.titleFontProp.fontSize) ?? this.TITLE_FONTSIZE;
        this.container.style.color = (this.para.titleFontProp && this.para.titleFontProp.color) ?? this.TITLE_COLOR;
        this.container.innerText = this.para.title;
        CommonUtil.centerTextInDiv(this.container);

        // 点击选项卡的触发动作
        let that = this;
        this.container.onclick=function(){
            that.para.onClickFunc.call(that.para.onClickObj,that);
        }
    }

该方法除了完成选项卡的渲染逻辑之外,还为选项卡添加点击事件,当点击选项卡时,会调用 para.onClickFunc 函数,并将选项卡对象的本体作为参数传递。
NeatHeaderTabItem 还提供了选项卡激活与选项卡非激活两个对外的接口:

	// 选项卡激活
    activate() {
        this.container.style.borderBottom = '2px solid ' + this.para.activeColor ?? NeatHeaderTabItem.ACTIVE_COLOR;
        this.panelContainer.style.display = 'block';
    }

    // 选项卡非激活
    deactivate() {
        this.container.style.borderBottom = '2px solid #ffffff'
        this.panelContainer.style.display = 'none';
    }

}

之后,开始定义 TAB 组件的主体类型:NeatHeaderTabWidget

class NeatHeaderTabWidget extends NeatBaseWid {

    static TAB_HEIGHT = "50px";     // 默认选项卡的高度
    static TITLE_OFFSET = "50px";     // 默认标题字符串两边的空白宽度
    static TITLE_FONTSIZE = "20px";     // 默认标题字符串的字体大小
    static TITLE_COLOR = "#000";     // 默认标题字符串字体颜色

    constructor(container, para) {
        super(container, para);
        this.tabContainer = null;   // 选项卡栏
        this.panelContainer = null;   // 面板容器
        this.tabItems = [];          // 选项卡集合
        this.activeTabItem = null;          // 当前激活的选项卡
        this.tabPanelMap = new Map();          // 选项卡面板容器的 map
        this.render();
    }

上面代码同样定义了 NeatHeaderTabWidget 的一些默认属性,并且创建构造函数,该函数接收调用者传入的 DIV 容器,并且调用 render 方法。
render 方法如下:

    render() {
        // 清空容器
        this.container.innerHTML = '';
        // 创建选项卡栏
        this.tabContainer = document.createElement('div');
        this.tabContainer.style.width = '100%';
        this.tabContainer.style.height = this.para.height ?? NeatHeaderTabWidget.TAB_HEIGHT;
        this.tabContainer.style.display = 'flex';
        this.container.appendChild(this.tabContainer);
        // 创建面板容器
        this.panelContainer = document.createElement('div');
        this.panelContainer.style.width = '100%';
        this.panelContainer.style.height = 'calc( 100% - ' + this.tabContainer.style.height + ' )';
        this.container.appendChild(this.panelContainer);

        // 创建标题栏
        let titleContainer = document.createElement('div');
        let titleOffset = this.para.titleOffset ?? NeatHeaderTabWidget.TITLE_OFFSET;
        titleContainer.style.marginLeft = titleOffset;
        titleContainer.style.marginRight = titleOffset;
        titleContainer.style.fontSize = (this.para.titleFontProp && this.para.titleFontProp.fontSize) ?? NeatHeaderTabWidget.TITLE_FONTSIZE;
        titleContainer.style.color = (this.para.titleFontProp && this.para.titleFontProp.color) ?? NeatHeaderTabWidget.TITLE_COLOR;
        titleContainer.style.fontWeight = 'bold'; // 标题默认是加粗
        titleContainer.style.letterSpacing = '4px'; // 文本间距
        titleContainer.innerText = this.para.title;
        CommonUtil.centerTextInDiv(titleContainer);
        this.tabContainer.appendChild(titleContainer);

        // 创建选项卡
        this.para.tabItems.forEach(element => {
            let tabItemContainer = document.createElement('div');
            this.tabContainer.appendChild(tabItemContainer);
            let panelContainer = document.createElement('div');
            panelContainer.style.width = '100%';
            panelContainer.style.height = '100%';
            panelContainer.style.display = 'none';
            this.panelContainer.appendChild(panelContainer);
            element.activeColor = this.para.tabItemActiveColor;
            element.titleFontProp = this.para.tabItemTitleFontProp;
            element.titleOffset = this.para.tabItemTitleOffset;
            element.onClickFunc = this.tabChange;
            element.onClickObj = this;
            let tabItem = new NeatHeaderTabItem(tabItemContainer, panelContainer, element);
            this.tabItems.push(tabItem);
            this.tabPanelMap.set(element.id,tabItem.panelContainer);
        });

        if (this.tabItems.length > 0) {
            this.tabItems[0].activate();
            this.activeTabItem = this.tabItems[0];
        }
    }

该方法完成了创建选项卡栏、创建面板容器、创建标题栏以及创建选项卡等核心渲染逻辑。
最后 NeatHeaderTabWidget 对外提供了选项卡切换以及根据 id 获取选项卡面板容器的方法:

	// 选项卡切换
    tabChange(tabItem) {
        this.tabItems.forEach(element => {
            element.deactivate();
        });
        tabItem.activate();
        this.activeTabItem = tabItem;
    }

    // 根据 id 获取选项卡面板容器
    getTabPanelFromId(id){
        if(this.tabPanelMap.has(id)){
            return this.tabPanelMap.get(id);
        }else{
            return null;
        }
    }
}

完成 TAB 组件的代码编写后,可以创建 neater_headertab.html 文件,调用 TAB 组件

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>header tab</title>
    <style>
        html {
            height: 100%;
        }

        body {
            margin: 0;
            height: 100%;
        }
    </style>
</head>

<body>
    <div id="divMain" style="height: 100%;width: 100%;"></div>
</body>
<script src="./neat_headertab.js"></script>
<script>
    let para = {
        "title": "网站标题",
        "titleFontProp": {
            "fontSize": "26px",
            "color": "#ea6f5a",
        },
        "titleOffset": "100px",
        "height": "50px",
        "tabItemActiveColor": "#ea6f5a",
        "tabItemTitleFontProp": {
            "fontSize": "17px",
            "color": "#333",
        },
        "tabItemTitleOffset": "20px",
        "tabItems": [
            {
                "id": "tabItem1",
                "title": "页面1",
            },
            {
                "id": "tabItem2",
                "title": "页面2",
            },
            {
                "id": "tabItem3",
                "title": "页面3",
            },
            {
                "id": "tabItem4",
                "title": "页面4",
            },
        ]
    }
    let headerTabWidget = new NeatHeaderTabWidget(document.getElementById('divMain'), para);
    let panel1 = headerTabWidget.getTabPanelFromId('tabItem1');
    panel1.style.backgroundColor = '#ADD8E6';
    panel1.innerText='页面1';
    let panel2 = headerTabWidget.getTabPanelFromId('tabItem2');
    panel2.style.backgroundColor = '#E1FFFF';
    panel2.innerText='页面2';
</script>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django模型进阶(Mysql配置、模型管理,表关联、一对一、一对多,多对多)

模型进阶&#xff1a; Mysql配置&#xff1a; 1.安装mysql 2安装MySQL驱动&#xff0c;使⽤mysqlclient pip install mysqlclient pip install -i https://pypi.douban.com/simple mysqlclientLinux Ubuntu下需要先安装&#xff1a;apt install libmysqld-dev 再安装: apt…

[BJDCTF2020]EzPHP1 --不会编程的崽

有一说一&#xff0c;这题还是有难度的 base32解码url编码绕过$_SERVER换行符绕过preg_match相同参数&#xff0c;post请求覆盖get请求&#xff0c;绕过$_REQUESTphp伪协议利用sha1数组绕过create_function代码注入 Level 1 右键源码里又发现&#xff0c;拿去base32解码即可…

w30使用python调用shell脚本

使用python脚本去实现永恒之蓝漏洞攻击 实验环境 攻击工具&#xff1a;pythonmsfconsole 靶场&#xff1a;win7 和 kali实验目的 演示python脚本调用过程 实验步骤 1.写一个永恒之蓝的攻击脚本&#xff0c;定义为blue.rc use exploit/windows/smb/ms17_010_eternalblue …

Microsoft PyRIT能自动化完成AI红队的任务

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【算法集训】基础算法:枚举

一、基本理解 枚举的概念就是把满足题目条件的所有情况都列举出来&#xff0c;然后一一判定&#xff0c;找到最优解的过程。 枚举虽然看起来麻烦&#xff0c;但是有时效率上比排序高&#xff0c;也是一个不错的方法、 二、最值问题 1、两个数的最值问题 两个数的最小值&…

【Android】View事件体系基础

文章目录 坐标系View滑动layout方法offserLeftAndRight() 和 offsetTopAndBottom()LayoutParams(布局参数)View动画scrollTo/scrollBy 解析Activity的构成 坐标系 分为Android坐标系和View坐标系 可以用 getWidth() 和 getHeight() 获取View自身的宽度和高度 对于ViewgetX() …

求Sn=a+aa+aaa+aaaa+aaaaa的前n项之和

求Snaaaaaaaaaaaaaaa的前5项之和&#xff0c;其中a是一个数字&#xff0c; 例如&#xff1a;222222222222222 int main() {int a;scanf("%d", &a);int n;scanf("%d", &n);int sum 0;int tmp 0;for (int i 0; i < n; i){tmp tmp * 10 a;sum…

bxCAN总线的工作模式和测试模式(STM32F4xx)

概述 本文主要介绍STM32F4XX的bxCAN知识&#xff0c;包括bxCAN的概念&#xff0c;各种工作模式下特性&#xff0c;如何配置各类工作模式等内容&#xff0c;还介绍了bxCAN的测试模式&#xff0c;bxCAN测试模式有3种工作类型&#xff0c;每种类型有什么特性&#xff0c;以及如何配…

C语言之指针习题一

1. 解析&#xff1a;全选 2. 解析&#xff1a;A.当内存空间释放后&#xff0c;指针将指向其他的区域&#xff0c;成为野指针 3. 解析&#xff1a;B&#xff0c;assert只会在调试模式&#xff08;debug&#xff09;下使用&#xff0c;release不会使用 4. 解析&#xff1a; A…

IDEA集成Tomcat服务器指南

目录 一.概述 二.下载安装 三.启动Tomcat服务器 四.修改端口号 五.Maven Web项目 六.创建项目 1.使用骨架 2.不使用骨架 七.Idea中集成Tomcat 1.集成本地Tomcat 2.使用Maven插件 一.概述 所谓的Web服务器软件&#xff0c;功能是对HTTP协议的操作进行封装&#xff0…

ros2的nav2_map_server导入地图时,rviz2显示no map received

ros2的nav2_map_server导入地图时&#xff0c;rviz2显示no map received 步骤&#xff1a; 1、打开终端&#xff0c;进入src/map/运行下面指令&#xff1a; ros2 run nav2_map_server map_server --ros-args --param yaml_filename:fishbot_map.yaml2、打开rviz2 rviz2通过a…

leetcode 热题 100_无重复字符的最长子串

题解一&#xff1a; 滑动窗口哈希表&#xff1a;假设字符串为"abcabcbb"&#xff0c;遍历循环所有子串&#xff0c;以不同位置作为子串的起始&#xff0c;则会得到以下最长子串。其中最长子串的右端点会随着左端点的右移而右移&#xff0c;也可能不变&#xff0c;原因…

跨平台指南:在 Windows 和 Linux 上安装 OpenSSL 的完整流程

Windows安装 一&#xff1a;找到安装包&#xff0c;双击即可 https://gitee.com/wake-up-again/installation-package.git 二&#xff1a;按照提示&#xff0c;一步一步来&#xff0c;就可以啦 三&#xff1a;此界面意思是&#xff0c;是否想向创作者捐款&#xff0c;自己视情…

访问修饰符、Object(方法,使用、equals)、查看equals底层、final--学习JavaEE的day15

day15 一、访问修饰符 含义&#xff1a; 修饰类、方法、属性&#xff0c;定义使用的范围 理解&#xff1a;给类、方法、属性定义访问权限的关键字 注意&#xff1a; ​ 1.修饰类只能使用public和默认的访问权限 ​ 2.修饰方法和属性可以使用所有的访问权限 访问修饰符本类本包…

消息中间件之RocketMQ源码分析(二十八)

延迟消息存储机制 概述 什么是延迟消息呢?延迟消息也叫定时消息&#xff0c;一般地&#xff0c;生产者在发送消息后&#xff0c;消费者希望在指定的一段时间后再消费。常规做法是&#xff0c;把信息存储在数据库中&#xff0c;使用定时任务扫描&#xff0c;符合条件的数据再…

js字符串转json的3种方法

1.eval方式解析 function strToJson(str){var json eval("(" str ")");return json;}console.log(strToJson("{int:1, string:demo}")); 运行截图&#xff1a; 注&#xff1a; 记得别忘了str两旁的小括号。 永远不要使用 eval !!! eval() 是一…

最短路径(2.19)

目录 1.网络延迟时间 弗洛伊德算法 迪杰斯特拉算法 2. K 站中转内最便宜的航班 3.从第一个节点出发到最后一个节点的受限路径数 4.到达目的地的方案数 1.网络延迟时间 有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的…

3、JavaWeb-Ajax/Axios-前端工程化-Element

P34 Ajax介绍 Ajax:Asynchroous JavaScript And XML&#xff0c;异步的JS和XML JS网页动作&#xff0c;XML一种标记语言&#xff0c;存储数据&#xff0c; 作用&#xff1a; 数据交换&#xff1a;通过Ajax给服务器发送请求&#xff0c; 并获取服务器响应的数据 异步交互&am…

C++ //练习 10.24 给定一个string,使用bind和check_size在一个int的vector中查找第一个大于string长度的值。

C Primer&#xff08;第5版&#xff09; 练习 10.24 练习 10.24 给定一个string&#xff0c;使用bind和check_size在一个int的vector中查找第一个大于string长度的值。。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*****…

VsCode配置PCL、Open3D自动补全

写在前面 本文内容 在VsCode上开发PCL、Open3D相关代码&#xff0c;代码自动补全 Open3D、PCL的安装使用见各个版本的Open3D、PCL的编译、使用教程 平台/环境 windows11(windows10): visual studio 2022&#xff1b;cmake 3.22; VsCode 通过cmake构建项目&#xff1b; 转载请…