【问题标题】:how to detect element update with ajax everytime如何每次都使用ajax检测元素更新
【发布时间】:2014-05-23 22:46:47
【问题描述】:

我的目标是使用 quicktime 插件播放音频文件并监听音频结束事件,然后用另一个文件更新音频对象以播放等等

这是音频元素(我使用的是 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>

这是我的 javascript 代码:

<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>

现在发生的事情是我的侦听器第一次正常工作,但是在我的处理函数通过 ajax 更新页面后,该事件再也不会触发了!

我猜这是因为 DOM 发生了变化,我需要在每次 ajax 更新到音频元素后再次重新注册事件监听器。

顺便说一句:qt 事件仅在 chrome 上触发,而不在 firefox 中触发。

感谢任何帮助。

【问题讨论】:

    标签: javascript jquery html ajax primefaces


    【解决方案1】:

    我猜这是因为 DOM 发生了变化,我需要 在每次 ajax 更新到 音频元素。

    是的,如果您将新内容加载到您的页面中以替换您之前拥有事件侦听器的元素并且您正在使用静态事件处理程序(您就是这样),那么您将不得不将这些事件处理程序重新附加到新的 DOM 元素新内容。

    您正在使用的事件处理程序附加到特定的 DOM 元素。当您加载新内容并用新的 DOM 元素替换 DOM 元素时,您在旧 DOM 元素上的事件处理程序就消失了。

    一种可能的解决方法是简单地调用:

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

    在将元素替换为 id='speedAudio''speechAudio_embed' 之后再次。


    另一种方法(如果您正在侦听气泡的事件)是使用委托事件处理,您将事件侦听器附加到未替换的父对象,并使用e.target 查看触发事件的对象。如果您的事件冒泡并且您使用附加到未重新创建的父对象的委托事件处理,那么即使您替换了子内容,您的事件处理程序仍然可以工作。


    好的,既然问题已经变成了关于Primefaces.ab() 的问题,this SO answer 显示.ab() 方法的第一个参数是一个cfg 对象,它可以被赋予一个oncomplete 属性,该属性将指定一个ajax 调用完成时要调用的函数。

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

    this Primefaces documentation 的第 509 页上有一个用于指定 oncomplete 处理程序的模板示例。

    【讨论】:

    • 那么如何实现这个解决方案呢?我试过 jquery (document).on 函数但是没用,可能是我实现错了。
    • @MohammadDorgham - 我不知道 qt_ended 事件是否会冒泡,所以我不知道它是否适用于委托事件处理。在herehere 中描述了使用jQuery 的.on() 进行委托事件处理的正确方法。我还在我的答案中添加了另一个选项,您只需再次致电RegisterListener()
    • 何时再次调用注册函数?我的意思是我怎么知道文档已重新加载?这是我的主要问题。
    • @MohammadDorgham - 如果这是您的主要问题,请向我们展示加载新内容的代码。如果没有看到该代码,我们将无能为力。如果您使用的是 jQuery 的 .load(),那么您只需为此提供一个完成函数并从完成函数中调用 RegisterListener()
    • 我正在使用 primefaces,这里是: ...我尝试了 oncomplete 属性没用的
    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    相关资源
    最近更新 更多