【问题标题】:How to re-attach jQuery functions after AJAX content load?如何在 AJAX 内容加载后重新附加 jQuery 函数?
【发布时间】:2013-02-04 17:46:46
【问题描述】:

我这样称呼一些 jQuery UI 函数:

jQuery(document).ready(function(){
    jQuery(".accordion").accordion();
});

但是我的页面是基于 AJAX 的,有些页面可能使用手风琴,有些可能不使用它。有 30 多个其他功能需要重新附加,这是一个有问题的开发任务。有什么聪明的方法可以解决这个问题,让每个新的.accordion 都能自动附加这个问题?

可能的解决方案及其不起作用的原因:

  • 在 AJAX 调用完成时触发文档就绪是理想的,但这是不可能的
  • 拥有load() 不是一种选择,因为它是一个用户可以安装插件的CMS - 这意味着插件仅使用jQuery(document).ready(); 添加的未知功能数量未知
  • ajaxComplete 上重新附加函数 - 对于未知数量的未知函数,每次安装或卸载 jQuery 插件时如果不修改 AJAX 脚本,这将无法正常工作

【问题讨论】:

  • 您正在构建单页 web 应用程序吗?你考虑过像 Backbone 这样的框架吗?
  • 小心调用$(".accordion").accordion() 多次,因为插件不必正确处理同一元素上的多次初始化。为了安全起见,我建议仅限制对新内容的调用,例如$("#newContent .accordion").accordion()

标签: javascript jquery ajax jquery-ui


【解决方案1】:

您可以使用DOMNodeInserted 事件并检查手风琴类。

document.addEventListener('DOMNodeInserted', function(e) {
    var el = $(e.target);
    if(el.hasClass('accordion')) {
        el.accordion();
    }
});

DOMNodeInserted 的使用示例:http://jsfiddle.net/qErHs/

【讨论】:

  • 我非常喜欢这个解决方案 :) 但是,我得出的结论是禁用 AJAX 会更简单。视觉效果会更差,但技术上会更好。
  • 仅供参考 DOMNodeInserted 已弃用,由于性能影响和跨浏览器兼容性问题,不鼓励使用,请参阅:developer.mozilla.org/en-US/docs/DOM/Mutation_events
  • @Paul 不要放弃 ajax,您的解决方法可以像编写一个通用的 contentReloaded 函数一样简单,该函数重新初始化所有必要的插件,然后总是在任何完成/成功回调时调用它阿贾克斯回调。这是我通常会做的事情,维护起来并不特别重,而且很有效。 (你只需要记住在添加新插件时更新它)
【解决方案2】:

我对 jQuery 小部件也有类似的问题。我所做的是使用 ajaxComplete 方法来附加小部件。

$(document).ajaxComplete(function()
    {
        $(".accordion").accordion();
    });

这样,每次 AJAX 方法完成时都会调用该函数,并将手风琴附加到任何具有手风琴类的新元素

【讨论】:

  • 感谢您的回答,但这正是我想要避免的 :) 我根本不知道需要附加多少功能以及需要附加哪些功能,因为它会动态变化......理想的解决方案是触发document ready - 这将涵盖我需要的所有内容,但这是不可能的。
  • 不确定它是否更好,但我在 ajaxComplete 之前所做的是在 AJAX 调用返回的内容中使用内联 JS 来为返回的 HTML 执行特定的 jQuery 内容
  • @Paul 您可以将 document.ready 包装在一个单独的函数中(例如,startUI()),然后在 document.ready 和 ajax 调用完成时调用它。但最好分别处理 document.ready 和 content reload。
  • 我明白你的意思。非常感谢您的建议,这确实是另一个好主意 :) 但我认为对于我正在寻找的东西没有优雅和完美的解决方案,所以我将禁用 AJAX。
【解决方案3】:

http://api.jquery.com/on/

“委托事件的优点是它们可以处理来自以后添加到文档的后代元素的事件。”

jQuery(document).on("change", ".accordion", function() {
  jQuery(".accordion").accordion();
});

【讨论】:

  • 谢谢!这是第一个建议,至少可以修复部分功能 :) 但是您的示例应该是这样的:jQuery(document).on('click', '.selector', function(){}); 因为on() 只有这样才能工作。
  • 而且......它不应该发生在点击上,而是发生在元素的外观上。
  • 你是对的。当我在工作中被ping通时,我把它扔了。对不起。我已经更新了我的答案并切换到了 change()。
  • 谢谢!这绝对是一个很好的解决方案,但我得出的结论是,禁用 AJAX 会更简单。视觉效果会更差,但技术上会更好。
【解决方案4】:

您可以检查“.accordeon”的长度。只需创建一个函数...

function init_accordeon(){
    if($('.accordeon').length) {
        $(".accordon").accordeon();
    }
}

然后在你的 ajax_calls 之后调用这个函数。

【讨论】:

  • 这 30 个函数不是我想要的。我需要它自动发生。与load() 一样。
  • 您只需要 1 个函数。请检查api.jquery.com/ajaxComplete 每次调用它,当您的 ajax_request 完成时
  • 是的,但我不想在 AJAX 请求完成后调用任何东西。我在文档中准备了未知数量的未知函数(用户可以添加自己的函数),因此他每次注册新的 jQuery 插件时还必须修改 ajaxComplete。
  • 因此我添加了一个 if 语句来检查“.accordeon”。顺便一提。当你的 dom 改变时,你必须初始化一个插件。如果您不想要这个,请尝试通过 iframe 解决它
【解决方案5】:

您可以在 ajax 调用后触发自定义事件。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  p {
    color: red;
  }
  span {
    color: blue;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<p>Has an attached custom event.</p>
<button>Trigger custom event</button>
<span style="display:none;"></span>

<script>
$( "p" ).on( "myCustomEvent", function( event, myName ) {
  $( this ).text( myName + ", hi there!" );
  $( "span" )
    .stop()
    .css( "opacity", 1 )
    .text( "myName = " + myName )
    .fadeIn( 30 )
    .fadeOut( 1000 );
});
$( "button" ).click(function () {
  $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});
</script>

</body>
</html>

【讨论】:

    猜你喜欢
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多