Gregory Jacob
Gregory Jacob

Reputation: 31

How can I avoid anonymous / inline functions

I am relative new to JS / JQuery / HTML and am looking for a way to avoid using so many inline / anonymous functions.

here is the example of what I have working:

initialize: function () {
    $('section.content').each(this.initWaypoints);
}

initWaypoints: function (index, item) {

    $(item).waypoint(function (direction) {
        $('.navButton.' + $(item).data('label')).toggleClass('active', direction === 'down');

    },{offset: '50%',vertical: true})

    $(item).waypoint(function (direction) {
        $('.navButton.' + $(item).data('label')).toggleClass('active', direction === 'up');

    },{offset: '-50%', vertical: true});

}

What i would prefer is something like this:

initialize: function () {
    $('section.content').each(this.initWaypoints);
},

initWaypoints: function (index, item) {
    $(item).waypoint(this.down, {offset: '50%', vertical: true});              
    $(item).waypoint(this.up, {offset: '-50%', vertical: true});
},

down: function (direction) {
    $('.navButton.' + $(item).data('label')).toggleClass('active', direction === 'down');
},

up: function (direction) {
    $('.navButton.' + $(item).data('label')).toggleClass('active', direction === 'up');
}

My problem is that my up and down methods do not know what $(item) is because they are not the same scope as the first example. And i have not found out how to pass item to them.

Thanks for the help.

Upvotes: 3

Views: 299

Answers (3)

Esailija
Esailija

Reputation: 140228

If you don't care about building elaborate object model and just want to sling together some jQuery then you can simply use this:

down: function (direction) {
    $('.navButton.' + $(this).data('label')).toggleClass('active', direction === 'down');
},

up: function (direction) {
    $('.navButton.' + $(this).data('label')).toggleClass('active', direction === 'up');
}

Upvotes: 1

user405398
user405398

Reputation:

Use closures.

Try this:

initialize: function () {
    $('section.content').each(this.initWaypoints);
},

initWaypoints: function (index, item) {
    $(item).waypoint(this.down(item), {offset: '50%', vertical: true});              
    $(item).waypoint(this.up(item), {offset: '-50%', vertical: true});
},

down: function (item) {
    return function(direction) {
      $('.navButton.' + $(item).data('label')).toggleClass('active', direction === 'down');
  }
},

up: function (item) {
   return function(direction) {
      $('.navButton.' + item.data('label')).toggleClass('active', direction === 'up');
   }
}

Upvotes: 1

Ted Hopp
Ted Hopp

Reputation: 234807

There are probably several approaches to do what you want. One is to provide an extra item argument to your functions and bind the argument when you pass the functions to waypoint:

initWaypoints: function (index, item) {
    $(item).waypoint(this.down.bind(this, $(item)), {offset: '50%', vertical: true});              
    $(item).waypoint(this.up.bind(this, $(item)), {offset: '-50%', vertical: true});
},

down: function (item, direction) {
    $('.navButton.' + item.data('label')).toggleClass('active', direction === 'down');
},

up: function (item, direction) {
    $('.navButton.' + item.data('label')).toggleClass('active', direction === 'up');
}

Upvotes: 2

Related Questions