Tech Savant
Tech Savant

Reputation: 3766

Multiple Event Listeners inside of Object Method Javascript HTML DOM

There are a few answers on here and some things I found through google that almost get me to where I want to be, but something tells me I'm going about this wrong and was hoping for some help.

I am trying to simplify adding multiple event listeners to the same element. I think my issue is just that I'm not using the correct scope for this when calling the controller.listenz() function. Any help would be greatly appreciated.

The error I am currently getting is being thrown in the listenz() method and is telling me "fn is not a function". Which makes sense I guess, it is an object, but how do I fix that?

JSFIDDLE

Javascript

 var controller = {

     realtime: true,
     listenz: function(ele, e, fn, c, o) {

         //validate
         if (!(e instanceof Array)) {
             throw 'Javascript Listener:  Error 642';
         }


         var h = function() {
            fn.apply(this, o && o instanceof Array ? o : []);
         };


         //bind events
         for (var i = 0; i < e.length; i += 1) {
             ele.addEventListener(e[i], h, c);
         }
     },
     initz: function() {
         this.listenz(document.getElementById("real"), ["change"], this, false);
         this.listenz(document.getElementById("foi"), ["change"], this, false);
         this.listenz(document.getElementById("sim"), ["change"], this, false);
         this.listenz(document.getElementById("rev"), ["change"], this, false);
     },

     handleEvent: function(e) {
         switch (e.target.id) {
             case 'real':
                 console.log('real');
                 //this.realtime = e.target.checked ? true : false;
                 //this.realz();
                 //if (this.realtime) this.submitz();
                 break;
             default:
                 console.log('default');
                 //if (this.realtime) this.submitz();
                 break;
         }
     }
 };

HTML

<body>
    <div class="wrapper">
        <ul>
            <li>
                Real
                <input type="checkbox" name="real" id="real">
            </li>
            <li>
                Strip
                <input type="checkbox" name="sim" id="sim">
            </li>
            <li>
                Reverse
                <input type="checkbox" name="rev" id="rev">
            </li>
            <li>
                Foil
                <input type="checkbox" name="foi" id="foi">
            </li>
        </ul>
    </div>
    <script>
        controller.initz();
    </script>
</body>

Upvotes: 0

Views: 56

Answers (1)

Kaiido
Kaiido

Reputation: 136627

A few problems :

  • The fn parameter of your listenz function actually stands for function and waits for a callback one. Here, in your listenz function you are passing this, which is the controller object. Change it to this.handleEvent.

  • The h variable will override the default event arguments to the ones specified in the o parameter in the listenz function, if any. As it is written now, if no o parameter is specified, it will apply an empty array to the callback function. What you want instead is to apply default arguments so you should change it to

     var h = function() {
        fn.apply(this, o && o instanceof Array ? o : arguments);
     }  
    

Finally, you never initiate the controller object.

Here is a working snippet :

     var controller = {

         realtime: true,
         listenz: function(ele, e, fn, c, o) {

             //validate
             if (!(e instanceof Array)) {
                 throw 'Javascript Listener:  Error 642';
             }


             var h = function() {
             	fn.apply(this, o && o instanceof Array ? o : arguments);
             };


             //bind events
             for (var i = 0; i < e.length; i ++) {
                 ele.addEventListener(e[i], h, c);
             }
         },
         initz: function() {
             this.listenz(document.getElementById("real"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("foi"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("sim"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("rev"), ["change"], this.handleEvent, false);
         },

         handleEvent: function(e) {
             switch (e.target.id) {
                 case 'real':
                     alert('real');
                 	 
                     //this.realtime = e.target.checked ? true : false;
                     //this.realz();
                     if (this.realtime) this.submitz();
                     break;
                 default:
                     console.log('default');
                     if (this.realtime) this.submitz();
                     break;
             }
         }
     };
controller.initz()
	<body>
	    <div class="wrapper">
	        <ul>
	            <li>
	                Real
	                <input type="checkbox" name="real" id="real">
	            </li>
	            <li>
	                Strip
	                <input type="checkbox" name="sim" id="sim">
	            </li>
	            <li>
	                Reverse
	                <input type="checkbox" name="rev" id="rev">
	            </li>
	            <li>
	                Foil
	                <input type="checkbox" name="foi" id="foi">
	            </li>
	        </ul>
	    </div>
	   
	</body>

Upvotes: 1

Related Questions