0

I have a simple script to toggle post image/text on onmouseover. The code works fine if there are no more than 2 posts, but it becomes VERY slow when the number of posts increases.

function showPost(ele, eve) {
    var id = ele.id.replace("post-", "");
    if (typeof window['timerHide-' + id] !== "undefined") {
        clearInterval(window['timerHide-' + id]);
    }
    var target = (eve.relatedTarget) ? eve.relatedTarget : eve.toElement;
    var parent = $("post-" + id);
    if (typeof target === "undefined" || target === parent || target.parentNode === parent || target.parentNode.parentNode === parent) {
        return;
    }
    var img = $("post-img-" + id);
    var txt = $("post-txt-" + id);
    if (img.style.opacity === "") {
        img.style.opacity = 1;
    }
    var opacity = img.style.opacity;
    window['timerShow-' + id] = setInterval(function () {
        if (opacity <= 0.1) {
            clearInterval(window['timerShow-' + id]);

            img.style.display = 'none';
            txt.style.display = 'block';
            txt.style.opacity = 1;
        }
        img.style.opacity = opacity;
        img.style.filter = 'alpha(opacity=' + opacity * 100 + ")";
        opacity -= opacity * 0.1;
    }, 1);
};

The other function is almost identical to this one except for that it hides the toggled text.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
sitilge
  • 3,687
  • 4
  • 30
  • 56
  • 2
    setInterval(foo, 1) is pretty demanding, you are executing the callback every millisecond, consider an higher interval (and eventually adjust the step of your animation). – FabienAndre Feb 05 '14 at 21:52
  • You may even be encountering intervals shorter than invocation time => serious problems. – Paul S. Feb 05 '14 at 21:53
  • 1
    It looks fairly scary for a solution to a problem that sounds like it could be solved with pure CSS or a minimum of script. It is easier to help if you provide a jsfiddle with your attempt. – tobi Feb 05 '14 at 21:53
  • 1
    Like the other comments mentioned, it might be a better idea to go with CSS animation for this. Take a look at http://stackoverflow.com/questions/11684895/css-transition-fade-element-on-hover-only and see if that can be adapted to your situation. Otherwise try increasing the timeout. Even just going up to 16ms would be about 60 FPS, which I think is pretty generous for this sort of thing. Or maybe try requestAnimationFrame and base the opacity on the elapsed time instead. Then it will just run as smoothly as it can. – Ivy Feb 05 '14 at 22:49
  • So could anyone be so kind a help me with some code snippets? Really need your help, guys :) – sitilge Feb 06 '14 at 19:20

1 Answers1

0

You seem to be saving the interval ID to a DOM element, try using a variable

var timerID = setInterval(function ()
if (opacity <= 0.1)
{
    clearInterval(timerID);
Rescribet
  • 393
  • 5
  • 11
  • If you're in the global scope, `var foo; 'foo' in window; // true` – Paul S. Feb 05 '14 at 22:03
  • 1
    When testing this in the console, writing a variable to window returns 0 in the setInterval scope. – Rescribet Feb 05 '14 at 22:08
  • I need *timer* variables to be global to set and clear intervals for each post. P.S. function $(ele) {return document.getElementById(ele);} == no JQuery – sitilge Feb 06 '14 at 14:43
  • Are those variables actually available in the setInterval function? If so, the code provided still doesn't need [globals](http://stackoverflow.com/questions/10525582/why-are-global-variables-considered-bad-practice-javascript) since you can use [closures](http://stackoverflow.com/a/111200/1630540), which make your code more readable and safe. – Rescribet Feb 06 '14 at 14:55