我正在使用 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 请求完成后重新执行它:
使用
oncomplete
PrimeFaces 命令按钮的属性:oncomplete="applyChangeHandler()"
使用
<h:outputScript target="body">
而不是$(document).ready()
,<h:outputScript id="applyChangeHandler" target="body"> applyChangeHandler(); </h:outputScript>
并在
update
中引用它属性:update=":applyChangeHandler"
使用
<p:outputPanel autoUpdate="true">
在每个 ajax 请求时自动更新它:<p:outputPanel autoUpdate="true"> <h:outputScript id="applyChangeHandler"> applyChangeHandler(); </h:outputScript> </p:outputPanel>
使用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/