4

Morning folks. Have an issue with a simple jQuery gallery i'm making. It lets the user cycle through a collection of images via some buttons and at the same time, rotates through these images on a timer. My problem is that the user is able to click the button multiple times which queues up the fade in animation and repeats it over and over, e.g. user clicks button 5 times > same image fades in/out 5 times > gallery moves to next image.

I've tried using:

$('#homeGalleryImage li a').unbind('click');

After the click event is fired and then rebinding:

$('#homeGalleryImage li a').bind('click');

After it's done but this simply removes the click event after pressing a button once and never rebinds to it?

I've also tried disabling the button via:

$('#homeGalleryImage li a').attr('disabled', true);

To no avail... ?

There is a secondary issue where if you manage to click a button while the image is in a transition, the next image appears 'faded' as if the opacity has been lowered? Very strange... Here is the code for button clicks:

var i = 1;
var timerVal = 3000;
$(function () {
    $("#homeGalleryControls li a").click(function () {
        var image = $(this).data('image');
        $('#galleryImage').fadeOut(0, function () {
            $('#galleryImage').attr("src", image);
        });
        $('#galleryImage').fadeIn('slow');
        $('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
        $(this).find('img').attr("src", "/Content/Images/Design/btn_checked.gif");
        i = $(this).data('index') + 1;
        if (i == 4) {
            i = 0;
        }
        timerVal = 0;
    });
});

Here is the code that cycles through the images on a timer:

//Cycle through gallery images on a timer
window.setInterval(swapImage, timerVal);
function swapImage() {
    $('#galleryImage').fadeOut(0, function () {
        var imgArray = ["/Content/Images/Design/gallery placeholder.jpg", "/Content/Images/Design/1.jpg", "/Content/Images/Design/2.jpg", "/Content/Images/Design/3.jpg"];
        var image = imgArray[i];
        i++;

        if (i == 4) {
            i = 0;
        }

        $('#galleryImage').attr("src", image);
        $('#galleryImage').fadeIn('slow');
    });
    var currentButton = $('#homeGalleryControls li a img').get(i - 1);
    $('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
    $(currentButton).attr("src", "/Content/Images/Design/btn_checked.gif");
}

I realise it might be a better idea to use a plugin but I'm very new to jQuery and I'd like to learn something rather than using some ready made code.

Any help at all, is much appreciated.

Thankyou

dtsg
  • 4,408
  • 4
  • 30
  • 40

2 Answers2

6

You could always try adding something to the element to cancel the click event?

For example

$(".element").click(function(e) {

    if ( $(this).hasClass("unclickable") ) {
        e.preventDefault();
    } else {

        $(this).addClass("unclickable");
        //Your code continues here
        //Remember to remove the unclickable class when you want it to run again.

    }

}):

In your case you could try adding a check on the click.

$('#homeGalleryImage li a').attr('data-disabled', "disabled");

Then inside your click event

if ( $(this).attr("data-disabled" == "disabled") {
  e.preventDefault();
} else {
  //Ready to go here
} 

Edit

Here is a working example showing the element becoming unclickable. http://jsfiddle.net/FmyFS/2/

Undefined
  • 11,234
  • 5
  • 37
  • 62
  • I just gave this a go removing the 'unclickable' class after the click code has completed but it appears to have done nothing at all :( I'll try your other suggestion next – dtsg Jul 19 '12 at 08:19
  • Ill put together a jsfiddle example for you, give me a minute or two :) – Undefined Jul 19 '12 at 08:19
  • Tried the second suggestion but no luck either. It seems like unbinding/binding once done should work but it doesn't appear to rebind? Very strange. Thankyou though! – dtsg Jul 19 '12 at 08:25
  • @Duane Is it possible for you to put an example on jsfiddle? – Undefined Jul 19 '12 at 08:27
  • @Duane Please see my edit for a working example, maybe this will help you – Undefined Jul 19 '12 at 08:30
  • Here's the jsFiddle, i'll give your updated answer a try too. Thanks http://jsfiddle.net/XqHFM/2/ – dtsg Jul 19 '12 at 08:39
  • used the code from your jsFiddle and it fixed the issue i was having, cheers! +1. I still get the issue of the images fading/opacity being lowered if i spam the buttons though :( – dtsg Jul 19 '12 at 08:48
  • I persume you have some sort of hover effect on them? Youll need to add the unclickable check to those hover functions as well – Undefined Jul 19 '12 at 08:50
  • No hover effect, i think it's to do with the transition code on a timer, if the user clicks a button during a transition every 3 seconds, it sort of halves the opacity of the images, almost like it hasn't finished fading in? You can recreate it by clicking the same button continuously in the jsFiddle, eventually the bug pops up. – dtsg Jul 19 '12 at 08:54
  • 1
    Played around in jsFiddle and found that it's the version of jQuery i'm using that's causing the fading/opacity issue I'm using 'jquery-1.5.1.min.js' whereas the version in jsFiddle is 1.72 which works fine. Thankyou for your help, I've marked this as answered :) – dtsg Jul 19 '12 at 09:22
1

if you want to make sure that the registered event is fired only once, you should use jQuery's one :

.one( events [, data ], handler ) Returns: jQuery

Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type.

see examples:

using jQuery: https://codepen.io/loicjaouen/pen/RwweLVx

// add an even listener that will run only once
$("#click_here_button").one("click", once_callback);

using vanilly JS: https://codepen.io/loicjaouen/pen/gOOBXYq

// add a listener that run only once
button.addEventListener('click', once_callback, {capture: true, once: true});
loic.jaouen
  • 489
  • 4
  • 9