文章目录
学习链接通过scrollHeight实现通过js获取auto时的高度去实现(效果不好)优化 通过grid实现
学习链接
vue项目列表折叠面板动画效果实现
element-ui之el-collapse-transition(折叠展开动画)源码解析学习
通过scrollHeight实现
以下代码注意两点
<template> <div> <el-button plain type="danger" @click="toggleDiv" size="mini" style="margin-bottom: 10px;" >toggleDiv</el-button> <div class="box1" ref="box1" id="box1"> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> </div> </div></template><script>export default { name: 'Collapse', components: { }, data() { return { isCollapse: false, } }, mounted() { // 刚开始的时候, 就必须先获取到这个元素的高度(transition需要有两个数值才能产生过渡), 它必须刚开始就是可见的(不能display:none) console.log('mounted', this.$refs['box1'].scrollHeight); this.$refs['box1'].style.height = this.$refs['box1'].scrollHeight + 'px' }, methods: { toggleDiv() { this.isCollapse = !this.isCollapse if(this.isCollapse) { this.$refs['box1'].style.height = 0 } else { // 这个时候,box1已经收缩了,但是需要展开,那就必须获取到它的高度(此时它的style的height为0) console.log( this.$refs['box1'].scrollHeight); this.$refs['box1'].style.height = this.$refs['box1'].scrollHeight + 'px' } } }}</script><style>.box1 { width: 200px; /* height: 200px; */ background-color: #bfa; transition: height 0.28s; overflow: hidden;}.box1 .box1-item { height: 20px; border: 1px solid red;}</style>
通过js获取auto时的高度去实现(效果不好)
虽然,实现效果并不怎么好,但是比较巧妙,它通过js设置height为auto,然后就可以获取元素的自然高度。这种获取高度的方式可以借鉴下
<template> <div> <el-button plain type="danger" @click="toggleDiv" size="mini" style="margin-bottom: 10px;" >toggleDiv</el-button> <div class="box1" ref="box1" id="box1"> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> </div> </div></template><script>export default { name: 'Collapse', components: { }, data() { return { isCollapse: false, } }, mounted() { console.log(this.$refs['box1'].scrollHeight); // 110 this.$refs['box1'].style.height = 'auto' this.$refs['box1'].style.height = window.getComputedStyle(this.$refs['box1']).height }, methods: { toggleDiv() { this.isCollapse = !this.isCollapse if(this.isCollapse) { this.$refs['box1'].style.height = 0 } else { this.$refs['box1'].style.height = 'auto' let height = window.getComputedStyle(this.$refs['box1']).height // 这里修改的太快,transition都还没开始做动画 this.$refs['box1'].style.height = 0 this.$refs['box1'].style.height = height } } }}</script><style>.box1 { width: 200px; background-color: #bfa; overflow: hidden;}.box1 .box1-item { height: 20px; border: 1px solid red;}</style>
优化
要使用setTimeout,才能在展开的时候,有过渡效果,不然两个修改高度的js在一起,它是不会有过渡的,可能跟浏览器的渲染有关系
<template> <div> <el-button plain type="danger" @click="toggleDiv" size="mini" style="margin-bottom: 10px;" >toggleDiv</el-button> <div class="box1" ref="box1" id="box1"> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> <div class="box1-item"></div> </div> </div></template><script>export default { name: 'Collapse', components: { }, data() { return { isCollapse: false, styleObj: {} } }, mounted() { console.log(this.$refs['box1'].scrollHeight); // 110 this.$refs['box1'].style.height = 'auto' this.$refs['box1'].style.height = window.getComputedStyle(this.$refs['box1']).height }, methods: { toggleDiv() { this.isCollapse = !this.isCollapse if(this.isCollapse) { this.$refs['box1'].style.height = 0 } else { this.$refs['box1'].style.height = 'auto' let height = window.getComputedStyle(this.$refs['box1']).height console.log(height,1); this.$refs['box1'].style.height = 0 setTimeout(()=> { this.$refs['box1'].style.height = height }) } } }}</script><style>.box1 { width: 200px; background-color: #bfa; overflow: hidden; transition: all 0.5s;}.box1 .box1-item { height: 20px; border: 1px solid red;}</style>
通过grid实现
注意下面的grid网格布局是加给外面的这个容器,外面这个容器从0fr到1fr会产生动画。overflow:hidden是加给里面的这个div。这样就能实现从0->auto的高度变化过渡效果。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; } .quick-example { margin: 1rem; padding: 1rem; background: hsl(200, 50%, 50% ); border-radius: 0.5rem; display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.5s; } .quick-example>div { overflow: hidden; } .quick-example:hover { grid-template-rows: 1fr; } </style></head><body> <div class="quick-example"> <div> this is amazing! this is amazing! this is amazing! this is amazing! this is amazing! this is amazing! this is amazing! this is amazing! </div> </div> <div> [一段很长的文字Lorem1000] </div></body></html>