Tabs are often used in web pages, so how to implement tabs?
In the current framework, dom operation is omitted, and developers only need to pay attention to data. Is it really unnecessary to operate dom? Yes, it is necessary, but the program has helped to do this, and pure data logic will make the front end more difficult.
Overall structure
<div class="app" id="app"> <div class="key-left"> <div class="tap">1</div> <div class="tap">2</div> <div class="tap">3</div> <div class="tap">4</div> <div class="tap">5</div> </div> <div class="key-value"> <div class="value"></div> <div class="value"></div> <div class="value"></div> <div class="value"></div>A <div class="value"></div> </div> </div> <script> let app = document.getElementById("app"); let tap = app.getElementsByClassName("tap"); let value = app.getElementsByClassName("value"); let color = ['red','green','blue','yellow','pink']; for(let i = 0;i<value.length;i++){ value[i].style.backgroundColor = color[i]; }
Implemented with native dom
Control css properties
1, Toggle tab
Through the none value of the display attribute, set the required to block and the unnecessary to none;
for(let i = 0;i<tap.length;i++){ tap[i].key = i; tap[i].onclick = function(){ var key = this.key; //The first way is through the display attribute for(var k = 0;k<value.length;k++){ value[k].style.display = "none"; if(key === k){ value[k].style.display = "block"; } } //The second method is realized by displacement } }
2, Displacement tab.
Through displacement, the elements to be displaced are set as absolute positioning, and the height of each element is obtained to position it in the visual area. The advantage of using this method is that by slightly changing the thinking and positioning the height of the scroll bar, you can automatically scroll to the specified position by clicking the option page on the left.
If the element height is known and ordered
You need to make a mark on the outermost layer
let sign = 0; //The location of the tag is the first by default
Set it to absolute positioning and save some data
let heightArr = []; //Used to get the height of each element in the value part let temp = 0; //Temporary transit let sign = 0; //The location of the tag is the first by default for (var i = 0;i < value.length;i++){ // temp = value[i].clientHeight; // //This is the case when all elements are equal height // value[i].style.top = temp*i + "px"; //If unequal height if(i != 0){ temp += value[i].clientHeight; } value[i].style.top = temp + "px"; let obj = { "height": value[i].clientHeight, "top": value[i].clientTop, "number": i, } heightArr.push(obj); }
if(sign === key) return; let sum = key - sign; //Get a positive or negative value //Now use the simplest method for(var index = 0;index < value.length;index++){ value[index].style.top = parseInt(value[index].style.top) - sum*500 + "px"; }
What if the height of each element is uncertain
We need to get the specific height of each displacement and encapsulate a function;
function specific(){ let temp = 0; if(sum>0){ for(var j = sign;j < key;j++){ temp += value[j].clientHeight; } return temp; }else{ for(var j = key;j < sign;j++){ temp += value[j].clientHeight; } return -temp; } }
That is, it returns a positive or negative value. You can call it when you use it
for(var index = 0;index < value.length;index++){ value[index].style.top = parseInt(value[index].style.top) - specific() + "px"; }
The most critical step: update the marker position after each click
sign = key;
3, Positioning tab
The left option bar is fixed and the right layout is adaptive. Click the left option to locate the content position on the right
First, the layout is implemented with css, and elastic boxes can be used
.app{ width: 800px; height: 500px; margin: 10px auto; position: relative; /* overflow-y: scroll;- */ /* display: flex; */ /* justify-content: space-between; */ } .key-left{ height: 500px; width: 100px; left:0; position: absolute; } .key-left .tap{ width: 100px; height: 100px; display: flex; justify-content: center; align-items: center; font-size: 50px; color: #4169E1; } .key-left .tap:hover{ background-color: burlywood; } .key-value{ position: absolute; right: 0; width: 700px; height: 500px; /* overflow: hidden; */ } .key-value .value{ width: 700px; height: 500px; font-size: 50px; text-align: center; line-height: 500px; color: aliceblue; position: absolute; transition: all 0.3s linear; } .key-value .value-box{ position: relative; width: 700px; height: 500px; overflow-y: scroll; overflow-x: hidden; transition: all 0.3s linear; }
Gets the outer box of the content area
let valueBox = app.getElementsByClassName("value-box")[0];
The implementation idea is to set the height of the scroll bar
let sum = function(){ let temp = 0; for(var index = 0;index < key;index++){ temp += value[index].clientHeight; } return temp; } valueBox.scrollTop = sum();
The same method is reset every time
You can also add a selected state
for(var index = 0;index < tap.length;index++){ if(index === key){ this.style.backgroundColor = "yellow"; value[index].innerText = "Currently selected"; }else{ tap[index].style.backgroundColor = ""; value[index].innerText = "Not selected"; } }
Set default initial state
tap[0].style.backgroundColor = "yellow"; value[0].innerText = "Currently selected";
This implementation
Yes
Ugly is ugly. Cover your face for the purpose of realizing function.
The above is implemented in a process oriented manner. Now do it again with object-oriented ideas
Object oriented implementation positioning tab
The dom structure remains unchanged, and a new JS file Tap.js is created
function Tap(className){ if(!className) return; console.log(className); this.app = document.getElementById(className); this.tap = this.app.getElementsByClassName("tap"); this.value = this.app.getElementsByClassName("value"); this.color = ['red','green','blue','yellow','pink']; this.valueBox = this.app.getElementsByClassName("value-box")[0]; this.heightArr = []; //Used to get the height of each element in the value part this.sign = 0; //The location of the tag is the first by default } //Initial state. Tap.prototype.init = function(defindex = 0){ let temp = 0; for (var i = 0;i < this.value.length;i++){ if(i != 0){ temp += this.value[i].clientHeight; } this.value[i].style.top = temp + "px"; let obj = { "height": this.value[i].clientHeight, "top": this.value[i].clientTop, "number": i, } this.heightArr.push(obj); } for(let i = 0;i<this.value.length;i++){ this.value[i].style.backgroundColor = this.color[i]; } for(var index = 0;index < this.tap.length;index++){ if(index === defindex){ this.tap[index].style.backgroundColor = "yellow"; this.value[index].innerText = "Currently selected"; }else{ this.tap[index].style.backgroundColor = ""; this.value[index].innerText = "Not selected"; } } this.valueBox.scrollTop = this.heightSum(defindex); return this; } //Height of scroll bar to jump Tap.prototype.heightSum = function(defindex = 0){ let temp = 0; for(var index = 0;index < defindex;index++){ temp += this.value[index].clientHeight; } return temp; } //Click function Tap.prototype.click = function(){ for(let i = 0;i<this.tap.length;i++){ this.tap[i].key = i; let that = this; this.tap[i].onclick = function(){ var key = this.key; that.init(key); } } return this }
It seems to be getting more complicated
Reference Tap.js
<script src="./Tab.js" type="text/javascript"></script>
Used in initialization
window.onload = function(){ new Tap('app').init(2).click(); }
That's it.