我正在尝试实现一个“切换可见性并带有滑动效果”的功能,类似于jQuery的slideDown(),但是使用普通的JS。我可以随时间动画化值,没有问题,但是当应该变得可见的元素的高度未知时,我该怎么办?现有的样本解决方案似乎总是将max-height值动画化到固定值,但我需要动画化到先前未知的值(高度)。(如果有一种使用css3实现这一点的方法,我也会很好奇!)
将您的元素高度设置为0,隐藏溢出,并使用CSS3转换来处理动画:
.container {
height: 0px;
overflow: hidden;
transition: all 1000ms;
}
您可以基于元素的 scrollHeight
轻松地对其进行动画处理:
var container= document.querySelector('.container');
container.style.height= container.scrollHeight + 'px';
片段
document.querySelector('button').addEventListener('click', function() {
var container= document.querySelector('.container');
container.style.height= container.scrollHeight + 'px';
});
.container {
font: 24px verdana;
background: #dfd;
height: 0px;
overflow: hidden;
transition: all 1000ms;
}
<button>
Slide Down
</button>
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
如果<input type="button" id="slide" value =" Slide Down "/>
有父元素,你可以进行测试,如果他没有父元素(即他的父元素是<body>
),你可以这样做:
var maxheight = $(window).height();
请看链接1
document.getElementsByTagName('div')[0].onclick = function() {
this.style.height = this.offsetHeight + 'px';
var that = this;
setTimeout(function() { that.style.height = '0'; }, 10);
};
div {
width: 50px;
background-color: yellow;
overflow: hidden;
transition: height 300ms ease;
}
<div>
<p>Let us not talk falsely now</p>
</div>
window.addEventListener("load", () => {
var div = document.getElementById("slindingDiv");
// set max height
div.style.setProperty("max-height", div.offsetHeight + "px");
// default: hide
div.classList.add("up");
// button logic
document.getElementById("toggle").onclick = () => {
if (div.classList.contains("up")) {
div.classList.remove("up");
} else {
div.classList.add("up");
}
};
});
#slindingDiv {
transition: max-height 0.5s ease-in-out;
overflow: hidden;
background: antiquewhite;
/* YOU CAN PLAY WITH WIDTH */
width: 75%;
}
/* You just have to add this class to make it slide up */
#slindingDiv.up {
max-height: 0 !important;
}
<div id="slindingDiv">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rutrum mi vel mauris ultricies, id vehicula mi hendrerit. Pellentesque placerat diam vel fermentum fermentum. Nulla eget odio a ipsum posuere dapibus. Ut sollicitudin tempor nibh, eu
convallis turpis iaculis tincidunt. Integer luctus ipsum vestibulum diam laoreet, at ornare felis tincidunt. Mauris dapibus diam ut ultrices ornare. Quisque nec risus in neque consequat efficitur vitae non turpis. Vivamus posuere sapien ac tellus
euismod volutpat eu id mauris. Nunc vel convallis nisi. Quisque convallis fringilla porttitor. Donec id consectetur nisi. Aliquam id dui ornare, efficitur erat sed, vestibulum nisi. Donec suscipit fringilla dolor, sed ullamcorper leo varius ac. Vestibulum</p>
</div>
<button id="toggle">Toggle slide</button>
我发现大多数解决方案都是基于“height”属性的动画,由于浏览器重新绘制进程(特别是在移动设备上),这可能会导致卡顿。因此,我建议使用“transition”和“opacity”属性的动画来模拟高度的变化;
示例:https://jsfiddle.net/av6207fy/3/
这种解决方案会更加流畅,因为它使用了“transform”和“opacity”属性的动画。您可以在这里阅读更多信息 http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
HTML
<div class="slider">
<div class="slider-header">
Click to toggle
</div>
<div class="slider-body">
"At vero eos et accusamus et iusto odio dignissimos ducimus qui
blanditiis praesentium voluptatum deleniti atque corrupti quos dolores
et quas molestias excepturi sint occaecati cupiditate non provident,
similique sunt in culpa qui officia deserunt mollitia animi, id est
laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita
distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
cumque nihil impedit quo minus id quod maxime placeat facere possimus,
omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem
quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet
ut et voluptates repudiandae sint et molestiae non recusandae. Itaque
earum rerum hic tenetur a sapiente delectus, ut aut reiciendis
voluptatibus maiores alias consequatur aut perferendis doloribus
asperiores repellat."
</div>
</div>
JS:
$(function(){
$('.slider').on('click', '.slider-header', function(e){
$(e.delegateTarget).toggleClass('expanded');
});
});
* {
box-sizing: border-box;
}
.slider {
position: relative;
overflow: hidden;
margin: 40px;
}
.slider .slider-header {
width: 100%;
height:40px;
text-align: center;
line-height: 40px;
background: green;
color: white;
cursor: pointer;
position: relative;
z-index: 2;
}
.slider .slider-body {
width: 100%;
padding: 20px;
position: relative;
z-index: 1;
background: red;
color: white;
text-align: center;
-ms-transform: translate3d(0, -140px, 0);
-o-transform: translate3d(0, -140px, 0);
-moz-transform: translate3d(0, -140px, 0);
transform: translate3d(0, -140px, 0);
opacity: 0;
-o-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-webkit-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.slider.expanded .slider-body {
-webkit=transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
}
left
属性上执行操作非常出色(即使像你所说的那样需要浏览器重绘)。 - Apolo两个纯CSS(无JavaScript)的替代方案:
1 - 隐藏复选框(允许同时打开多个框):
input[type=checkbox] {
display: none;
}
2 - 暗藏的单选按钮(“单选”行为):
input[type=radio] {
display: none;
}
Javascript改进:
2b - 带有第二次点击取消选择的“单选”行为的秘密单选按钮:
var allRadios = document.getElementsByName('image');
var booRadio;
var x = 0;
for(x = 0; x < allRadios.length; x++){
allRadios[x].onclick = function() {
if(booRadio == this){
this.checked = false;
booRadio = null;
}else{
booRadio = this;
}
};
}