Mister Epic
Mister Epic

Reputation: 16743

All click event handlers firing when a single click event triggered

I've tried to organize my Javascript using IIFEs to make things more modular. However, I'm getting some strange behaviour I can't explain.

I have two divs:

<div id="one">foo</div>
<div id="two">bar</div>

I have some IIFEs to:

I try to assign a click handler to each div, but when I click on either div, all handlers fire. Why?

http://jsfiddle.net/u61vet1g/

(function(foobar) {
    foobar.elements = (function() {
        var one, two;

        return{
            one: function(){
                return one || (one = $('#one'));
            },
            two: function(){
                return two || (two = $('#two'));
            }   
        }
    })();

    foobar.eventListeners = (function(elems){       

        return {
            oneOnClick: function(e) {
                alert('1');
            },
            twoOnClick: function(e) {
                alert('2');
            }
        }
    })(foobar.elements);

    foobar.bindEventListeners = (function(elems, listeners) {
        return function () {
            $(document).on('click', elems.one(), listeners.oneOnClick);

            $(document).on('click', elems.two(), listeners.twoOnClick);
        }
    })(foobar.elements, foobar.eventListeners);

    foobar.init = function (options) {
        foobar.bindEventListeners();
    };
})(window.foobar = window.foobar || {});
foobar.init();

Upvotes: 0

Views: 38

Answers (3)

Moob
Moob

Reputation: 16204

The Delegated Listener requires a jQuery selector not an object (http://api.jquery.com/on/):

$(document).on('click', '#two', listeners.twoOnClick);

So if you change your foobar.elements() to return a selector string (eg:'#two') it works:

See: http://jsfiddle.net/moob/u61vet1g/1/

Upvotes: 1

Bergi
Bergi

Reputation: 665256

I have some IIFEs to

Whoa. These look totally over-engineered.

when I click on either div, all handlers fire. Why?

Because you're not binding the handlers to the elements, but to document:

$(document).on('click', …);

The jQuery objects passed for the second argument will become the data parameter. Instead, use

elems.one().on('click', listeners.oneOnClick);
elems.two().on('click', listeners.twoOnClick);

Upvotes: 3

vp_arth
vp_arth

Reputation: 14992

This happened because you handle both on document.
Try click on white and you get both alerts too.

Try followed syntax:

elems.one().on('click', listeners.oneOnClick);

Upvotes: 2

Related Questions