1

I have a problem with the setAttribute function.

Here my code

mind.SetRequest(rec_input.value);
mind.Reply();
element.setAttribute('text', mind.GetReply());
element.speak();

element.speak() isn't waiting for setAttribute to be completed.

Is there any function to call speak() when setAttribute is finished?

The img.onload = function(){ . . . } function called after the img is loaded, is there a similar way where I can call my speak function after setAttribute?

Sumner Evans
  • 8,951
  • 5
  • 30
  • 47
Gor
  • 2,808
  • 6
  • 25
  • 46

1 Answers1

5

Try this:

mind.SetRequest(rec_input.value);
mind.Reply();
element.setAttribute('text', mind.GetReply());
setTimeout(function () {
   element.speak();
}, 0);

setAttribute() is synchronous, but it is DOM-based method. It means browser needs some additional processor ticks to set that attribute. So use timeouts to move code execution (that tries to get that attribute) to the next event loop.

Max
  • 1,824
  • 13
  • 22
  • Hi Max , I am trying your method, but in this way speak function didnt called – Gor May 09 '15 at 10:29
  • can you tell me more, why in this way all goes well, but my method didnt worked, or where I can read about it more , thank you – Gor May 09 '15 at 20:40
  • @Gor Yes, sure. In short: setTimeout(element.speak, 0) didn't work because of .speak() is DOM API provided by `SpeechSynthesis` class and DOM APIs can't be called in that way, because setTimeout call `fn.apply(this, ...)` and it looses the context. But if you wrap `element.speak()` into anonymous function is saves context (`this` is linked with `element`). But that is not all. Since you set `text` attribute (DOM operation) you need move all code requires this attribute to the next loop of life cycle. It's called multi-tasking. Read more here: http://stackoverflow.com/a/779785/1453833 – Max May 11 '15 at 11:06