Skip to main content
Participant
May 5, 2016
Question

Issue with moduleReadyEvent CP9 external Javascript

  • May 5, 2016
  • 2 replies
  • 702 views

I am trying to create an external script that detects when a captivate SWF ends so the user can choose to move onto the next SWF or quit.

The SWF's are dynamically loaded onto the page using an XML document as a reference and then removed from the DOM using jquery when a new SWF is loaded.

My issue is that the external script works flawlessly. Exactly once. Any videos loaded after the initial video do not activate the script.

var interfaceObj;

var eventEmitterObj;

var i=1;

window.addEventListener("moduleReadyEvent", function evtFunc(evt)

{

    console.log(i++);

//evt.Data carries the interface object.

//It is same as window.cpAPIInterface

interfaceObj = evt.Data;

eventEmitterObj = interfaceObj.getEventEmitter();

      initializeEventListeners();

      //evt.returnValue = true;

      return true;

});

function initializeEventListeners()

{

console.log(i++)

//check if window.cpAPIInterface is available

if(interfaceObj)

{

    // window.removeEventListener("moduleReadyEvent", function(evt){})

    //check if window.cpAPIEventEmitter is available

    if(eventEmitterObj)

    {

              //add a listener to CPAPI_SLIDEENTER event

        eventEmitterObj.addEventListener("CPAPI_MOVIESTOP",function endSimFunc(e)

            {

                console.log("End of Simulation!")

            });

            }

}

}

I am loading the videos onto the page using a slight variant of the provided code on a CP9 publish.

function linkID(swfObj){

    //alert(swfObj.getAttribute("href"));

      var swfLink = swfObj.getAttribute("href");

     //alert(swfLink);

  var strURLFull = window.document.location.toString();

  var intTemp = strURLFull.indexOf("?");

  var strURLParams = "";

  if(intTemp != -1)

  {

  strURLParams = strURLFull.substring(intTemp + 1, strURLFull.length);

  }

        //alert("do i run first");

     var so = new SWFObject( swfLink, "Captivate", "1300", "874", "10", "#CCCCCC" );

  so.addParam("quality", "high");

  so.addParam("name", "Captivate");

  so.addParam("id", "Captivate");

  so.addParam("wmode", "window");

  so.addParam("bgcolor","#000000");

  so.addParam("seamlesstabbing","false");

  so.addParam("menu", "false");

  so.addParam("AllowScriptAccess","always");

        so.addParam("security", "allowDomain();");

  so.addVariable("variable1", "value1");

  if(strURLParams !== "")

  {

  so.addVariable("flashvars",strURLParams);

  }

  so.setAttribute("redirectUrl", "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash");

  so.write("objectDiv");

         return false;

}

Can anyone tell me why the scripts fire only once? I need to be able to detect the end of the published SWF on every video available to the user.

In the JQuery to dynamically load/unload the SWF's I have tried both .remove() and .unload() methods. I am extremely new to Captivate and almost as new to Javascript, so I feel like I am fundamentally misunderstanding how something here is working.

Any help would be extremely appreciated.

This topic has been closed for replies.

2 replies

Participant
May 9, 2016

Hi, again, thank you so much for taking the time to reply, I really appreciate it.

I'm using the moduleReadyEvent, as I am attempting to apply javascript to existing published SWFs, and cannot republish them to include any JS in the actual publish. As I understood from the documentation Adobe provides, I need to use this. That should fire once, to say Flash is loaded and ready to be interacted with.

I can confirm that endSimFunc(e) only fires once as well.

So I load the first video, and everything works as expected. Then I try to load a second and nothing works. I am loading the videos onto the DOM using code ripped straight from the index of a publish in CP9 and then removing them using the .remove() function in JQuery. Is it perhaps due to the way I am loading and unloading the SWF?

Thanks

TLCMediaDesign
Inspiring
May 9, 2016

That's what I alluded to in my previous comment. Instead of loading swf's in the same html file you should put the files in separate folders with all of the necessary files and link to the html pages.

Since you have a working folder structure, copy that into project folders and replace the swf's for each.

Participant
May 10, 2016

Hi, thank you for your help.

I actually found a different answer to the problem that doesn't involve reloading new html pages to attach listeners and events each time.

window.addEventListener("moduleReadyEvent", function evtFunc(evt)

{

      window.cpAPIEventEmitter.addEventListener("CPAPI_MOVIESTOP",function endSimFunc(e)

            {

                console.log("End of Simulation!");

  window.cpAPIInterface = undefined;

  window.cpAPIEventEmitter = undefined;

            });

});

I could move it all within the one function, and then reset the states of window.cpAPIInterface and window.cpAPIEventEmitter after the CPAPI_MOVIESTOP listener is triggered. This suits my needs perfectly, as it means each video I load is treated as fresh again. Downsides are if you reach the end of a video, and it triggers, if you rewind it won't trigger again. But, for my use case, this is fine and I can work around that.

Thank you for your help, your answers really got me thinking as to why it needed a new page each time.

The problem line in the standard.js file is the if(!cpAPIInterface) statement, it only allows the important stuff to run once if cpAPIInterface has already been defined.

Also, as a side note, Adobe's provided code on the Common JS page is actually near worthless.

Again, thank you for taking the time to answer my questions and attempt to help me out, I appreciate it a lot.

TLCMediaDesign
Inspiring
May 5, 2016

I think it's because you are only swicthing swf's in the same page, you need to load from the html page that goes with the swf. You'll see the functions are actually in the standard.js which you have only loaded once.

Participant
May 6, 2016

Thanks for your answer, it makes sense and has put me on the right path.

Do you know if there's any way to sort of force them to reload each time I call a SWF in order to maintain the single page aspect of the application?

TLCMediaDesign
Inspiring
May 6, 2016

Are you saying that the endSimFunc(e) only fires once also?

It's not necessary to use the moduleReady event. When I create html5 add-ins and insert them on the first slide, the moduleReady event has already fired, so I just go ahead and add the specific listeners I want.