Jakub Kohout Jakub Kohout - 8 months ago 37
Javascript Question

Accessing clicked element and "this" class reference in the same scope

I have this piece of code written in coffeescript (sorry..)

_this = this
$('body').on 'click', '.open-modal', =>
_this.modalId = $(this).attr('data-modal-id')
_this.modalEl = $( '#' + _this.modalId )
_this.modalAction = $(this).attr('data-action')


is there a way how to access clicked element
and in the same time preserving
keyword for the Class not the clicked element.

basically I would want to achieve something like this

$('body').on 'click', '.open-modal', (el) =>
this.modalId = $(el).attr('data-modal-id')
this.modalEl = $( '#' + this.modalId )
this.modalAction = $(el).attr('data-action')


is there a way how to do it?


If you are using ECMAScript 6, the arrow function syntax (() => {}) does this, though you'll have to get the element from the event object. I think CoffeeScript might convert it's () => {} syntax to ES5 version of a function and may not do this (I think it depends on your compiler settings).

$('body').on('click', '.open-modal', (evt) => {
    this.modalId = $(evt.target).attr('data-modal-id');
    this.modalEl = $('#' + this.modalId);
    this.modalAction = $(evt.target).attr('data-action');

If you can't use that, the common pattern is to save this as self and then use that in other scopes. This doesn't rely on any specify compiler help.

var self = this;
$('body').on('click', '.open-modal', function () {
    this.modalId = $(this).attr('data-modal-id')
    this.modalEl = $('#' + self.modalId)
    this.modalAction = $(this).attr('data-action')

Finally, if you really want it exactly as you have it, you can wrap the callback in another function that sets things up as you want.

$('body').on('click', '.open-modal', (function (self) {
    return function () { 
        (function (el) {
            this.modalId = $(el).attr('data-modal-id');
            this.modalEl = $('#' + this.modalId);
            this.modalAction = $(el).attr('data-action');
        }).call(self, this);

That that's a bit silly and overkill. It uses a self-calling function to scope the this to self, returns a function, which then wraps another that uses call to specify this and pass in the element as a parameter.