这是我的第一篇博客 博客生涯才开始 然而人生曾经过来了二十个年头了 才开始弄这个 也没搞得太懂 我本来的想法是想搞个源代码上来 然而看了半天如同就只能传 html 源代码 那我还有 css js 的局部呢 我还想给大伙看看性能呢 其实我老早就想开个博客了 始终没找到在哪里来弄 学倒是始终在学 就这么学下来了 从 html css h5c3 挪动端适配 js 根本语法 jQuery 到当初的 js 高级语法 es6 只不过后面如同也没什么须要讲的 当初才刚刚 开始 明天搞了个 面向对象版的 tab 栏 整点图片 上来把 我的话和教训也都在图片里 老手老手
HTML
<!DOCTYPE html>
<html lang="en">
<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> 面向对象 Tab</title>
<link rel="stylesheet" href="./styles/tab.css">
<link rel="stylesheet" href="./styles/style.css">
</head>
<body>
<main>
<h4>
Js 面向对象 动静增加标签页
</h4>
<div class="tabsbox" id="tab">
<!-- tab 标签 -->
<nav class="fisrstnav">
<ul>
<li class="liactive"><span> 测试 1 </span><span class="iconfont icon-guanbi"></span></li>
<li><span> 测试 2 </span><span class="iconfont icon-guanbi"></span></li>
<li><span> 测试 3 </span><span class="iconfont icon-guanbi"></span></li>
</ul>
<div class="tabadd">
<span>+</span>
</div>
</nav>
<!-- tab 内容 -->
<div class="tabscon">
<section class="conactive"> 测试 1 </section>
<section> 测试 2 </section>
<section> 测试 3 </section>
</div>
</div>
</main>
<script src="./js/index.js"></script>
</body>
</html>
JS
// 剖析 整个 tab 栏就是他的对象 而后下来有 切换 新增 删除 批改的内容
var that
class Tab {constructor(id) {
that = this
// 1. 获取元素
this.main = document.querySelector(id)
/* // 2. 切换性能 先获取 li 和 section
this.lis = this.main.querySelectorAll('.fisrstnav li')
this.sections = this.main.querySelectorAll('section') */
// 3. 新增性能 获取元素
this.add = this.main.querySelector('.tabadd')
this.ul = this.main.querySelector('ul')
this.fsections = this.main.querySelector('.tabscon')
this.init()}
// 3.5 获取最新的 li 和 section
updateTogle() {this.lis = this.main.querySelectorAll('.fisrstnav li')
this.sections = this.main.querySelectorAll('section')
// 4. 获取删除按钮 因为这个也是也始终在动静减少的 所以须要动静获取
this.removes = this.main.querySelectorAll('.icon-guanbi')
// 5.1 动静获取第一个 span 的标签
this.spans = this.main.querySelectorAll('li span:first-child')
}
// 2.1 初始化函数 因为页面一刷新就会要绑定事件 须要一实例化 就绑定事件 就要一个初始化函数在构造函数里被调用
init() {
// 3.5 获取最新数据
this.updateTogle()
// 3.1 新增按钮就一个 所以不须要写在循环里、this.add.onclick = this.addTab
// 2.2 给 lis 绑定点击事件
for (var i = 0; i < this.lis.length; i++) {
// 2.4 要实现对应的 section 的切换 须要给每个 li 增加一个 index
this.lis[i].setAttribute('data-index', i)
this.lis[i].onclick = this.toggleTab
// 4.1 删除按钮点击事件
this.removes[i].onclick = this.removeTab
// 5. 增加性能就是 对 li section 做操作 就不须要获取了 间接绑定双击事件
this.spans[i].ondblclick = this.insertTab
this.sections[i].ondblclick = this.insertTab
}
}
// 2.4 给其余事件清空类名操作 因为前面可能还会用到 封装一个函数
clearClass() {for (var i = 0; i < this.lis.length; i++) {this.lis[i].classList.remove('liactive')
that.sections[i].classList.remove('conactive')
}
}
// 切换
toggleTab() {that.clearClass()
// 2.3 在这外面实现切换性能 留神以后的 this 为点击的这个 li
this.classList.add('liactive')
var index = this.getAttribute('data-index')
// 留神 这个时候不能用 this 要用 controcutor 外面的 this
that.sections[index].classList.add('conactive')
}
// 新增
addTab() {
// 3.2 点击新增就会减少一个 li
var li = '<li class="liactive"><span> 新选项卡 </span><span class="iconfont icon-guanbi"></span></li>'
that.ul.insertAdjacentHTML('beforeend', li)
// 3.3 同时新增一个 section
var radom = Math.random()
var section = '<section class="conactive"> 测试'+radom+'</section>'
that.fsections.insertAdjacentHTML('beforeend', section)
// 3.4 因为新增过后就须要到新增的选项卡外面来 所以 就要从新清空类名
that.clearClass()
// 3.5 间断点多个新增 前面新增的全是选中状态的起因 新增一次过后就要从新执行一次初始化 获到最新的 li 和 section
that.init()}
// 删除
removeTab(e) {e.stopPropagation()
// 4.2 点一次删除 就会把以后的父元素删掉
var index = this.parentNode.getAttribute('data-index')
this.parentNode.remove()
// 同时把 section 删掉
that.sections[index].remove()
// 删除一个 应该跳转到前一个选项卡
// 疑难点:这里遇到了做下来的第一个艰难点 我一看代码始终在寻思没什么没问题啊 但就是不能实现点击事件 起初才发现是因为此处有个冒泡事件 先执行了那个就点击在原地两个相互作用才呈现了问题 敞开冒泡事件即可
// that.lis[index - 1].click()
// 4.3 删除到第一个会报错 这里能够利用与的短路运算 后面为 true 就执行前面 后面为 false 就执行后面
// that.lis[index - 1] && that.lis[index - 1].click()
// 此处还是有点小瑕疵 就是当我点击选项一的时候 我去删除选项三 删完过后 它会主动跳到选项二 失常应该放弃不动就能够
// 忽然想到这里如果有 jq 的 hasclass 办法就难受了
if (this.parentNode.classList[0] == 'liactive') {that.lis[index - 1] && that.lis[index - 1].click()}
}
// 批改
insertTab() {
// 勾销双选选中文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty()
// 5.1 双击过后把第一个 span 里的内容改为文本框
var str = this.innerHTML
this.innerHTML = '<input type=“text”>'
// 5.2 变文本框之后应该把 span 的值给到文本框外面
this.children[0].value = str
// 5.3 失去焦点后 把 input 的值给到 innerhtml -----------------------time---------------------------
this.children[0].onblur = function() {this.parentNode.innerHTML = this.value}
}
}
new Tab('#tab')
CSS
不重要的 css 局部 可疏忽
* {
margin: 0;
padding: 0;
}
ul li {list-style: none;}
main {
width: 960px;
height: 500px;
border-radius: 10px;
margin: 50px auto;
}
main h4 {
height: 100px;
line-height: 100px;
text-align: center;
}
.tabsbox {
width: 900px;
margin: 0 auto;
height: 400px;
border: 1px solid lightsalmon;
position: relative;
}
nav ul {overflow: hidden;}
nav ul li {
float: left;
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
border-right: 1px solid #ccc;
position: relative;
}
nav ul li.liactive {
border-bottom: 2px solid #fff;
z-index: 9;
}
#tab input {
width: 80%;
height: 60%;
}
nav ul li span:last-child {
position: absolute;
user-select: none;
font-size: 12px;
top: -18px;
right: 0;
display: inline-block;
height: 20px;
}
.tabadd {
position: absolute;
/* width: 100px; */
top: 0;
right: 0;
}
.tabadd span {
display: block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border: 1px solid #ccc;
float: right;
margin: 10px;
user-select: none;
}
.tabscon {
width: 100%;
height: 300px;
position: absolute;
padding: 30px;
top: 50px;
left: 0px;
box-sizing: border-box;
border-top: 1px solid #ccc;
}
.tabscon section,
.tabscon section.conactive {
display: none;
width: 100%;
height: 100%;
}
.tabscon section.conactive {display: block;}
前端爱好者,望大佬给个内推机会!!!