0

my target is to play audio file with quicktime plugin and listen for the audio end event and then update the audio object with another file to play and so on

here is the audio element (I am using primefaces4):

 <h:panelGroup id="questionsAudioPG">
    <object width="2" height="2" data="#{testBean.audioPath}" id="speechAudio"
    name="speechAudio" >
    <param name="CONTROLLER" value="false" />
    <param name="AUTOPLAY" value="true" />
    <param name="LOOP" value="false" />
    <param name="POSTDOMEVENTS" value="true" />
    <param name="ENABLEJAVASCRIPT" value="true" />
    </object>
 </h:panelGroup>

and here is my javascript code:

<h:outputScript type="text/javascript">

$(document).ready(function(){
    RegisterListener('qt_ended', 'speechAudio', 'speechAudio_embed', audioEndedEventFired);
});

function audioEndedEventFired() {
audioEnded();
}

function myAddListener(obj, evt, handler, captures) {
    if (document.addEventListener)
        obj.addEventListener(evt, handler, captures);
    else
        // IE
        obj.attachEvent('on' + evt, handler);
}

function RegisterListener(eventName, objID, embedID, listenerFcn) {
    var obj = document.getElementById(objID);
    if (!obj)
        obj = document.getElementById(embedID);
    if (obj)
        myAddListener(obj, eventName, listenerFcn, false);
}
</h:outputScript>

what is happening now is that my listener is working properly at the first time, but after my handler function updates the page by ajax the event is never fired again !!

I guess that this is happening because the DOM is changed and I need to re register the event listener again after each ajax update to the audio element.

BTW: the qt event is fired on chrome only and not fired in firefox.

any help is appreciated.

Dorgham
  • 962
  • 1
  • 9
  • 17

1 Answers1

0

I guess that this is happening because the DOM is changed and I need to re register the event listener again after each ajax update to the audio element.

Yes, if you load new content into your page that replaces elements you previously had event listeners on and you are using static event handlers (which you are), then you will have to reattach those event handlers to the new DOM elements in the new content.

Event handlers like you are using are attached to a specific DOM element. When you load new content and replace DOM elements with new DOM elements, the event handlers you had on the old DOM elements are gone.

One possible fix is to simply call:

RegisterListener('qt_ended', 'speechAudio', 
    'speechAudio_embed', audioEndedEventFired);

again after you replace the element with id='speedAudio' or 'speechAudio_embed'.


Another approach (if the events you're listening for bubble) is to use delegated event handling where you attach your event listener to a parent object that is not replaced and you use e.target to see which object triggered the event. If your events bubble and you use delegated event handling attached to a parent object that is not itself recreated, then your event handler will still work even after you replace the child content.


OK, now that the question has turned into one about Primefaces.ab(), this SO answer shows the first argument to the .ab() method is a cfg object that can be given an oncomplete property that will specify a function to be called when the ajax call is done.

var cfg = {
   ...
   oncomplete: function() {
       // register your event handlers here
   }
};
Primefaces.ab(cfg, ...);

There's a template example for specifying the oncomplete handler on page 509 of this Primefaces documentation.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • then how to implement this solution ? I tried jquery (document).on function but didn't work, may be I implemented it wrong. – Dorgham May 23 '14 at 23:47
  • @MohammadDorgham - I don't know if the qt_ended event bubbles or not so I don't know if it would work with delegated event handling. The proper way to use jQuery's `.on()` for delegated event handling is described [here](http://stackoverflow.com/questions/8752321/jquery-live-vs-on-method-for-adding-a-click-event-after-loading-dynamic-ht/8752376#8752376) and [here](http://stackoverflow.com/questions/9814298/does-jquery-on-work-for-elements-that-are-added-after-the-event-handler-is-cre/9814409#9814409). I also added another option to my answer where you just call `RegisterListener()` again. – jfriend00 May 23 '14 at 23:49
  • when to call the register function again ? I mean how do I know that the document is reloaded ? that's my main question. – Dorgham May 24 '14 at 00:22
  • @MohammadDorgham - If that's your main question, then please show us the code that loads the new content. We can't help on that without seeing that code. If you're using jQuery's `.load()`, then you just supply a completion function for that and call `RegisterListener()` from the completion function. – jfriend00 May 24 '14 at 00:29
  • I am using primefaces, here it is: ... I tried oncomplete attribute with no use – Dorgham May 24 '14 at 00:31
  • @MohammadDorgham - that looks like some sort of server template language - that is not what the browser sees and is not regular HTML or javascript. You will have to either shed some light on how this works or do some research on it yourself to find out if it has a notification for when it's done reloading content or add to your question what back-end this is from so someone who knows that back-end can perhaps help you. – jfriend00 May 24 '14 at 00:36
  • actually this primefaces code translates to this javascript: – Dorgham May 24 '14 at 00:40
  • @MohammadDorgham - see what I added to the end of my answer. – jfriend00 May 24 '14 at 00:51