使用构造函数来 创建 一个工具类函数实现 选项卡
功能说明
-
独立写的 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 一起用 构造函数 生成
封装成 真正的 可复用话 工具函数