700 Software
700 Software

Reputation: 87763

Appropriate JavaScript delay to trigger CSS?

Suppose I have some CSS so #joe { transition: opacity 500ms; opacity: 0; }

Then I have JavaScript so when you click the page it adds the div and then animates opacity to = 1.

document.body.onclick = function () {
  var joe = document.createElement('div')
  joe.innerHTML = 'yo!'
  joe.id = 'joe'
  document.body.appendChild(joe)
  joe.style.opacity = 1
}

Well, it doesn't animate. (I guess because the CSS transition considers it an 'initial page load')

But if you add a timeout

document.body.onclick = function () {
  var joe = document.createElement('div')
  joe.innerHTML = 'yo!'
  joe.id = 'joe'
  document.body.appendChild(joe)
  setTimeout(function () {
    joe.style.opacity = 1
  }, 100)
}

Then the animation works.

But in some situations, even a 100ms delay has a visible affect on the apparent responsiveness of the page. And, unfortunately, setting the timeout to 1ms doesn't work.

So, what should the timeout be? I am looking to have animation that works most all the time across major browsers, but I don't want to raise the timeout without good reason.

I am not interested in jQuery animation because in my experience it is less efficient than CSS transitions, and doesn't sync multiple animations well. I'm open to suggestion if there's another JavaScript implementation that wins over CSS, but don't let that stop you from answering the question.

If there is an initial animation for CSS, that would be nice to know...

But what I really want to know is how the timeout should be set, because sometimes I animate left or width and I don't want to have to code in start and finish into CSS, when I need to use JavaScript to dynamically calculate these values.

Upvotes: 2

Views: 2635

Answers (2)

Andrei Beziazychnyi
Andrei Beziazychnyi

Reputation: 2917

It is possible to implement it without setTimeout using window.getComputedStyle().

Basic idea is:

joe.style.opacity = 0; //unnecessary in this case, set by css class   
window.getComputedStyle(joe).getPropertyValue("width");
joe.style.opacity = 1;   

Here is the jsfiddle: http://jsfiddle.net/4Vy9n/2/

Upvotes: 1

Arbel
Arbel

Reputation: 30989

Very simple, here is a pure CSS solution:

Demo http://jsfiddle.net/X7Zg5/7/

CSS:

.joe {
    font-size: 100px;
    -webkit-animation-duration: 500ms;
    -webkit-animation-name: fadeIn;
    -moz-animation-duration: 500ms;
    -moz-animation-name: fadeIn;
    -o-animation-duration: 500ms;
    -o-animation-name: fadeIn;
    animation-duration: 500ms;
    animation-name: fadeIn;
}
@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-webkit-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-moz-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}
@-o-keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

JS:

document.documentElement.onclick = function () {
    var joe = document.createElement('div');
    joe.innerHTML = 'yo!';
    joe.className = 'joe';
    document.body.appendChild(joe);
}

Upvotes: 0

Related Questions