Jquery click events firing before clicking?

Hi guys! I’m working on creating an OOP jquery slider and something really weird is happening. I bind an element to an event and call a function, be the function is being called before the event happens. Here’s my code so far:


jQuery(function ($) {
	'use strict';
	var Slider = {
		init : function() {
			this.cacheElements();
			this.bindEvents();
		},
		cacheElements: function(){
			this.$slider = $('.slideshow .wrapper');
			this.$slides = this.$slider.find('.slide');
			this.$activeSlide = this.$slider.find('.active');
			this.$prevTrigger = this.$slides.find('.prev');
			this.$nextTrigger = this.$slides.find('.next');
			this.slideWidth = this.$slides.width();
			this.numberOfSlides = this.$slides.length;
			this.animating = false;
		},
		bindEvents: function(){
			this.$prevTrigger.on('click', this.slide('prev'));
			this.$nextTrigger.on('click', this.slide('next'));
		},
		slide:function(direction){
			this.animating = true;
			if(direction === 'prev'){
				if(this.$slides.index(this.$activeSlide) === 0 ){
					// go to last slide
					alert('last slide');
					return false;
				}

			}
			if(direction === 'next'){
				if(this.$slides.index(this.$activeSlide) === this.numberOfSlides){
					//go to first slide
					alert('first slide');
					return false;
				}
			}
			alert(this.animating); // this isn't supposed to happen until clicked
		}
	};

	Slider.init();
});

Alert boxes with ‘last slide’ (there is a slide with the active class already) and ‘true’ show up when the page loads, but nothing happens when the triggers are clicked. What’s wrong with the code?

The problem is that when you init the code, the prev/next calls are being immediately triggered:


this.$prevTrigger.on('click', this.slide('prev'));
this.$nextTrigger.on('click', this.slide('next'));

You can fix that by wrapping them in a function declaration, so that they only get run when the function is invoked:


var slider = this; // cache the this keyword, so that the function can later on use it
this.$prevTrigger.on('click', function () {
    slider.slide('prev');
});
this.$nextTrigger.on('click', function () {
    slider.slide('next');
});

Maybe I don’t know something about javascript…the init function only binds the events and let it listen for clicks. What makes it automatically fire?
Sorry, It’s not obvious to me what the problem is…

I updated my initial post with lots more details, before I saw your reply - it could be worth looking back over that again.

I did this but it doesn’t look like the event is registered at all. I can’t even access the Slider object from chrome dev tools.

Really? It works for me. See a simplified example that demonstrates the code example that I provided above, at at http://jsfiddle.net/J7KwN/

If it helps, you can set a manual breakpoint with the scripting command debugger; which only takes effect when the developer panel is active.
You can read more about it at http://blog.katworksgames.com/2012/09/27/debugger-statement-makes-javascript-development-easier/

That debugger seems like a useful tool! Thanks. But unfortunately I still can’t solve the problem. I even copied and pasted your code and checked the selectors.
The slider function works, it just doesn’t seem like the events are binding

Can you please put together a test page for us that demonstrates the problem that you are having? There may be some subtle issue there that we can find by investigating the source code.

Here is the hosted version: http://cruel-cora.gopagoda.com/

When I load the web page, the developer console says that the following file could not be loaded.
http://cruel-cora.gopagoda.com/javascripts/vendor/jquery-1.10.2.min.map

Would that be relevant to your issue?

No, i don’t even include that script in the file…

It’s okay - that’a a part of the jquery that you’re loading. Look at the sourcemap part near the top of the jquery script.

In regard to your issue though, here is where your problem is occurring:


this.$slides = this.$slider.find('.slide');
this.$activeSlide = this.$slider.find('.active');
this.$prevTrigger = this.$slides.find('.prev');
this.$nextTrigger = this.$slides.find('.next');

The prevTrigger is looking in the $slides to find .prev, but it’s not finding anything there. That’s because your .prev and .next elements are not in the slides area, but seem to be in a separate .controls section instead.

Ah yes, that was the problem. Thank you so much for helping me.
I have one more question: how do i access the e variable on the slide method? If i pass it in and alert it, it’s undefined.
I updated the code on the website so you can see.

Where do you pass in the e variable?


slide:function(direction, e){
	alert(direction);
	alert(e);
}

Ahh - I had to refresh the script for the update to come through.

e is undefined because you are not passing anything for it when you call the slide function.


self.slide('prev');

Ah! I see. I got it working. Thank you so much for all your time.