**问题描述:**当tab切换时,由于tab对应的内容不同,导致内容容器的高度的不同。 直接的切换显示内容显得太僵硬了,所以希望内容容器根据内容的多少实现slideToggle效果。
**解析问题:**首先一点是使用原生,意味着不能使用第三方框架。而实现slideToggle动画效果主要有两种手段, 一种是使用css3动画,另一种是javascript使用定时器实现slideToggle效果。但是使用原生js实现很繁琐,还是使用css3的方式推荐。 使用css3动画的transition属性来完成这效果,但是要注意的是使用transition的话,元素不能使用display: none;和display: block/flex/…;等进行切换。
我的实现方案是将sildeToggle动画和内容切换分离,在原来内容切换基础上,给外部容器添加transition动画;这样的话不论里面内容如何切花显示, 只需要根据内容给容器设置高度,而容器作为视口,对超过的内容进行隐藏,而高度的改变触发了transition属性。
<!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><style>* {padding: 0;margin: 0;}#container {transition: height 0.3s linear;background-color: cadetblue;overflow: hidden;}.nav-list {display: flex;flex-wrap: nowrap;}.tab {padding: 0 15px;height: 40px;line-height: 40px;text-align: center;display: inline-flex;justify-content: center;align-content: center;align-items: center;background-color: darkcyan;color: orange;}.tab.active {background-color: orange;color: darkcyan;}.content {display: none;}.content p {color: gold;}.content.active {display: block;}</style></head><body><dl id="tab"><dd id="nav"><dl class="nav-list"><dd class="tab active" data-index="0">tab1</dd><dd class="tab" data-index="1">tab2</dd><dd class="tab" data-index="2">tab3</dd><dd class="tab" data-index="3">tab4</dd><dd class="tab" data-index="4">tab5</dd></dl></dd><dd id="container"><dl class="content-list"><dd class="content active"><p>1</p><p>1</p><p>1</p><p>1</p><p>1</p><p>1</p><p>1</p><p>1</p></dd><dd class="content"><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p><p>2</p></dd><dd class="content"><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p><p>3</p></dd><dd class="content"><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p><p>4</p></dd><dd class="content"><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p><p>5</p></dd></dl></dd></dl><script type="text/javascript">'use strict';function load () {const navList = document.querySelector('#nav .nav-list')const contentList = document.querySelector('#container .content-list')const container = document.querySelector('#container')const tabs = document.querySelectorAll('#nav .tab')const contents = document.querySelectorAll('#container .content')let activeIndex = 0container.style.height = contentList.offsetHeight + 'px'navList.addEventListener('click', function (e) {const el = e.target || e.srcElementif (el.classList && el.classList.contains('tab')) {const currIndex = parseInt(el.getAttribute('data-index'))if (tabs[activeIndex].classList.contains('active')) {tabs[activeIndex].classList.remove('active')}if (contents[activeIndex].classList.contains('active')) {contents[activeIndex].classList.remove('active')}if (!tabs[currIndex].classList.contains('active')) {tabs[currIndex].classList.add('active')}if (!contents[currIndex].classList.contains('active')) {contents[currIndex].classList.add('active')container.style.height = contentList.offsetHeight + 'px'}activeIndex = currIndex}}, false)}window.addEventListener('load', function () {load()}, true)</script></body></html>