setTimeout not working in injected JavaScript?

956 views Asked by At

I have an external JavaScript file mypapopup.js with this content:

function mypopup() {
alert("Hello stackoverflow")
}

In a Delphi XE8 VCL Form application, with TEmbeddedWB.ExecScript I inject this JavaScript into a loaded document in EmbeddedWB:

procedure TForm1.btnPopupJSClick(Sender: TObject);
begin
   EmbeddedWB1.ExecScript('var script = document.createElement(''script'');' +
                          'script.src = "mypapopup.js";' +
                          'script.setAttribute(''type'', ''text/javascript'');' +
                          'document.getElementsByTagName(''head'')[0].appendChild(script);' +
                          'setTimeout(mypopup(), 1000);'
                          ,'JavaScript');   
end;

Please note that with this code a script tag is being added to the HEAD section which references the external JavaScript file mypapopup.js.

Then the mypopup function from the external JavaScript file is called with a delay of 1000 ms.

After clicking once the button btnPopupJS in my Delphi program nothing happens.

Only after clicking the button btnPopupJS in my Delphi program a second time the JavaScript popup is executed WITHOUT A DELAY!

This is also the case when I increase the setTimeout delay to e.g. 5000 ms, where also after having clicked the button a second time the popup is executed WITHOUT A DELAY.

So is there a way to wait until the external JavaScript has been loaded and then automatically execute the mypopup function?

EDIT: I have found a solution, but I don't know whether this is an optimal solution:

procedure TForm1.btn1Click(Sender: TObject);
var
  t, tt: Int64;
begin
   EmbeddedWB1.ExecScript('var script = document.createElement(''script'');' +
                          'script.src = "mypapopup.js";' +
                          'script.setAttribute(''type'', ''text/javascript'');' +
                          'document.getElementsByTagName(''head'')[0].appendChild(script);'
                          // + 'setTimeout(mypopup, 1000);'
                          ,'JavaScript');

   t := TThread.GetTickCount;
   repeat
     tt := TThread.GetTickCount - t;
     Application.ProcessMessages;
   until tt > 1000;

   EmbeddedWB1.ExecScript('mypopup();', 'JavaScript');
end;
2

There are 2 answers

0
mario.van.zadel On

I think there will be a reference error when executing setTimeout(mypopup, 1000); because the external js file isn't loaded yet so that mypopup is unknown when executing that line.

Please change

setTimeout(mypopup, 1000);

to

setTimeout(function() { mypopup(); }, 1000);
0
vega On

i also had a same problem. I soluted this problem with this code:

window.setTimeout(function(){ mypopup();},5000);

maybe it`s helpfull for you