views:

54

answers:

4

I've got a photo slideshow with thumbnails. Next/Previous buttons appear and disappear based on the size of the window; if the thumbnails overflow the window size, the buttons appear. If not, they disappear. My problem is that, at times, they won't come up, or they won't come up for a couple of seconds. At other times they won't disappear. Sometimes it works fine.

I am still pretty new to jQuery and JavaScript. Any suggestions?

    // hide previous and next buttons
$('#prev, #next').hide();

// get width of thumbnail list
var thumbsWidth = $('div#thumbs ul').width();

// show/hide next/prev buttons
function buttonVisibility() {
    if (thumbsWidth + 225 > screenWidth) {
        $('#prev, #next')
        .fadeTo('fast', 0.5)
        .hover(function(){
            $(this).fadeTo('fast', 1);
        }, function(){
            $(this).fadeTo('fast', 0.5);
        });
    } else {
        $('#prev, #next').fadeTo('fast', 0, function(){
            $(this).hide();
        });
    }
}

// declare global screenWidth variable
var screenWidth

// find width of thumbnail window and show/hide next/prev buttons accordingly
function findWidth(){
    screenWidth = $('div#thumbs').width();
    buttonVisibility();
}

// perform findWidth() on load and on window resize
findWidth();
$(window).resize(function(){
    findWidth();
});
A: 

Calculate screenWidth once upon load, so you don't have to search for div#thumbs over and over.

mcandre
What if the window is re-sized?
Squirkle
Then your window will resize. Try the several code examples listed on this page.
mcandre
The "screenwidth" variable is actually holding the element width, not the actual screen resolution. It will change as the window is resized; that's the whole point.
Pointy
I'm pretty sure that the screenWidth variable is "checked" once on $(document).ready(). It needs to be told to reload the variable when the window is resized.
Squirkle
A: 

Create a variable displayed which stores the current state of whether the buttons are visible or not. Now in the resize event you only do fadeIn if they are hidden.

Also you can store the selected elements in order not to do the selection every time.

// hide previous and next buttons
$prevNext = $('#prev, #next');
$prevNext.hide();

// get width of thumbnail list
var $thumbs = $('#thumbs');
var thumbsWidth = $('#thumbs ul').width();
var screenWidth;
var displayed = false;

// show/hide next/prev buttons
function buttonVisibility() {
    if (thumbsWidth + 225 > screenWidth) {
        if (!displayed) {
            displayed = true;
            $prevNext.fadeTo('fast', 0.5).hover(function () {
                $(this).fadeTo('fast', 1);
            }, function () {
                $(this).fadeTo('fast', 0.5);
            });
        }
    } else if (displayed) {
        displayed = false;
        $prevNext.fadeTo('fast', 0, function () {
            $(this).hide();
        });
    }
}

// find width of thumbnail window and show/hide next/prev buttons accordingly
function findWidth() {
    screenWidth = $thumbs.width();
    buttonVisibility();
}

// perform findWidth() on load and on window resize
findWidth();
$(window).resize(findWidth);

Ryan Kinal
It'd also be good to just use `$('#thumbs')` instead of `$('div#thumbs')`
Pointy
Why is that? I typically see more general selectors, but I thought more specificity would reduce lookup time...
Squirkle
+3  A: 

It might be that the work the browser intrinsically has to do while the window is resized (that is, re-figure the layout in response to the changing window size), added to the DOM changes you're making, is just bogging things down. What you might try is waiting for the user interaction to finish before triggering your code.

$(window).resize((function() {
  var timeout = null;
  return function() {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(findWidth, 250);
  };
})());

That'll change things so that your code won't try and do anything until 1/4 second after the user pauses or stops dragging the window around.

Pointy
Ahh! That works beautifully.
Squirkle
A: 

The frequency in which the onresize event is fired seems to be inconsistent across browsers. You may need to implement a custom mechanism to control the timing.

Josh Stodola