【问题标题】:AJAX forces page refresh (but shouldn't)AJAX 强制页面刷新(但不应该)
【发布时间】:2013-10-20 21:34:37
【问题描述】:

使用 JQuery 的简单 AJAX 测试页面。 显示的页面最初显示按钮 (BUTTON1)。点击后,它将通过 script.js 运行 react.php。 react.php 将通过 span 元素将 BUTTON1 替换为 BUTTON2。这一切都有效。

这就是问题所在。点击 BUTTON2 应该通过 script2.js 运行 react2.php。 react2.php 然后应该用文本“SUCCESS”替换 BUTTON2。但是,当单击 BUTTON2 时,页面会刷新(并再次显示 BUTTON1),而不是这样做。

当初始 begin.php 页面上的按钮类从 button1 更改为 button2 时,按钮成功替换为 react2.php 中的字符串。我无法深究。

如何防止刷新,以便页面在 span 元素中显示“SUCCESS”? 提前致谢!

beginning.php

 <html>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="script2.js"></script>
<?php
echo "<span class='span_display'>
    <a href='' id='button1' class='button1'>BUTTON1</a>&nbsp;
</span>";
?>
</html>

script.js

$(function() {
    $(".button1").click(function() {
        $.ajax({
            url: "react.php",
            cache: false,
            success: function(html) {
                $(".span_display").html(html);
            }
        });
        return false;
    });
});

script2.js

...(all the same except)
   url: "react2.php",

react.php

<?php
echo "<a href='' id='button2' class='like_button2'>BUTTON2</a>&nbsp;";
?>

react2.php

<?php
echo "SUCCESS";
?>

【问题讨论】:

  • 因为您的脚本无法识别按钮2。你必须把它放在你的标记中(隐藏它,并在你第一次点击按钮后显示它)或者你必须在你的 react.php 中输出你的 button2 点击处理程序。不过会选择第一个选项。我没有将其作为答案发布,因为我对第二个选项不是 100% 确定,而且我现在没有时间测试它。
  • 感谢您的回答。对不起,您能否通过一些提示或示例来扩展您的答案,以说明如何将此原则放入代码中?你的意思是这样的:link?这里是初学者。
  • 由于您似乎是 SO 的新用户,我想鼓励您take the tour 或阅读help page,了解如何(以及为什么)接受答案。 ;-) 请不要使用 w3schools 作为资源,而是使用 [官方文档](api.jquery.com/)。

标签: javascript php jquery ajax


【解决方案1】:

您的问题是由于第二个链接上缺少单击处理程序造成的,因为它是通过 ajax 动态添加的。通常建议使用delegated events 而不是直接将处理程序附加到元素:

function handler(uri) {
    $.ajax({
        url: uri,
        cache: false,
        success: function(html) {
            $(".span_display").html(html);
        }
    });
}

$(document)
    .on("click", "#button1, #button2", function(e) {
        e.preventDefault();
        var uri = $(this).hasClass("button1") ? "react.php" : "react2.php";
        handler(uri);
    });
});

jQuery documentation 解释得很精彩,所以我就引用它吧:

委托事件的优点是它们可以处理来自 以后添加到文档中的后代元素。经过 选择一个保证在该时间存在的元素 附加了委托事件处理程序,您可以使用委托事件 避免频繁附加和删除事件处理程序的需要。这 element 可以是视图中的容器元素 例如,模型-视图-控制器设计,或记录事件 处理程序想要监视文档中的所有冒泡事件。这 文档元素在文档头部之前可用 加载任何其他 HTML,因此在此处附加事件是安全的 等待文档准备好。

除了处理后代元素事件的能力 尚未创建,委托事件的另一个优点是它们 当必须使用许多元素时,开销可能会低得多 监控。

【讨论】:

  • 我花了一些时间来理解这段代码以及它应该如何工作,但我想我现在明白了原理。但是,它仍然不起作用。我将您的代码 sn-p 放入 script.js 并在 begin.php 中禁用 script2.js。现在单击 BUTTON1 会刷新页面以再次显示 BUTTON1。
  • 我现在开始工作了。你的方法做到了。只是我在导入您的代码时在 script.js 文件中留下了一个简单的错误。非常感谢。
  • @Minion 很高兴听到。我还用一个可行的解决方案更新了你的jsBin example(请注意,我显然必须模拟$.ajax() 调用)。 ;-)
  • 哦,很好。我想知道我应该如何使它工作。非常感谢!
【解决方案2】:

问题是button2是由Ajax创建的。

script2.js 在第一次加载页面时执行,在按钮 2 存在之前,因此无法将任何事件绑定到按钮 2(它不存在)。

当按钮 2 被创建并被点击时,它就像一个提交页面的普通按钮。

您必须在按钮 2 加载后强制脚本 2 运行。您可以通过在创建按钮后在脚本 1 中成功调用脚本 2 中的方法来做到这一点。

或者您可以查看 jquery 中的实时事件,它们可以锁定创建的新元素。

不过,在这种情况下,我会选择选项 1,它更简洁、更可预测。

使用 nietonfir 的脚本,更简单。

【讨论】:

  • 请阅读jQuery documentation 关于on() 和一般委托事件。一个事件侦听器可以轻松处理 OP 场景(只需对目标 URI 进行少量逻辑调整)。 //Just to make sure the dom is finished 应该是您做错了的第一个提示。
  • 我记录了现场活动,这是代表活动的旧名称。我仍然认为这是一个更糟糕的解决方案,因为如果您在不同级别上有许多不同的事件,它可以使页面更复杂。在这种情况下,我认为直接解决方案更好,特别是如果可能有许多不同的新按钮应该绑定到不同的事件,但这是一个见仁见智的问题。我的回答有什么错误吗?
  • 关于 Dom 完成的注意事项是我记得 html 命令,至少习惯于在 dom 实际准备好之前完成。这可能会更好,但对于较旧的浏览器,它仍然有效,除非 jquery 100% 确定 dom 已完成。
  • 是的,我认为这是错误的,因为您故意增加了复杂性。如果在页面中添加第三/第四/第五个按钮,您会怎么做?将更多功能绑定到dom(在超时黑客之后)?那不是很干也不是亲吻!
  • 两种解决方案都有效,在这种情况下您的解决方案可能更好,但您没有描述为什么必须这样做的真正原因,我认为这是回答问题的最重要部分.
猜你喜欢
  • 2013-01-18
  • 2015-10-19
  • 2021-10-28
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
相关资源
最近更新 更多