Martyn Ball
Martyn Ball

Reputation: 4885

JavaScript assign function within variable to click event within plugin

I have got a plugin where I assign click event functions based on a string. However I don't think I can use Window['variable name'] as the variable is within my plugin scope not the window scope.

How would I go about assigning the EventLeft/EventRight/EventClose variable anonymous functions to the click event of the querySelectorAll loop?

(function() {

  // Constructor
  this.MarvLightbox = function() {

    // Initialise plugin
    this.open();
  };

  MarvLightbox.prototype.open = function() {

    setupLightbox.call(this);
  };

  function setupLightbox() {

    var createExpand = function(img) {

          // Generate lightbox HTML and append
          var instance = this,
              html = buildHTML(instance.options.html),
              EventClose = function() {
                // Do stuff
              },
              EventLeft = function() {
                // Do stuff
              },
              EventRight = function() {
                // Do stuff
              };

          // Lightbox is active
          instance.active = true;

          // Assign click events
          html.getElementsByClassName('image')[0].src = img;

          html.querySelectorAll('[data-click]').forEach(function(e) {
            e.addEventListener('click', function() { instance[this.dataset.click]; });
          });

    }.bind(this);

  }

});

Upvotes: 0

Views: 67

Answers (2)

t.niese
t.niese

Reputation: 40852

While you own answer will work it is not really readable and therefore not easy to maintain.

Store your functions in an object and use the key to access it.

var events = {
  EventClose: function() {
    instance.active = false;
    item.current = null;
  },
  EventLeft: function() {
    if (item.current !== 0) {
      item.current = item.current - 1;
    } else {
      item.current = instance.images_count;
    }
  },
  EventRight: function() {
    if (item.current !== instance.images_count) {
      item.current = item.current + 1;
    } else {
      item.current = 0;
    }
  }
}

html.querySelectorAll('[data-click]').forEach(function(e) {
  e.addEventListener('click', events[e.dataset.click]);
})

Upvotes: 1

Martyn Ball
Martyn Ball

Reputation: 4885

Not too sure why the question is so confusing. Managed to find a solution:

events = function(fnstring) {
  switch(fnstring) {
      case 'EventClose': (function() {
        instance.active = false;
        item.current = null;
      }()); break;
      case 'EventLeft': (function() {
        if (item.current !== 0) {
          item.current = item.current - 1;
        } else {
          item.current = instance.images_count;
        }
      }()); break;
      case 'EventRight': (function() {
        if (item.current !== instance.images_count) {
          item.current = item.current + 1;
        } else {
          item.current = 0;
        }
      }()); break;
    }
};

html.querySelectorAll('[data-click]').forEach(function(e) {
  e.addEventListener('click', function() { events(e.dataset.click); });
});

Upvotes: 0

Related Questions