js实现tab栏切换,并实现增,删,改,查
html样式
<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>
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;
}
style.css
@font-face {
font-family: "iconfont";
src: url("./iconfont/iconfont.eot?t=1553960438096");
/* IE9 */
src: url("./iconfont/iconfont.eot?t=1553960438096#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAK4AAsAAAAABmwAAAJrAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAp4fwE2AiQDCAsGAAQgBYRtBzAbpQXIrrApw71oi3CCOyzEy8RvE4yIN8TD036/zp03qCYRjaJZNBFFS/gREoRGipQKofjuNrb+9XbTqrmXcqWzfTRDqFqWkhAJzYToaE6LQ7Q30CirRqSKMnj58DdIdrNAdhoTQJa5VGfLrtiAy+lPoAcZdUC57UljTR4TMAo4oL0xiqwYG8YueIHPCdTqYajty/t+bUpmrwvEnUK42lQhLMssVy1UNhzN4kmF6vSQVvMY/T5+HEU1SUXBbti7uBBrx++cgqJULp0GhAgBna5AgSkgE0eN6R1NwTitNt0yAI5VG7wr/8AljmoX7K+zq+tBF1Q8k9JTPWp1AjnJDgCzmM3bU0V31dsvV3M2eC6fHjaGfX/qS7U5Gr58vj6uD0bgxudyrV/OtHHyP+NZnpO1txbktjdY+3FB61+7nxeOzq8niGYnRwT3v3aZxeXf6rrNxl5//49WlEtZUUL1Pj3Bv1EO7MuG2namrCkbvcnApLUJtWpRhv2tzlRLx43kQ7WO2/FW6c5QqDZEZnYKFeosoVK1NdSa5E/XaVM1Ra7BhAEQmk0kjV5QaLbIzG5U6HRRqTkK1DqJtivrjMT1zJaNnIsihAiyQE3JdbszcW0Xiadzdl4d8UO0HSUGNDNXzl2hifYSO5pPjrorgdjUAAavoa5TKDZVUXD3kuuOOzh70fShvUiN2owtNsRxIREIIiATUCYpGO2aqXy/CxEeHcfuaKrLDiGbQ5kcEMsNIK8M5qCmR3mn8RFHOpcECBtlAAwWIZ2OAqV5kQoJXHvShORYBzrDZKhhb3uT8QPlrA3bmsKZV6i89DiTV2o1AAAA") format("woff2"), url("./iconfont/iconfont.woff?t=1553960438096") format("woff"), url("./iconfont/iconfont.ttf?t=1553960438096") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url("./iconfont/iconfont.svg?t=1553960438096#iconfont") format("svg");
/* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-guanbi:before {
content: "\e676";
}
js样式
var that = null;
class Tab {
constructor(id) {
// that 以后就是实例对象 tab
that = this;
// 获取最外面的包裹,注意 id 不要加引号
this.main = document.querySelector(id);
// 获取添加按钮
this.add = this.main.querySelector('.tabadd');
// 标题的包裹
this.ul = this.main.querySelector('.fisrstnav ul');
// 内容的包裹
this.con = this.main.querySelector('.tabscon');
// 构造函数中的 this 就是实例,就是 tab
this.init();
}
init() {
// 每次添加完之后要重新【获取所有的标题和内容】,并且【重新绑定事件】
this.updateNode();
this.add.onclick = this.addTab;
// this.add.ul
// this.add.con
// 点击标题输出对应的索引
for(var i = 0; i < this.lis.length; i ++) {
// 给每一个标题先准备索引
this.lis[i].index = i;
this.lis[i].onclick = this.changeTab;
this.removes[i].onclick = this.removeTab;
this.spans[i].ondblclick = this.editTab;
this.sections[i].ondblclick = this.editTab;
}
}
updateNode() {
// 获取所有标题
this.lis = this.main.querySelectorAll('li');
// 获取所有内容
this.sections = this.main.querySelectorAll('section');
// 删除
this.removes = this.main.querySelectorAll('.icon-guanbi');
// 编辑
this.spans = this.main.querySelectorAll('.fisrstnav li span:first-child');
}
// 1. 切换
changeTab() {
// 先干掉其他的
that.clearAll();
// 再操作自己
this.className = "liactive";
// 让【所有内容】当中和【当前点击索引】对应的哪一个出来
that.sections[this.index].className = "conactive";
}
clearAll() {
// 方法中的 this,谁调用就是谁
// 这里就是 that 调用的 clearAll,所以这里的 this 就是 that,而 that 就是 tab,就是实例对象,实例对象什么都有,当然也有 lis、sections
for(var i = 0; i < this.lis.length; i ++) {
this.lis[i].className = "";
this.sections[i].className = "";
}
}
// 2. 添加
addTab() {
// 添加之前先取消之前的高亮,和隐藏之前的内容
that.clearAll();
var r = Math.random().toString().substring(0, 5);
var li = `<li class="liactive"><span>${r}</span><span class="iconfont icon-guanbi"></span></li>`;
var con = `<section class="conactive">${r}</section>`;
// 添加到元素内容的最后
that.ul.insertAdjacentHTML('beforeend', li);
that.con.insertAdjacentHTML('beforeend', con);
// 每次添加完之后要重新【获取所有的标题和内容】,并且【重新绑定事件】
that.init();
}
// 3. 删除
removeTab(e) {
// 阻止冒泡,防止 li 也触发点击
e.stopPropagation();
// 找到要删除的是哪一个
var idx = this.parentNode.index;
// 只需要从【所有的标题和内容】里面找【对应的这一个】并干掉就好啦
that.lis[idx].remove(); // remove() 就是“自杀”
that.sections[idx].remove();
that.init(); // 删除完毕后更新所有的选择元素
// 删除完毕后如果有被选中的,说明我删除的不是选中的那个,就没有必要让前一个激活了
if (document.querySelector('.liactive')) return;
idx--;
// 保证要删除的这个元素是存在的才进行删除
that.lis[idx] && that.lis[idx].click();
}
// 4. 编辑
editTab() {
// 双击禁止选定文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
// 双击时候的文字
var str = this.innerHTML; // <input type="xx"/>
this.innerHTML = '<input type="text"/>';
var input = this.children[0];
// 把 双击时候的文字 给 input 框的 value
input.value = str;
// 先获取焦点
input.focus();
// 获取焦点之后再选中文字
input.select();
input.onblur = function() {
// 把 input 框的 value 给span 的 innerHTML
this.parentNode.innerHTML = this.value;
};
// 回车的时候也进行上述操作
input.onkeyup = function(e) {
if (e.keyCode === 13) {
// 主动触发离开事件
this.blur();
}
};
// 防止在 input 里面再次进行双击,会冒泡到 span 上面,再次触发span 的双击,出现 Bug
input.ondblclick = function(e) {
e.stopPropagation();
};
}
}
// tab 具有 Tab 的各种属性和方法
var tab = new Tab('#tab');
// tab.init();