我希望有与 jQuery 滑动类似的效果,但不使用 jQuery 或任何其他库。我知道这是“可能的”,因为 jQuery 中的任何事情都可以在纯 JavaScript 中完成。就更难了。
我不能使用 jQuery,因为所有内容都必须用我自己的代码编写,而不使用任何库。
有没有人使用纯 JavaScript 做过这样的事情或任何效果?
我希望有与 jQuery 滑动类似的效果,但不使用 jQuery 或任何其他库。我知道这是“可能的”,因为 jQuery 中的任何事情都可以在纯 JavaScript 中完成。就更难了。
我不能使用 jQuery,因为所有内容都必须用我自己的代码编写,而不使用任何库。
有没有人使用纯 JavaScript 做过这样的事情或任何效果?
既然是 2014 年,为什么不使用 CSS 过渡,只更改元素的高度属性? 小提琴
CSS:
.wrapper {
transition:height 1s ease-out;
height:0;
overflow:hidden;
}
HTML:
<div id="wrapper">
//content
</div>
Java脚本:
document.getElementById("wrapper").style.height = //content height +"px";
所以我们在 2020 年,现在更明显的是我们应该依靠 CSS 效果来制作这种动画。
但是,针对此答案提出了一个有效观点 - 您需要在 js 代码中指定要设置动画的元素的高度,并且您可能事先不知道该值。
所以六年后,我添加了几行额外的代码来涵盖这种情况。
因此,如果我们使用与 2014 年旧示例相同的 CSS 和 HTML,这就是新的 JS。 新小提琴!
const slideDown = elem => elem.style.height = `${elem.scrollHeight}px`;
slideDown(document.getElementById("wrapper"));
这是我从头开始编写的一小段代码。
它纯粹是基于时间的。
var minheight = 20;
var maxheight = 100;
var time = 1000;
var timer = null;
var toggled = false;
window.onload = function() {
var controller = document.getElementById('slide');
var slider = document.getElementById('slider');
slider.style.height = minheight + 'px'; //not so imp,just for my example
controller.onclick = function() {
clearInterval(timer);
var instanceheight = parseInt(slider.style.height); // Current height
var init = (new Date()).getTime(); //start time
var height = (toggled = !toggled) ? maxheight: minheight; //if toggled
var disp = height - parseInt(slider.style.height);
timer = setInterval(function() {
var instance = (new Date()).getTime() - init; //animating time
if(instance <= time ) { //0 -> time seconds
var pos = instanceheight + Math.floor(disp * instance / time);
slider.style.height = pos + 'px';
}else {
slider.style.height = height + 'px'; //safety side ^^
clearInterval(timer);
}
},1);
};
};
在这里测试:http : //jsbin.com/azewi5/5
作为对忽略未知高度用例的@Ruben Serrate 解决方案的改进,我使用 CSS3 和 javascript(无 jQuery)创建了它:
/**
* getHeight - for elements with display:none
*/
getHeight = function(el) {
var el_style = window.getComputedStyle(el),
el_display = el_style.display,
el_position = el_style.position,
el_visibility = el_style.visibility,
el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''),
wanted_height = 0;
// if its not hidden we just return normal height
if(el_display !== 'none' && el_max_height !== '0') {
return el.offsetHeight;
}
// the element is hidden so:
// making the el block so we can meassure its height but still be hidden
el.style.position = 'absolute';
el.style.visibility = 'hidden';
el.style.display = 'block';
wanted_height = el.offsetHeight;
// reverting to the original values
el.style.display = el_display;
el.style.position = el_position;
el.style.visibility = el_visibility;
return wanted_height;
};
/**
* toggleSlide mimics the jQuery version of slideDown and slideUp
* all in one function comparing the max-heigth to 0
*/
toggleSlide = function(el) {
var el_max_height = 0;
if(el.getAttribute('data-max-height')) {
// we've already used this before, so everything is setup
if(el.style.maxHeight.replace('px', '').replace('%', '') === '0') {
el.style.maxHeight = el.getAttribute('data-max-height');
} else {
el.style.maxHeight = '0';
}
} else {
el_max_height = getHeight(el) + 'px';
el.style['transition'] = 'max-height 0.5s ease-in-out';
el.style.overflowY = 'hidden';
el.style.maxHeight = '0';
el.setAttribute('data-max-height', el_max_height);
el.style.display = 'block';
// we use setTimeout to modify maxHeight later than display (to we have the transition effect)
setTimeout(function() {
el.style.maxHeight = el_max_height;
}, 10);
}
}
这是演示:http : //jsfiddle.net/pgfk2mvo/
如果您能找到任何改进,请告诉我,因为我总是尝试改进我的代码。快乐编码!:D
可以用纯 JavaScript 完成。就更难了。
其实也不算太难。你只需要适应setTimeout()
(无论如何这是个好主意,因为它教你 node.js 的编程风格)。最简单的实现(没有 jQuery 的所有功能,这留给读者作为作业):
function slideDown (element, duration, finalheight, callback) {
var s = element.style;
s.height = '0px';
var y = 0;
var framerate = 10;
var one_second = 1000;
var interval = one_second*duration/framerate;
var totalframes = one_second*duration/interval;
var heightincrement = finalheight/totalframes;
var tween = function () {
y += heightincrement;
s.height = y+'px';
if (y<finalheight) {
setTimeout(tween,interval);
}
}
tween();
}
当然,这不是最短的编写方式,您不必声明所有这些变量,例如one_second
等。我只是这样做是为了清楚地显示正在发生的事情。
这个例子也比试图阅读 jQuery 的源代码更短更容易理解。
有没有人使用纯 JavaScript 做过这样的事情或任何效果?
哦,是的,当然,这是我周末做的有趣的事情:
这是使用带有未知内容高度元素的slideDown、slideUp 动画的解决方案。https://jsfiddle.net/gebpjo1L/18/
它基于 CSS 3 高度动画,但动画需要指定内容高度,因此您需要在展开之前通过 JavaScript 获取内容的高度。
var container = document.querySelector('div')
var button = document.querySelector('button')
button.addEventListener('click', () => {
/** Slide down. */
if(!container.classList.contains('active')) {
/** Show the container. */
container.classList.add('active')
container.style.height = "auto"
/** Get the computed height of the container. */
var height = container.clientHeight + "px"
/** Set the height of the content as 0px, */
/** so we can trigger the slide down animation. */
container.style.height = "0px"
/** Do this after the 0px has applied. */
/** It's like a delay or something. MAGIC! */
setTimeout(() => {
container.style.height = height
}, 0)
/** Slide up. */
} else {
/** Set the height as 0px to trigger the slide up animation. */
container.style.height = "0px"
/** Remove the `active` class when the animation ends. */
container.addEventListener('transitionend', () => {
container.classList.remove('active')
}, {once: true})
}
})
div {
transition: height .5s ease;
overflow : hidden;
}
div:not(.active) {
display: none;
}
<div>
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
I'm an unknown content height element.
</div>
<button>Slide Toggle</button>