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

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();          // 选项卡面板容器的 mapthis.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.hqwc.cn/news/508551.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dockerfile构建过程详解

Dockerfile介绍 docker是用来构建docker镜像的文件&#xff01;命令参数脚本&#xff01; 构建步骤&#xff1a; 1、编写一个dockerfile文件 2、docker build构建成为一个镜像 3、docker run 运行镜像 …

MySql表子查询

目录 表子查询数据准备 表子查询 子查询返回的结果是多行多列&#xff0c;常作为临时表&#xff0c;这种子查询称为表子查询。 案例&#xff1a;查询入职日期是 “2006-01-01” 之后的员工信息 , 及其部门信息 分解为两步执行&#xff1a; 查询入职日期是 “2006-01-01” 之后…

css 鼠标移入放大的效果

效果 HTML <div class"img-wrap"><img class"img-item" src"../assets/1.png" alt"" srcset""></div> CSS <style lang"less" scoped> .img-wrap {/* 超出隐藏 */overflow: hidden;.img-…

WebSocket介绍+3分钟时间使用WebSocket搭建属自己的聊天室

WebSocket 的由来 在 WebSocket 出现之前&#xff0c;我们想实现实时通信、变更推送、服务端消息推送功能&#xff0c;我们一般的方案是使用 Ajax 短轮询、长轮询两种方式&#xff1a;比如我们想实现一个服务端数据变更时&#xff0c;立即通知客户端功能&#xff0c;没有 WebS…

【LeetCode题解】2809. 使数组和小于等于 x 的最少时间+2788. 按分隔符拆分字符串+410. 分割数组的最大值

文章目录 [2809. 使数组和小于等于 x 的最少时间](https://leetcode.cn/problems/minimum-time-to-make-array-sum-at-most-x/)思路&#xff1a; [2788. 按分隔符拆分字符串](https://leetcode.cn/problems/split-strings-by-separator/)思路&#xff1a; [410. 分割数组的最大…

设计模式(十三)抽象工厂模式

请直接看原文:设计模式&#xff08;十三&#xff09;抽象工厂模式_抽象工厂模式告诉我们,要针对接口而不是实现进行设计。( )-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- …

通信原理:通信的基本概念(第一节课)

1.通信的基本概念 1.1消息&#xff0c;信息与信号 我们先看一个调幅AM无线广播系统 我们信号举个例子&#xff1a; 可以看出&#xff0c;我们研究的参量不一样&#xff0c;对应的模拟和数字信号也会与我们看上去的不同。 信息&#xff1a; 生活中的例子来认识一下&#xff1…

Python——桌面摄像头软件(附源码+打包)

目录 一、前言 二、桌面摄像头软件 2.1、下载项目 2.2、功能介绍 三、打包工具&#xff08;nuitka&#xff09; 四、项目文件复制&#xff08;我全部合到一个文件里面了&#xff09; 五、结语 一、前言 看见b站的向军大叔用electron制作了一个桌面摄像头软件 但是&#x…

LabVIEW起重机工作参数远程监测系统

LabVIEW起重机工作参数远程监测系统 随着起重机技术的持续发展&#xff0c;对其工作参数的实时监控需求日益增加。设计了一个基于LabVIEW和TBox的起重机工作参数远程监测系统&#xff0c;能够实现起重机工作参数的实时采集、传输、解析和显示&#xff0c;有效提升起重机的性能…

自动化测试介绍、selenium用法(自动化测试框架+爬虫可用)

文章目录 一、自动化测试1、什么是自动化测试&#xff1f;2、手工测试 vs 自动化测试3、自动化测试常见误区4、自动化测试的优劣5、自动化测试分层6、什么项目适合自动化测试 二、Selenuim1、小例子2、用法3、页面操作获取输入内容模拟点击清空文本元素拖拽frame切换窗口切换/标…

【计算机网络】HTTPS 协议原理

https 一、HTTPS 是什么二、加密1. 加密概念2. 加密的原因3. 常见的加密方式&#xff08;1&#xff09;对称加密&#xff08;2&#xff09;非对称加密 三、数据摘要(数据指纹)四、HTTPS 的工作原理探究1. 只使用对称加密2. 只使用非对称加密3. 双方都使用非对称加密4. 非对称加…

信息系统项目管理师--项目立项管理

项⽬⽴项管理是对拟规划和实施的项⽬技术上的先进性、适⽤性&#xff0c;经济上的合理性、效益性&#xff0c;实施上的可能性、⻛险性以及社会价值的有效性、可持续性等进⾏全⾯科学的综合分析&#xff0c; 为项⽬决策提供客观依据的⼀种技术经济研究活动 项⽬建议与⽴项申请、…