JavaScript execution context

I have an object called Gallery with several properties and methods. One of them, setCurrentPicture, removes all existing DOM photo and video elements from the gallery container before showing a new photo / video. In addition, my gallery stops playing the video (set it to pause) when the user clicks on it. This is the togglePlayVideo method inside the gallery prototype. First, I remove the elements from the DOM, and then show the new content. If this video, I add eventListener for documentation, use the binding method.

So, in setCurrentPicture I want to remove the EventListener for the video elements. Is it possible to associate this context with a document inside the Array.prototype.forEach method when removing eventListener? If I saved the necessary context to a new variable, then I succeeded. But then I try to bind, my IDE says "Potentially invalid use of this."

Code snippet:

Gallery.prototype = { setCurrentPicture: function(currentPhoto) { var self = this; Array.prototype.forEach.call(container.children, function(item) { if (item.tagName === 'VIDEO') { document.removeEventListener('click', self.togglePlayVideo); } if (item.tagName === 'VIDEO' || item.tagName === 'IMG') { container.removeChild(item); } }); if (pictures[currentPhoto] instanceof Video) { var video = document.createElement('video'); .... document.addEventListener('click', self.togglePlayVideo); } }, }, togglePlayVideo: function(e) { if (e.target.tagName === 'VIDEO') { return e.target.paused ? e.target.play() : e.target.pause(); } } } 

In case of adding document.addEventListener('click', self.togglePlayVideo); I can use bind instead of self: document.addEventListener('click', this.togglePlayVideo.bind(this) .

Is it possible to use bind in removeEventListener? document.removeEventListener ('click', this.togglePlayVideo.bind (this);

0
source share
2 answers

The best thing for you is to get to know what โ€œthisโ€ is and what โ€œbindโ€ is. You can do this by reading this brilliant description.

and second part

In short, when you declare a function with "this" as follows:

  • in defaul case "this" will be a Window object

    var f = function(){return this;};

    f(); //will return Window object

  • when an object owns a link to your function as follows:

    var f = function(){return this;};

    var o = {func: f};

    o.func(); // will return the "o" object becuase "this" becomes o object

  • when you use an explicit binding such as call / apply, you set it to a specific value as follows:

    var f = function(){return this;};

    var obj = {};

    f.call(obj); // will return your obj

  • and there is a so-called "tight binding". used as follows:

    var f = function(){return this;};

    var obj1 = {num:1};

    var obj2 = {num:2};

    var boundFunc = f.bind(obj1); //now it hardbound to obj1

    //let try to switch this by using "call"

    boundFunc.call(obj2); // will return obj1, because it hardbound

  • and this can be affected when calling a function with the keyword "new":

    f = function(){ this.a =1; this.b =2; };

    var obj = new f(); // will set brand new object as "this" and return it

    //so we will get {a:1, b:2} object as a result

+2
source

I should add to bind this to Array.prototype.forEach.call instead of implementing this for a callback function.

  Array.prototype.forEach.call(container.children, function(item) { if (item.tagName === 'VIDEO') { document.removeEventListener('click', this.togglePlayVideo); } if (item.tagName === 'VIDEO' || item.tagName === 'IMG') { container.removeChild(item); } }.bind(this)); 

Thanks everyone for the answers.

0
source

Source: https://habr.com/ru/post/1239156/


All Articles