javascript - JSF/PrimeFaces ajax 更新破坏了 jQuery 事件监听器函数绑定(bind)

标签 javascript jquery ajax jsf-2 primefaces

我正在使用 jQuery 为 HTML 中的每个 input 注册一个 change 事件监听器,如下所示:

<h:head>
    <script type="text/javascript">
        //<![CDATA[
        $(document).ready(function(){
            $(':input').each(function() {
                $(this).change(function() {
                    console.log('From docReady: ' + this.id);
                });
            });
        });

        function changeHandler() {
            console.log("from changeHandler");
        }
        //]]>
    </script>
</h:head>
<h:body>
    <h:form id="topForm">
        <p:commandButton id="myButton" value="update"
                         action="#{testBean.submit}"
                         partialSubmit="true" process=":myForm:panel"
                         update=":myForm:panel" />
    </h:form>
    <h:form id="myForm">
        <p:panel id="panel">
            <p:inputTextarea id="myTextarea"
                             value="#{testBean.val}"
                             onchange="changeHandler();"/>
        </p:panel>
    </h:form>
</h:body>

如果用户更改 myTextarea 的内容,则会触发两个 change 事件。然而,按下更新按钮后,部分更新了myTextarea,之后只有changeHandler 被触发。 $(document).ready() 中绑定(bind)的事件不再触发。

这是 PrimeFaces 相关的和/或预期的行为吗?如果是,那么我如何确保触发第二个事件而不再次重新运行文档就绪脚本。

最佳答案

至于问题的原因,ajax 请求将使用 ajax 响应中的新 HTML 元素更新 HTML DOM 树。显然,这些新的 HTML 元素没有附加 jQuery 事件处理函数。然而,$(document).ready()不会在 ajax 请求上重新执行。您需要手动重新执行它。

这可以通过多种方式实现。最简单的方法是使用 $(document).on(event, selector, function)而不是$(selector).on(event, function) 。这与文档和给定的 functionRef 相关。当给定 eventName 时总是被调用在与给定 selector 匹配的元素上触发。因此您永远不需要通过 JSF 方式显式地重新执行该函数。

$(document).on("change", ":input", function() {
    console.log("From change event on any input: " + this.id);
});
<小时/>

另一种方法是在 ajax 请求完成后自己显式地重新执行该函数。当您真正有兴趣在 ready 期间立即执行该函数时,这将是唯一的方法。/load事件(例如,直接应用一些插件特定的行为/外观,例如日期选择器)。首先,您需要重构 $(document).ready()将作业转换为可重用函数,如下所示:

$(document).ready(function(){
    applyChangeHandler();
});

function applyChangeHandler() {
    $(":input").on("change", function() {
        console.log("From applyChangeHandler: " + this.id);
    });
}

(请注意,我删除并简化了您完全不必要的 $.each() 方法)

然后,选择以下方式之一在 ajax 请求完成后重新执行它:

  1. 使用 oncomplete PrimeFaces 命令按钮的属性:

    oncomplete="applyChangeHandler()"
    
  2. 使用<h:outputScript target="body">而不是$(document).ready() ,

    <h:outputScript id="applyChangeHandler" target="body">
        applyChangeHandler();
    </h:outputScript>
    

    并在 update 中引用它属性:

    update=":applyChangeHandler"
    
  3. 使用<p:outputPanel autoUpdate="true">在每个 ajax 请求时自动更新它:

    <p:outputPanel autoUpdate="true">
        <h:outputScript id="applyChangeHandler">
            applyChangeHandler();
        </h:outputScript>
    </p:outputPanel>
    
  4. 使用OmniFaces <o:onloadScript> 而不是$(document).ready() , <h:outputScript>一切都在他们身上。

    <o:onloadScript>applyChangeHandler();</o:onloadScript>
    

关于javascript - JSF/PrimeFaces ajax 更新破坏了 jQuery 事件监听器函数绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31199913/

相关文章:

javascript - 了解 AJAX

JavaScript、React - 发送多个同时的 ajax 调用

javascript - 从基于 JS 的 AIR 应用程序登录 ColdFusion 站点?

javascript - 通过 javaScript 获取 chrome 中当前的事件语言 (Chrome 66 Stable)

javascript - 在 Handlebar JS 中声明公共(public)变量

javascript - 如何测试测试中的负面行为?就像调用 API 失败时一样

javascript - JavaScript 中的单词词典及其翻译

javascript - 使用 JS onclick 使特定表格范围的内容可编辑

javascript - 在 jQuery 中设置下拉菜单的值时,.change 函数会被调用吗?

javascript - 从 <div> 添加/删除 <button>?