话不多说,先上全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#dom_id{
width: 100px;
background-color: #e0e0e0;
font-size: 12px;
text-align: center;
}
.btn{
width: 70px;
height: 35px;
line-height: 35px;
text-align: center;
font-size: 14px;
background-color: #9c9c9c;
user-select: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="dom_id" >
<div>something dangerous</div>
<!-- <div>丝滑</div> -->
<div>丝滑</div>
</div>
<div class="btn" data-status="show" onclick="slideToogle(event,‘dom_id‘,500)">切换</div>
<script>
function slideToogle(e,el,duration=1000){
var dom = document.getElementById(el)
var status = e.target.dataset.status
var flag = e.target.dataset.status == ‘show‘ //保存当前的状态,方便进行判断
e.target.dataset.status = flag?‘hide‘:‘show‘ //如果本来是show,现在就更改为隐藏,懒省事的写法
dom.style.transition = ‘height ‘+duration/1000+‘s‘ //设置动画时间
dom.style.overflow = ‘hidden‘ //保证子元素不外溢
animateDom(flag,dom,duration) //操作dom的height属性
}
function animateDom(flag,dom,duration){
clearTimeout(dom.tagTimer);
setData(dom);
dom.style.height = flag?dom.tagHeight:"0px"
setTimeout(()=>{
dom.style.height = flag?"0px":dom.tagHeight
},0)
dom.tagTimer = setTimeout(()=>{
dom.style.display = flag?‘none‘:‘block‘
dom.style.transition = ‘‘;
dom.style.overflow = ‘‘;
dom.style.height = ‘‘;
},duration)
}
function setData(dom){
dom.tagTimer = dom.tagTimer || null
dom.style.display = ‘block‘;
dom.tagHeight = dom.tagHeight || dom.clientHeight+‘px‘
dom.style.display = ‘‘;
}
</script>
</body>
</html>
jquery、及vue的slide效果都用到了transition属性,这个属性设置的是元素的过渡效果,想要有这种丝滑的动态效果,必须要设置该属性
div{
height: 50px;
/* 下面这行表示,height值如果变化,就会在1秒内线性变化到指定的值 */
transition: height 1s linear;
}
我在dom加了一个属性data-status
为了方便控制显示和隐藏(其实可以直接设置在js的dom对象上),然后设置css的transition,overflow属性。
<div id="dom_id" >
<div>something dangerous</div>
<!-- <div>丝滑</div> -->
<div>丝滑</div>
</div>
<div class="btn" data-status="show" onclick="slideToogle(event,‘dom_id‘,500)">切换</div>
<script>
function slideToogle(e,el,duration=1000){
var dom = document.getElementById(el)
var status = e.target.dataset.status
var flag = e.target.dataset.status == ‘show‘ //保存当前的状态,方便对显示或者隐藏进行判断
e.target.dataset.status = flag?‘hide‘:‘show‘ //如果本来是show,现在就更改为隐藏,懒省事的写法
dom.style.transition = ‘height ‘+duration/1000+‘s‘ //设置动画时间
dom.style.overflow = ‘hidden‘ //保证子元素不外溢
animateDom(flag,dom,duration) //操作dom的height属性
}
</script>
function animateDom(flag,dom,duration){
clearTimeout(dom.tagTimer); // 清除定时器,因为连续点击会产生很多定时器,避免同时作用于dom
setData(dom); // 这个函数主要是设置一下属于当前dom的tagTimer,以及保存初始化高度tagHeight
dom.style.height = flag?dom.tagHeight:"0px" //这一行代码是初始化height属性,免得transition效果不触发,
setTimeout(()=>{
//这个定时器只是为了让js异步执行这两行代码,从而产生transition的过渡效果
dom.style.height = flag?"0px":dom.tagHeight //如果是显示,那就设置为原始高度,不显示就设置为0px
},0)
dom.tagTimer = setTimeout(()=>{
//动画结束以后设置 显示状态,并且把相关属性清空,这样更清爽,不是么?
dom.style.display = flag?‘none‘:‘block‘
dom.style.transition = ‘‘;
dom.style.overflow = ‘‘;
dom.style.height = ‘‘;
},duration)
}
function setData(dom){ //这个就不多说了,理解一下
dom.tagTimer = dom.tagTimer || null
dom.style.display = ‘block‘;
dom.tagHeight = dom.tagHeight || dom.clientHeight+‘px‘
dom.style.display = ‘‘;
}
Jquery的slideDown、slideUp、slideToggle原理
原文:https://www.cnblogs.com/the-artist/p/12668551.html