我试图在GUI加载后将所有请求都利用JS,Prototype和AJAX放在一起,该应用程序很简单:一组链接和一个容器元素,用于显示链接指向的任何内容,就像iframe一样。这里有一个近似的HTML片段:如何使用AJAX作为iframe的替代方案
<a class="ajax" href="/somearticle.html">An article</a>
<a class="ajax" href="/anotherarticle.html">Another article</a>
<a class="ajax" href="/someform.html">Some form</a>
<div id="ajax-container"></div>
伴随上述(抱歉,这是一个有点冗长)看起来像这样的JS:
document.observe('dom:loaded', function(event) {
ajaxifyLinks(document.documentElement);
ajaxifyForms(document.documentElement);
});
function ajaxifyLinks(container) {
container.select('a.ajax').each(function(link) {
link.observe('click', function(event) {
event.stop();
new Ajax.Updater($('ajax-container'), link.href, {
method: 'get',
onSuccess: function(transport) {
// Make sure new ajax-able elements are ajaxified
ajaxifyLinks(container);
ajaxifyForms(container);
}
});
});
});
}
function ajaxifyForms(container) {
console.debug('Notice me');
container.select('form.ajax').each(function(form) {
form.observe('submit', function(event) {
event.stop();
form.request({
onSuccess: function(transport) {
$('ajax-container').update(transport.responseText);
// Make sure new ajax-able elements are ajaxified
ajaxifyLinks(container);
ajaxifyForms(container);
}
});
});
});
}
当点击一个链接,该响应将显示在容器中。我没有在容器中使用iframe,因为我希望页面上的任何元素都可以通过JS在某些时候与对方进行通信。现在,有一个大问题和一个奇怪的现象:
问题:如果一个表单被返回并显示在容器中,上面的JS会试图将相同的行为应用于表单,以便在提交后收到任何响应显示在容器中。这失败了,因为提交事件从未被捕获。为什么?请注意,所有返回的表单元素都具有class =“ajax”属性。
现象:注意ajaxifyForms()中的console.debug()语句。我希望它在页面加载后输出到控制台一次,然后每次使用表单更新容器。事实是,每次单击指向表单的链接时,控制台的输出数似乎都会增加一倍。为什么?
因为你附加的事件处理程序到你的页面加载链接和表单。然后,当Ajax请求完成时,将事件处理程序附加到链接和表单中,依此类推。因此,原始链接和表单在第一次链接点击后有2个事件处理程序连接到它们,然后在每次点击之后有更多,然后更多。 – 2012-02-18 23:21:49
谢谢,保罗。我怀疑它必须遵循这些原则。 – 2012-02-19 13:43:14