JavaScript slidedown without jQuery

Ell*_*ott 44 javascript

I wish to have a similar effect to jQuery slidedown but without using jQuery or any other libary. I know it's "possible" as anything in jQuery can be done in plain JavaScript. Just harder.

I cannot use jQuery as everything has to be written in my own code without any libaries used.

Has anyone done something like this or any effects just using plain JavaScript?

小智 30

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

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);
    };
};
Run Code Online (Sandbox Code Playgroud)

在这里测试:http://jsbin.com/azewi5/5


Cla*_*diu 26

作为@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是演示:http: //jsfiddle.net/pgfk2mvo/

如果您能找到任何改进,请告诉我,因为我总是试图改进我的代码.快乐的编码!:d


Rub*_*ate 23

既然我们在2014年,为什么不使用CSS转换并只更改元素的height属性? 小提琴

CSS:

.wrapper {
    transition:height 1s ease-out;
    height:0;
    overflow:hidden;
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div id="wrapper">
//content
</div>
Run Code Online (Sandbox Code Playgroud)

JAVASCRIPT:

document.getElementById("wrapper").style.height = //content height +"px";
Run Code Online (Sandbox Code Playgroud)

  • 一个问题是如果你不知道内容高度(这不是一个利基用例) (7认同)
  • @ScriptsConnect有一种称为优雅降级的东西,这是一个很好的例子.用户仍将看到高度变化,只有未动画.这只发生在使用IE9-的非常小的人群中. (3认同)
  • 它的2018年,这应该是最好的答案.https://caniuse.com/#feat=css-transitions (3认同)
  • @ScriptsConnect我不完全同意.是的,OP要求提供一个javascript解决方案,但请记住,2010年CSS转换是未知领域,因为它们没有可靠的跨浏览器支持.这个解决方案是一个优雅的解决方 (2认同)

sle*_*man 16

可以用纯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();
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是写入它的最短方式,你不必声明所有这些变量等one_second.我只是这样做是为了清楚地显示正在发生的事情.

与尝试读取jQuery的源代码相比,此示例更短,更容易理解.


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

哦,是的,当然,这是我周末开心的事情:


Yam*_*mel 6

这是使用具有未知内容高度元素的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})
    }
})
Run Code Online (Sandbox Code Playgroud)
div {
    transition: height .5s ease;
    overflow  : hidden;
}

div:not(.active) {
    display: none;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


小智 5

早期答案的问题是你需要在开始之前知道高度.很多时候你没有.我建立了一个滑动你首先建立一个持有人div,把对象放到ge里面向下滑动设置对象的显示以阻止并获得高度并将其用于sind.当侧面完成时,保持器会移动,在完成拆卸后向下滑动.下面是一个例子.

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <div >
            <div id="test" style="height: 150px; width: 100px; background-color: yellowgreen; display:none">block</div>
        </div>
        <div>&nbsp;</div>
        <div onclick="slideUp(document.getElementById('test'));">slide Up</div>
        <div>&nbsp;</div>
        <div onclick="slideDown(document.getElementById('test'))">slide down</div>
        <script>
            function slideDown(obj, speed) {
                var mySpeed = speed || 300;
                var intervals = mySpeed / 30; // we are using 30 ms intervals
                alert('intervals = ' + intervals);
                var holder = document.createElement('div');//
                var parent = obj.parentNode;
                holder.setAttribute('style', 'height: 0px; overflow:hidden');
                parent.insertBefore(holder, obj);
                parent.removeChild(obj);
                holder.appendChild(obj);
                obj.style.display = obj.getAttribute("data-original-display") || "";
                var height = obj.offsetHeight;
                var sepHeight = height / intervals;
                //  alert(sepHeight)
                var timer = setInterval(function() {
                    var holderHeight = holder.offsetHeight;
                    if (holderHeight + sepHeight < height) {
                        holder.style.height = (holderHeight + sepHeight) + 'px';
                    } else {
                        // clean up
                        holder.removeChild(obj);
                        parent.insertBefore(obj, holder);
                        parent.removeChild(holder);
                        clearInterval(timer);
                    }
                }, 30);
            }

            function slideUp(obj, speed) {
                var mySpeed = speed || 300;
                var intervals = mySpeed / 30; // we are using 30 ms intervals
                var height = obj.offsetHeight;
                var holder = document.createElement('div');//
                var parent = obj.parentNode;
                holder.setAttribute('style', 'height: ' + height + 'px; overflow:hidden');
                parent.insertBefore(holder, obj);
                parent.removeChild(obj);
                holder.appendChild(obj);
                var originalDisplay = (obj.style.display !== 'none') ? obj.style.display : '';
                obj.setAttribute("data-original-display", originalDisplay);
                var sepHeight = height / intervals;
                //  alert(sepHeight)
                var timer = setInterval(function() {
                    var holderHeight = holder.offsetHeight;
                    console.log(holderHeight);
                    if (holderHeight - sepHeight > 0) {
                        holder.style.height = (holderHeight - sepHeight) + 'px';
                    } else {
                        // clean up
                        obj.style.display = 'none';
                        holder.removeChild(obj);
                        parent.insertBefore(obj, holder);
                        parent.removeChild(holder);
                        clearInterval(timer);
                    }
                }
                , 30);
            }

        </script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)