【JS学习-封装思想--利用构造函数】以 嵌套选项卡 为例

本文介绍如何使用JavaScript的构造函数实现一个可复用的选项卡功能,通过事件绑定实现切换效果,同时允许外部设置容器尺寸。通过实例展示了嵌套选项卡的封装和动态结构生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用构造函数来 创建 一个工具类函数实现 选项卡

功能说明

  • 独立写的 html结构 与 css (待拓展优化-完全由JS控制生成)

  • JS提供构造函数 绑定事件 实现选项卡效果(鼠标点击或移入,卡片进行变换)

  • 选项卡容器长宽由 构造函数的方法提供接口

  • 效果截图展示
    在这里插入图片描述

codepen 源码效果展示

嵌套选项卡—封装思想–利用构造函数


源码

HTML

	<!-- 
		- 如使用构造函数,重复使用的HTML结构,单独设置class样式似乎不太合适?
			- 可行
			- 不过 选项卡样式 的长宽最好 可以外部来设置
			- 同时注意!!!---设置选项卡内部结构样式就要避免使用定宽了
	 -->
	<div class='tabContainer' id="tabContainer">
		<ul id='cardTab' class="cardTab">
			<li class="titItem active">电器</li>
			<li class="titItem">数码</li>
			<li class="titItem">家具</li>
			<li class="titItem">男孩</li>
		</ul>
		<ol id='cardContainer' class='cardContainer'>
			<li id='card' class="card">
				<div class='tabContainer' id="tabContainer2">
					<ul id='cardTab' class="cardTab">
						<li class="titItem active">电器</li>
						<li class="titItem">数码</li>
						<li class="titItem">家具</li>
						<li class="titItem">男孩</li>
					</ul>
					<ol id='cardContainer' class='cardContainer'>
						<li id='card' class="card">电器内容</li>
						<li id='card' class="card">数码内容</li>
						<li id='card' class="card">家具内容</li>
						<li id='card' class="card">男孩内容</li>
					</ol>
				</div>
			</li>
			<li id='card' class="card">数码内容</li>
			<li id='card' class="card">家具内容</li>
			<li id='card' class="card">男孩内容</li>
		</ol>
	</div>

css

		/* 公共设置 */
		*{
			margin:0;
			padding:0;
			box-sizing:border-box;
		}
		body{
			background-color:#eee;
			width:100vw;
			height:100vh;
			display:flex;
			justify-content:center;
			align-items:center;
		}
		li{
			list-style:none
		}
		/* 页面样式 */
		.tabContainer{
			background-color:#fff;
			/* UN 最好 暴露给外部来设置 */
			width:800px;
			height:600px;
			/* temp */
			width:80%;
			height:60%;

			padding: 30px 20px;
			border: 1px solid #ccc;
			display:flex;
			flex-direction:column;
			justify-content:center;
			align-items:center;
		}
		.cardTab{
			width: 100%;
			height: 20%;
			display: flex;
			justify-content: flex-start;
			margin-bottom: -1px;
		}
		.titItem{
			border:1px solid #ccc;
			display: inline-block;
			color: blue;
			float: left;
			margin-right:5px ;
			width: 15%;
			height: 100%;
			display:flex;
			justify-content:center;
			align-items:center;
		}
		.active{
			color: orangered;
			border-bottom:1px solid white;
			z-index: 99;
		}
		
		ol.cardContainer{
			width: 100%;
			height: 80%;
		}
		.card{
			width: 100%;
			height: 100%;
			display:none;
			justify-content:center;
			align-items:center;
			border:1px solid #ccc;
			
		}
		ol.cardContainer > li:first-child{			
			display: flex;
		}

JS

JS源码说明
  • 构造函数 TabNavF 有两个原型方法
    • 设置容器长宽updateWidthAndHeight
    • 执行绑定事件函数addEvent
/**
* Document Create By SAM9029 At 20200806 P.M. 17:50
* CreateNavProperty
* ProjectName:Nav
* 
* @param {String} _tabContainerName 导航容器的名称
* 
*/

// 私有化
(function() {
	function TabNavF(_tabContainerName){
		// 设置 初始化
	 	this.titleList = document.querySelectorAll(`${_tabContainerName}>#cardTab>li`);
		this.cardList = document.querySelectorAll(`${_tabContainerName}>#cardContainer>li`);		
		// 默认 绑定的事件 (外部访问可改)
		this.eventType = 'click'
		// 存储变量
		this.tabContainer= document.querySelector(_tabContainerName)		
	}
	
	/** 方法属性写在原型身上 
	* 修改容器高宽
	* 绑定事件
	* UN创建元素结构及样式(似乎直接写在构造函数内,直接执行比较好)
	*/ 
	
	// 修改容器高宽
	TabNavF.prototype.updateWidthAndHeight=function(_width,_height) {
		this.tabContainer.style.width = _width + 'px'
			this.tabContainer.style.height = _height + 'px'
	}
	
	// 绑定 事件 的方法
	TabNavF.prototype.addEvent=function(){
		/** 
		 * 此处this 指向 实例的对象本身 所以可调用
		 * 但是 之后绑定事件会改变 this 指向,所以要保存此处的this
		*/
		const _tabThis = this
	
		for(let i=0;i<_tabThis.titleList.length;i++){
			// 给所有span标签加onclick事件
			_tabThis.titleList[i].addEventListener(_tabThis.eventType,function(e){
				// 此处的 this 指向已改变 为 鼠标浮动的元素对象
				// console.log(this);
	
				// 遍历所有(即导航标题,卡片元素所在标签,清除历史)
				for(let j=0;j<_tabThis.titleList.length;j++){
					if(j!=i){
						// 将(除当前导航标题元素所在标签)的active类名删除
						_tabThis.titleList[j].classList.remove('active');
						// 将(除当前导航卡片元素所在标签)的display值改为none
						_tabThis.cardList[j].style.display='none';
					}
				}
				//给当前元素对象(即导航标题元素所在)标签加(触发)类名 
				e.target.classList.add('active');
				// 将当前卡片标签display值改为flex
				_tabThis.cardList[i].style.display='flex'
	
			})
		}
	}
	
	// 添加至 window属性,让外部使用
	window.TabNavF = TabNavF
})()


const tab1 = new TabNavF('#tabContainer')
// tab1.updateWidthAndHeight(800,600)
tab1.addEvent()

const tab2 = new TabNavF('#tabContainer2')		
tab2.eventType = 'mouseenter'
// tab2.updateWidthAndHeight(800,600)
tab2.addEvent()

待拓展

  将所有html + css 一起用 构造函数 生成
  封装成 真正的 可复用话 工具函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值