没有 jQuery 的 JavaScript 幻灯片

IT技术 javascript
2021-03-05 07:01:01

我希望有与 jQuery 滑动类似的效果,但使用 jQuery 或任何其他库。我知道这是“可能的”,因为 jQuery 中的任何事情都可以在纯 JavaScript 中完成。就更难了。

我不能使用 jQuery,因为所有内容都必须用我自己的代码编写,而不使用任何库。

有没有人使用纯 JavaScript 做过这样的事情或任何效果?

6个回答

既然是 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 EDIT(处理未知高度):

所以我们在 2020 年,现在更明显的是我们应该依靠 CSS 效果来制作这种动画。

但是,针对此答案提出了一个有效观点 - 您需要在 js 代码中指定要设置动画的元素的高度,并且您可能事先不知道该值。

所以六年后,我添加了几行额外的代码来涵盖这种情况。

因此,如果我们使用与 2014 年旧示例相同的 CSS 和 HTML,这就是新的 JS。 新小提琴!

const slideDown = elem => elem.style.height = `${elem.scrollHeight}px`;

slideDown(document.getElementById("wrapper"));

浏览器兼容性是这样做的原因,即使在 2014 年,如果人们不知道如何以浏览器兼容的方式(纯 JS 或 jQuery)来做,那么作为前端开发人员的能力就会出现问题。太多的开发人员采用 CSS3 方法,这对于使用几乎没有 CSS3 支持的浏览器的大部分人群来说是一个问题。
2021-04-15 07:01:01
它是 2018 年,这应该是最佳答案。caniuse.com/#feat=css-transitions
2021-04-21 07:01:01
@ScriptsConnect 有一种叫做优雅降级的东西,这是一个完美的例子。用户仍然会看到高度变化,只是没有动画。而这只发生在使用 IE9- 的极少数人群中。
2021-04-25 07:01:01
@ScriptsConnect 我不完全同意。是的,OP 要求提供 javascript 解决方案,但请记住,2010 年 CSS 转换是未知领域,因为它们没有可靠的跨浏览器支持。这个解决方案是一个优雅的解决方案,使用最少的 JS 和 CSS。
2021-04-27 07:01:01
一个问题是如果您不知道内容高度(这不是一个利基用例)
2021-05-04 07:01:01

这是我从头开始编写的一小段代码。
它纯粹是基于时间的

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

谢谢,当 div 隐藏在 css 中时,它是否可以工作,然后在它向下滑动时显示?
2021-04-20 07:01:01
是的,我相信可以通过添加更多代码行来完成这项工作
2021-04-23 07:01:01
@elliott 尝试更新的演示jsbin.com/azewi5/3,我正在使用不透明度来改变可见性
2021-05-01 07:01:01
此外,每秒 1000 帧是一个非常乐观的目标。即使是 Quake 也没有试图达到那个目标 :-P
2021-05-03 07:01:01
不建议将超时设置为 1ms,因为 Windows 以外的操作系统通常将内核刻度设置为高于此值(Linux 和 BSD 将其设置为 10ms,我相信这将使 10ms 成为最小推荐值)。这将导致在其他操作系统上,动画与 Windows 相比会显得缓慢。
2021-05-14 07:01:01

作为对忽略未知高度用例的@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

如果要向下滑动的 div 最初是可见的,则此“切换”将具有视觉错误。
2021-04-18 07:01:01
效果很好,但是当某些东西开始打开时会出现问题。
2021-04-23 07:01:01
@StevenWade 什么东西开始打开是什么意思是否有什么干扰了动画?在什么情况下?也许对 JSFiddle 进行编辑?
2021-05-13 07:01:01

可以用纯 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>

我认为它出现在屏幕上的速度太快了
2021-04-16 07:01:01
这是迄今为止我找到的最好的解决方案。小而简洁,使用 CSS 过渡。
2021-04-27 07:01:01
哦,我不知道container.clientHeight确实存在。我认为他们都做同样的事情,但container.clientHeight速度更快,所以我编辑了答案,谢谢。
2021-04-28 07:01:01
window.getComputedStyle(container, null).getPropertyValue("height")container.clientHeight什么理由使用而不是
2021-05-04 07:01:01
这对我有用,但我无法理解一件事。当你这样做container.style.height = "auto"(计算高度)然后回到 0px时,为什么我们没有闪烁我们不应该看到一些东西,或者它发生得太快而无法出现在屏幕上?
2021-05-06 07:01:01