0

I am creating class in javascript using function defination and "this" keyword as sample below. this is not in ES6 OR advance script. this is pure vanila scirpt ES5

THANK YOU FOR YOUR TIME. ANY QUICK HLLP WILL BE GREAT.

For Sample : trying to create class that inject iframe and exchange data between page and iframe and call specific function when notificaiton come back from iframe.

for each instance of this class will have diff function needs to call back and have diff. iframe url.

var a= new myclass('url1',fun1);

var b= new myclass('url2',fun2);

Eventlistner of message runs under window context so "this" will refer to window not the current class instance.

function myclass(url,  onMessage) {
    this.ifrmUrl = url || "about:blank";
    this.onMsgcb = onMessage ;//call once revive message from  loaded iframe

}
myclass.prototype = function () {
    function injIfrm(a, b, c) {
        //logic to inject iframe
    }
    function rcvMsg(evt) {
        console.log("rcvMsg called " + evt.origin + "...." + this.onMsgcb);
        //QUESTION: HOW TO CALL this.onMsgcb() method here.??
    }
  //bind message listner
    (function (w) {
        w.addEventListener ? w.addEventListener("message", rcvMsg, !1) : w.attachEvent && w.attachEvent("onmessage", rcvMsg);
    })(window);

    return {
        init: function () {
            //inject iframe 
            var d = document, w = window;
            (/complete|loaded/i.test(d.readyState) ? injIfrm(this.ifrmUrl, this.frmid, this.oncbs) : w.addEventListener("DOMContentLoaded", function () {
                injIfrm(this.ifrmUrl, this.frmid, this.oncbs);
            }));

        },
        sndMsg: function (msg, cb) {
            this.onMsgcb = cb;// update callback if needed
 //rcvMsg=rcvMsg.bind(this); //BIND  does not help this case
           //logic to post messsage to iframe
        }

    };
}();

////////////////updated sample 
//point is envetliner bindindg needs to happen instie any instance method of Class //and  then pass 'this' to event listner function using bind fucntion.

//now need to make sure that init called only once...need to keep private varible to keep track and nobody can overwrite externally.

function tst(cb) {
    this.name = "test1";
    this.cb = cb || function(d) {
        console.log('defualt callback called');
    };

}
tst.prototype.init = function() {
    window.addEventListener("message",
        (function(e) {
            console.log(e.data);
            this.cb(e);
        }).bind(this), false);

};

var a = new tst();
a.init();
a.cb = function(d) {
    console.log('updatedcallback called');
};

Thank you for your input and time on this.

  • The weirdest thing of your design is that `rcvMsg` is completely independent of any instances (it might even get called when there are none!) and has no way of knowing for which instance the message was meant for. – Bergi Feb 11 '20 at 00:01
  • So: put it inside the `init` method, and check against the `evt.origin` against the `ifrmUrl` to figure out whether the current instance is meant – Bergi Feb 11 '20 at 00:03
  • Thanks for your time to reply. I tried to bind window message listner with this.onMsgcb in init() method but later on if I need to change onMsgcb via sndMsg,it will not change. it will always call which is first time used when it is bind with window.onmessage. I m trying to keep fucntion private that bind the callback wiht messagelisnter and do processing before calling class method. – user3796012 Feb 11 '20 at 02:58
  • Just seen your update, looks good to me! I don't see what "*now need to make sure that init called only once*" has to do with your question though, your initial code didn't guarantee that either. Nor can you even really prevent that in ES5. I guess your best bet would be a boolean flag on the instance which records that it is already initialised. – Bergi Feb 11 '20 at 07:55

0 Answers0