tags:

views:

97

answers:

3

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?

A: 

Have a look at the jQuery source for that effect (slideDown calls show).

Skilldrick
cowardly refusing to understand parts of jQuery (even though I've looked at the source many times) -->
Dan Beam
+3  A: 

can be done in plain JavaScript. Just harder.

Actually it's not too hard. You just need to get comfortable with setTimeout() (which is a good idea anyway since it teaches you the programming style of node.js). The most bare-bones implementation (does not have all of jQuery's features, that's left as homework for the reader):

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();
}

Of course, that's not the shortest possible way to write it and you don't have to declare all those variables like one_second etc. I just did it this way for clarity to show what's going on.

This example is also shorter and easier to understand than trying to read jQuery's source code.


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

Oh yeah, sure, it's the sort of thing I do for fun on weekends:

slebetman
Thanks I tried this but I couldnt get it working. Any chance of a working example? Thanks :)
Elliott
Works for me, http://jsfiddle.net/zZgrZ/
Robert
Ah I see now, I have my div hidden with display:none in my css. How could I get this to show when it slides down, I tried display:block but the effect doesnt work. Thanks
Elliott
+1 - for the tank animation ;)
Peter Ajtai
@Robert: Thanks for the jsfiddle. I realized I had a bug in my calculations and it should now be fixed. My intention was that duration is expressed in seconds (it accepts floating point).
slebetman
+1 cool game, love it. freakout =)
Ninja Dude
@Avinash: I don't understand, what do you mean not time based. It's using a setTimeout to schedule changes over time. Surely that's the definition of time flow.
slebetman
@Eliott: Can you post what exactly you are doing that makes this not work for you. Perhaps at jsfiddle or even as an addition to your question. It's hard to debug something we can't see :-P
slebetman
@slebetman I got it working now, I am just trying to set the div as hidden on load and then it is shown while it slides down.
Elliott
+1  A: 

Here's the code which I wrote it from scratch, This is purely time based. Tell you what I felt difficulty in writing this code, 'cause coding with jQuery for a long made me forgot how to code in pure javascript, finally I'm done ^^

var minheight = 20;
var maxheight = 100;
var time = 1000;
var timer = null;
var toggled = false;

window.onload = function() {
    var controler = document.getElementById('slide');
    var slider = document.getElementById('slider');
    slider.style.height = minheight + 'px'; //not so imp,just for my example
    controler.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);
    };
};

Test it here : http://jsbin.com/azewi5

Ninja Dude
Thanks is it possible to have it working when the div is hidden in css and then its shown as it slides down?
Elliott
yes, I believe It can be done by adding few more lines of code will do the job
Ninja Dude
@elliott try the updated demo http://jsbin.com/azewi5/3 , I'm using opacity to vary the visibility
Ninja Dude
Setting timeout to 1ms is not recommended because OSes other than Windows usually have the kernel tick set higher than that (Linux and BSD set it to 10ms I believe which would make 10ms the minimum recommended value). This will have the effect that on other OSes the animation will appear slow compared to Windows.
slebetman
Besides, 1000 frames per second is a very optimistic target. Even Quake doesn't try to reach that goal :-P
slebetman