0

I have an Object that called vars and it belongs to a jQuery plugin function. The vars object contains bunch of HTML DOM classes for using inside of the class scope. My expectation is to pass the object into the class and could access it no matter where it has been called from the scope.

Passing the vars to a new class Proto works fine. The problem is when I try to get the vars from a nested function, it doesn't work (esp touch methods in my case). The vars can be only accessed through the constructor and the instance methods.

This is the code:

(function ($, window, undefined) {
  $.fn.plugin = function(options) {
    return this.each(function() {
      const that = $(this);
      const vars = {
        thatItem : 'thatItem'
        // ...
      }
      var Proto = new className(options, vars);
      Proto.exe(that);
    })
    // ...
  }
  class className {
    constructor(options, globals) {
      const defaults = {
        value: 'this is a value'
      }
      this.options = Object.assign(defaults, options);
      this.globals = globals;
      console.log(this.globals, 'can be called using this keyword. works fine.');
    }
    exe(that) {
      that.on({
        touchstart:this.istouchStart,
        touchmove:this.istouchMove,
        touchend:this.istouchEnd
      })
    }
    istouchStart(e) {
      this.coordX = e.touches[0].clientX;
      this.coordY = e.touches[0].clientY;
      return this.coordX, this.coordY;
    }
    istouchMove(e) {
      let dx = e.touches[0].clientX,
          dy = e.touches[0].clientY,
          dist = Math.sqrt(dx + this.coordX);
    }
    istouchEnd(e) {
      var dist = e.changedTouches[0].clientX - this.coordX;
      if (dist > 200) {
        console.log(this.globals, "It doesn't work inside of the touch event.");
      } else if (dist < -200) {
      } else {
      }
      console.log(dist);
      e.stopPropagation();
    }
  }
}(jQuery));
$('.inline-grid').plugin({})
      * {
        margin: 0;
        padding: 0;
      }
      html, body
      {
        background-color: black;
      }
      div {
        position: relative;
      }
      .inline-grid {
        margin: 0 auto;
        width: 560px;
        border: 7px solid teal;
        display: flex;
        flex-flow: row;
        overflow: hidden;
      }
      .wrap {
        width: 100%;
        display: flex;
        flex-flow: row;
      }
      .cell {
        display: flex;
        flex-flow: column;
        flex-shrink: 0;
        width: 100%;
        height: 200px;
      }
      .orange {
        background-color: orange;
      }
    <div id="slider" class="inline-grid">
      <div class="wrap">
        <a href="#" class="cell orange">

        </a>
        <a href="#" class="cell blue">

        </a>
        <a href="#" class="cell crimson">

        </a>
        <a href="#" class="cell green">

        </a>
      </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

I've changed istouchEnd(e) to istouchEnd(globals) for giving the vars as the parameter directly. And I used return keyword to pass the event but this way also didn't work.

istouchEnd(globals) {
  return function(e) {
    var dist = e.changedTouches[0].clientX - this.coordX;
    if (dist > 200) {
      console.log(this.globals, "It doesn't work when this.globals are inside of the nested function.");
    } else if (dist < -200) {
    } else {
    }
    console.log(dist);

  }
  e.stopPropagation();
}

How would I get the vars in the nested functions?

=============== Question Updated ===============

first try:

 exe(that) {
  that.on({
    touchstart: (e) => {
      this.coordX = e.touches[0].clientX;
      this.coordY = e.touches[0].clientY;
      return this.coordX, this.coordY;
    },
    touchmove: (e) => {
      let dx = e.touches[0].clientX,
          dy = e.touches[0].clientY,
          dist = Math.sqrt(dx + this.coordX);
      console.log('test');
    },
    touchend: (globals) => {
      return function(e) {
        var dist = e.changedTouches[0].clientX - this.coordX;
        if (dist > 200) {
          console.log(this.globals, "It doesn't work inside of the touch event.");
        } else if (dist < -200) {
        } else {
        }
        console.log(dist);
        e.stopPropagation();

      }
    }
  })
}
l3lue
  • 531
  • 4
  • 16
  • With `touchend:this.istouchEnd`, the handler loses its calling context of `this`. Use `.bind` or an arrow function – CertainPerformance Mar 18 '19 at 03:38
  • @CertainPerformance I've tried it just right now but it didn't work. the `touchend` still doesn't respond. I will update my question for showing what I've done. – l3lue Mar 18 '19 at 03:44
  • 1
    Your `return function(e) {` is still a full-fledged `function`, so the `this` is not the same as in the outer scope. Use, eg, `touchend: () => this.istouchEnd()` – CertainPerformance Mar 18 '19 at 03:48
  • Thank you for advice @CertainPerformance. I should've given the `globals` as the parameter into the `exe` function. After I fixed that, `touchend: (e) => this.istouchEnd(e, globals)` this way works. – l3lue Mar 18 '19 at 08:54

0 Answers0