现在的框架省去dom操作,开发者只需要关注数据即可,那么真的不需要操作dom了吗,是需要的,只不过程序已经帮忙做了这件事,纯粹的数据逻辑也将前端变得更难了。
<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];
}
控制css属性
通过display属性的 none值,给需要的设置为block,不需要的设置为none;
for(let i = 0;i<tap.length;i++){
tap[i].key = i;
tap[i].onclick = function(){
var key = this.key;
//第一种方式通过display属性
for(var k = 0;k<value.length;k++){
value[k].style.display = "none";
if(key === k){
value[k].style.display = "block";
}
}
//第二种方式通过位移实现
}
}
通过位移实现,给需要位移的元素设置为绝对定位,获取每一个元素的高度,使其定位在可视区内。使用这种方式的好处是,稍微改变一下思路,定位滚动条的高度,可以实现点击左侧选项页面自动滚动到指定位置。
如果元素高度知道,并有序
需要在最外层做一个标记
let sign = 0; //标记所在位置 默认是第一个
将其设置为绝对定位,并保存一些数据
let heightArr = []; //用于获取value部分每一个元素的高度
let temp = 0; //临时中转
let sign = 0; //标记所在位置 默认是第一个
for (var i = 0;i < value.length;i++){
// temp = value[i].clientHeight;
// //这是所有元素都等高的情况下
// value[i].style.top = temp*i + "px";
//如果不等高
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; //获得正值或者负值
//现在用最简单方法
for(var index = 0;index < value.length;index++){
value[index].style.top = parseInt(value[index].style.top) - sum*500 + "px";
}
如果每个元素的高度都不确定昵,该怎么做
我们需要得到每次位移的具体高度,封装一个函数;
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;
}
}
即返回正值或者负值,使用的时候调用一下即可
for(var index = 0;index < value.length;index++){
value[index].style.top = parseInt(value[index].style.top) - specific() + "px";
}
最关键的一步:每次点击完成后更新标记位置
sign = key;
实现左侧选项栏固定 右侧布局自适应,点击左侧选项定位到右侧内容位置
首先用css实现布局 ,可使用弹性盒子
.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;
}
获取到 内容区域的外层盒子
let valueBox = app.getElementsByClassName("value-box")[0];
实现思路是设置滚动条高度即可
let sum = function(){
let temp = 0;
for(var index = 0;index < key;index++){
temp += value[index].clientHeight;
}
return temp;
}
valueBox.scrollTop = sum();
同样的方法每一次都重新设置
还可以添加选中状态
for(var index = 0;index < tap.length;index++){
if(index === key){
this.style.backgroundColor = "yellow";
value[index].innerText = "当前被选中";
}else{
tap[index].style.backgroundColor = "";
value[index].innerText = "没有被选中";
}
}
设置默认的初始状态
tap[0].style.backgroundColor = "yellow";
value[0].innerText = "当前被选中";
这样实现
了
丑是丑了点, 捂脸,以实现功能为目的。
以上使用面向过程的方式实现的。现在以面向对象的思想再来实现一次
dom结构不变 ,新建一个js文件 Tap.js
function Tap(className){
if(!className) return;
console.log(className);
this.app = document.getElementById(className)[0];
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 = []; //用于获取value部分每一个元素的高度
this.sign = 0; //标记所在位置 默认是第一个
}
//初始状态。
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 = "当前被选中";
}else{
this.tap[index].style.backgroundColor = "";
this.value[index].innerText = "没有被选中";
}
}
this.valueBox.scrollTop = this.heightSum(defindex);
return this;
}
//滚动条需要跳转的高度
Tap.prototype.heightSum = function(defindex = 0){
let temp = 0;
for(var index = 0;index < defindex;index++){
temp += this.value[index].clientHeight;
}
return temp;
}
//点击功能
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
}
貌似变得更复杂了
引用Tap.js
<script src="./Tab.js" type="text/javascript"></script>
在初始化中使用
window.onload = function(){
new Tap('app').init(2).click();
}
这就搞定了。